基于无状态的极速扫描技术
大家都知道TCP是可靠的面向连接的协议,一个完整的TCP会话每个过程都有不同的状态。正是操作系统在底层已经保存了这些状态我们在应用层使用起来才更方便可靠。可靠的同时带来的是资源占用,在古老的xp时代系统TCP/IP连接默认只有10个。即使系统没有这种限制,应用内部要使用上万的连接也是消耗极大资源的,一般的应用程序每个连接启动一个线程。apache默认1500个连接,打垮它是很容易的。无状态连接是指无需关心TCP状态,不占用系统TCP/IP协议栈资源,忘记syn,ack,fin,timewait,不进行会话组包。在实现上也有可能需要把必要的信息存放在数据包本身中。如13年曾以44分钟扫描完全部互联网zmap,之后出现的massscan,都使用了这种无状态技术,扫描速度比以往任何工具都有质的提升,后者更是提出了3分钟扫完互联网的极速。
我们注意到zmap和masscan都有一个控制发包速率的参数,为什么需要这个参数呢?不是越高越好吗?不是的,这个参数的设置直接影响漏报。一般家用adsl的上行速度在100kb/s-300kb/s之间,以互联网最小包60byte计算,100kb/s =1746pps,也就是说每秒发送数据包约2000个,超出就容易丢包漏报。通过这个公式不难得出在一个家庭adsl环境下且保证准确度,用zmap扫描全部互联网需要255*255*255*255/2000/3600/24=24天。
zmap在实现上还有两个必须提的技巧,一个是为了避免扫描连续的IP地址而触发目标网络的IDS,采用了一种分组扫描算法,这样扫描的IP地址随机分布,不再连续,就不会因为密集扫描而触发IDS。第二个技巧是利用对扫描无影响的可用字段,来标记自己的扫描流量。在TCP扫描中使用了sequencenumber和source port 两个字段,而ICMP则是 identifier 和 sequencenumber。通过这两个自定义的标记过滤掉其它应用的背景流量。masscan在过滤背景流量使用的是另外一种方法,通过注册一个不存在的IP地址,来发送扫描数据。相比这两种过滤方法,zmap产生的大量sequencenumber 会导致交换机在跟踪会话时内存占满。masscan就安全的多了。
这两工具扫描端口的交互过程一致如下,在确认端口打开后通过RST放弃建立连接。
zmap和masscan重点都是端口扫描,并没有建立完整的TCP会话,接下来我们要实现建立完整的连接。建立连接对扫描程序没什么性能消耗,考虑下apache的慢连接攻击,那么对服务器的危害就很大了。
tscan工具架构
tscan是我们自己实现的工具,在这个工具中我们用了两个线程,一个线程负责发起SYN包,一个线程用来处理返回包,在背景流量过滤上使用了winpcap的端口和IP过滤器,同时打开windows系统自带的防火墙防止系统自动发出RST干扰会话。
场景一 全连接测试
这是最简单的会话实现,只建立连接,不提交任何数据。在没有使用虚拟IP的情况下,受端口4字节长度限制,一个IP对一个主机的同一端口只能建立65535个连接。截图来自2010年我的博客http://hi.baidu.com/cnqing/item/93894bf3c329e4c4a935a266,如果要建立更多连接可以利用虚拟IP地址(同masscan背景流量过滤方式)
应答数据包主要有下面几个关键信息
1.源MAC和目的MAC互换
2.源IP和目的IP互换
3.源PORT和目的PORT互换
4.响应ack=原seq+本次数据长度
这几个动作做好,再计算校验和就可以正确的响应一个SYN +ACK,至此TCP连接建立完成。
应答数据包构造代码:
场景二 扫描OpenSSL heartbeat
这个场景稍微复杂,不但建立会话还需要完成两次数据交互,第一次是发送clienthello,第二次发送heatbeat验证漏洞。
process 处理流程示意:
OpenSSL HeartBleed 漏洞扫描流程示意图:
代码示例:
完成之后我们做了两个测试
1.在上行速度3Mb的情况下,对12W活跃IP扫描,耗时36秒,漏报约1%。
2.用最低配的云主机测一个A段1600W ip地址,耗时7.5小时,2977个漏洞。
照此粗略计算,目前全球受ssl影响的主机约为75W个地址,接近zoomeye公布的71W。
场景三 批量扫描FTP匿名
通过分析FTP登录过程发现FTP的状态码还算可靠,只需关心的几个状态码。
220 服务就绪,客户端提交用户名
331 服务器肯定,肯定继续提交密码
230 登录成功
4xx/5xx 异常
下图是我们模拟的登录过程,在最后登录成功后,多发送了一个RST终止流量。
FTP扫描要比SSL慢一些主要原因是FTP服务响应没有openssl在handshake阶段响应的快。
更高级的应用WEB漏洞扫描
理解前面的过程后扫描web漏洞就很容易实现,举个扫描phpinfo的例子建立连接之后我们提交:
GET /phpinfo.php HTTP/1.1
Host: {$AUTOIP}
通过验证返回的数据内容判断是否存在phpinfo。
关于带宽
不同的场景,带宽消耗不同,端口扫描出流量,远大于入流量,http扫描出流量和入流量比例在1:20左右。适当的设置发包速度可以有效降低漏报。
出于仅技术讨论的目的,本文涉及的工具这里暂不提供。有兴趣的同学可以通过更改masscan研究。
页:
[1]