这雨夜太漫长 失眠的我 在谁梦里 歌唱
搞安全的应该都知道端口扫描在渗透测试、漏洞扫描过程中的重要性,其与URL爬虫等技术构成了漏洞扫描的第一阶段,即目标信息收集。因此能否开发出一款高效稳定的端口扫描器,往往决定了漏洞扫描器的好坏。那么说到端口扫描器,我们往往会先想到nmap、masscan等神器,它们是这个领域的标杆。但本篇并不是为了介绍这几款工具,而是谈谈如何自研一款高效稳定的端口扫描器。
端口扫描器,顾名思义就是为了探测服务器上的某个端口是否开放,究其原理可以分为很多种探测方式,比如tcp三次握手扫描,syn扫描等等,本篇并不打算详细介绍这些扫描方式的区别,有兴趣的可以看下nmap的文档,对这几种扫描方式有详细的介绍。
那么说下本文重点,基于这几天我研究并尝试利用python、go开发tcp扫描器、tcp-syn扫描器,以及对比它们之间的速度性能、稳定性差异情况,将测试结果在此做个记录,并分享一下代码以及方案。
说明:文章结尾将给出本篇所使用代码的Github地址,可供大家测试,代码测试环境为centos7。
scan for Python Socket
Python的Socket模块可以创建套接字,创建tcp三次握手连接,以此探测目标端口是否存活。本篇将使用socket模块编写tcp扫描以及syn扫描,并对比两者的差异。
tcp scan
快来看代码:
运行结果:
说明一下:可以看到此代码扫描1024个端口用了102s,当然代码并没有用多线程、协程等方式提高扫描效率(使用协程测试过扫65535个端口用时400s左右),因为python在这方面的能力比较弱;由于扫描过程中会建立tcp三次握手,因此比较消耗资源。
tcp syn scan
相对tcp扫描,tcp syn扫描方式更为隐蔽,也更节省资源,那么如何利用socket模块实现tcp syn扫描呢?这里需要用到SOCK_RAW,这个在socket编程中相对少用,资料也不多。
有一点需要注意的,运行这段代码前,需要在系统上安装依赖:
运行结果:
说明:从运行结果上来看,并没有很准确,而且速度也不快,不清楚是不是代码上有问题。
scan for Python scapy
除了socket模块外,python还有一个scapy模块,可以用来模拟发包,但只能在linux下使用,其他操作系统不建议使用此模块。
tcp syn csan
代码在这里:
运行结果:
说明:由于scapy可以一次性发多个syn包,因此速度相对socket更快一些,但稳定性没有很好。
scan for python+nmap
文章开头提到了nmap,其实在python中也可以直接调用nmap,看代码:
运行结果:
由于nmap扫描速度相对比较慢,因此这里只演示扫描4个端口,不做速度的对比,当然其稳定性还是可以的。
scan for go
前文一直在介绍使用python语言开发端口扫描器,然而由于python在多线程方面的弱势,扫描器的性能可想而知,因此我又利用go语言的高并发性优势,尝试开发端口扫描器。(题外话:为此我花了半天时间看了下go语言的基础,勉强看懂了扫描代码,并做了一些修改)
tcp scan
直接看代码吧:
代码我就不解释了(我在代码中加了些注释,应该大致可以看懂),本文也不打算介绍go的用法,毕竟自己也是刚开始学习go,有兴趣的可以看看go的文档,然后再回过头来看看这段代码。
代码运行结果:
说明:由于是tcp扫描,所以多少还是占资源的,而且测试发现稳定性不是很好。
tcp syn scan
看代码看代码:
代码运行结果:
没错,就是2s!我测试了扫描全端口(0-65535),大概120s左右,而且稳定性不错。
scan for go+python
经过前面的测试我们不难发现,在并发的性能上,go完胜python,但go不适合做复杂的逻辑处理,以及web开发之类的。因此如何整合python跟go呢?这里我想了两种方案,第一种将go语言打包成.so动态连接库,利用python的ctypes模块可以调用;第二种是go写成接口,提供python调用。写成接口的方式相对简单一些,因此这里不介绍了,说说如何打包go,即如何利用python调用go的方法或者说函数。
先看下修改过后的tcp_syn_scan.go代码:
然后利用go自身的build命令,将其打包成.so库:
打包后会得到一个tcp_syn_scan.so和一个tcp_syn_scan.h。然后利用下面的python代码就可以调用Go代码中的Scan()函数了,创建一个tcp_syn_scan.py文件。
代码运行结果:
说明:相当原生的go,利用python去调用go会损耗一些性能,但总体上还可以。
后记
本文结论就是可以利用go开发扫描模块(性能更佳),并结合python调用。
本文代码项目地址:https://github.com/tengzhangchao/PortScan