3

SSH爆破检测规则

 2 years ago
source link: https://co5mos.github.io/2019/11/23/ssh-brust/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在漫天风沙里望着你远去,我竟悲伤得不能自已,多盼能送君千里,直到山穷水尽,一生和你相依。——《漂洋过海来看你》

昨天去面试,被问如何写一个SSH爆破的检测规则,我当时有点懵逼,一时间不知道该怎么写。

学习一下吧。

什么是SSH

Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接。虽然任何网络服务都可以通过SSH实现安全传输,SSH最常见的用途是远程登录系统,人们通常利用SSH来传输命令行界面和远程执行命令。使用频率最高的场合类Unix系统,但是Windows操作系统也能有限度地使用SSH。2015年,微软宣布将在未来的操作系统中提供原生SSH协议支持,Windows 10 1809 版本已提供可手动安装的 OpenSSH工具。——《维基百科

SSH是运行在TCP协议上的应用层协议。

SSH协议是建立在不安全的网络之上的进行远程安全登陆的协议。它是一个协议族,其中有三个子协议,分别是:

  1. 传输层协议[SSH-TRANS]:提供服务器验证、完整性和保密性功能,建立在传统的TCP/IP协议之上。
  2. 验证协议[SSH-USERAUTH]:向服务器验证客户端用户,有基于用户名密码和公钥两种验证方式,建立在传输层协议[SSH-TRANS]之上。
  3. 连接协议[SSH-CONNECT]:将加密隧道复用为若干逻辑信道。它建立在验证协议之上。

SSH认证方式

基于口令的认证

SSH的publish key和private key都是自己生成的,没法公证。通过Client端自己对公钥进行确认。通常在第一次登录的时候,系统会出现下面提示信息:

The authenticity of host '192.168.31.177 (192.168.31.177)' can't be established.
ECDSA key fingerprint is SHA256:z0zrUwb0IOaQesVyNdZ8b5A/HKgdNSy1HnM8sWo1u6E.
Are you sure you want to continue connecting (yes/no)?

上面这段话的意思是,无法确认192.168.1.4主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?这样我们就可以看到,SSH是将这个问题抛给了SSH使用者,让SSH使用者自己来确定是否相信远程主机。但是这样对于用户来说,就存在一个难题,用户怎么知道远程主机的公钥指纹是多少;这的确是一个问题,此时就需要远程主机必须公开自己的公钥指纹,以便用户自行核对。

如下已经获取远程主机认可:

Warning: Permanently added '192.168.31.177' (ECDSA) to the list of known hosts.

输入密码即可。

当远程主机的公钥被接受以后,它就会被保存在文件~/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。

基于公钥的认证

  1. Client将自己的公钥存放在Server上,追加在文件authorized_keys中。
  2. Server端接收到Client的连接请求后,会在authorized_keys中匹配到Client的公钥pubKey,并生成随机数R,用Client的公钥对该随机数进行加密得到pubKey(R),然后将加密后信息发送给Client。
  3. Client端通过私钥进行解密得到随机数R,然后对随机数R和本次会话的SessionKey利用MD5生成摘要Digest1,发送给Server端。
  4. Server端会也会对R和SessionKey利用同样摘要算法生成Digest2。
  5. Server端会最后比较Digest1和Digest2是否相同,完成认证过程

可以参考往GitHub上传自己的SSH keys。

SSH爆破

爆破工具网上有很多,也可以使用 nmap + hydra 的方式进行爆破。

TODO: Golang爆破工具。

Suricata检测SSH爆破

关于Suricata可以参考之前的文章Suricata基础

针对暴力破解,嵌入了这种能力(例如flowint)。这是因为在Suricata上已经通过使用flowint进行了手动警报规则配置。规则如下:

alert tcp any any -> any any (msg:"Counting Failed Logins"; content:"incorrect"; flowint: username, notset; flowint:username, =, 1; noalert; sid:1;)
alert tcp any any -> any any (msg:"More than two Failed Logins!"; content:"incorrect"; flowint: username, isset; flowint:username, +, 1; flowint:username, >, 2; sid:2;)
alert tcp any any -> $MY_SSH_SERVER 22 (msg:"Connection to SSH server"; threshold: type threshold, track by_src, count 10, seconds 60,flow:to_server; flags:S,12; sid:888;)

这条规则的意思是说当同一源在1分钟内有5次ssh,就会产生告警

如何限制SSH爆破

iptables规则限制SSH登录

iptables的原理主要是对数据包的控制。

通过设定时间内限制SSH的连接次数,超过次数之后直接丢弃该包。一次连接的允许的密码错误尝试次数在另外的SSH SERVER设置文件里。

通过两条规则进行限制:

  1. iptables -A INPUT -m limit –limit-burst 5

用来比对瞬间大量封包的数量,上面的例子是用来比对一次同时涌入的封包是否超过 5 个(这是默认值),超过此上限的封将被直接丢弃。使用效果同上。

  1. iptables -A INPUT -m limit –limit 3/hour

用来比对某段时间内数据包的平均流量,上面的例子是用来比对:每小时平均流量是否超过一次3个数据包。 除了每小时平均次外,也可以每秒钟、每分钟或每天平均一次,默认值为每小时平均一次,参数如后: /second、 /minute、/day。 除了进行数据包数量的比对外,设定这个参数也会在条件达成时,暂停数据包的比对动作,以避免因洪水攻击法,导致服务被阻断。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK