[synscan] SYN扫端口
语言自带扫描功能是本语言的一个大亮点。你在使用 yak 的时候,将不会再费心思考虑如何实现一个端口扫描功能,或者如何把 nmap 集成进你想编写的语言中。
什么是 SYN 端口扫描?
- 自己维护一套网络栈,拆解 TCP 三次握手
- 只进行第一次握手,如果收到了扫描目标的
SYN-ACK
则判定为端口开放 - 发送
RST
强行中断握手
本系统工具实现原理基本同 masscan
:短时间内把 SYN
数据包都发送出去,检查若干秒内的返回记录。
所以,我们在本扩展包中开放出了 synscan.wait(second)
这个参数配置,可以动态配置想要等待的秒数。
#
为什么 SYN 扫端口比 TCP 连接扫描更快速?直接调用系统接口进行 TCP 连接,系统需要帮忙维护一个 TCP 连接状态。众所周知
- 系统可打开的 TCP 连接是有限制的,可配置开放这个限制。
- 系统可同时打开的文件描述符也是有限制的,
ulimit
可配。
#
优势- 不需要进行完整 TCP 连接,系统对 TCP 连接无感知
- 资源消耗极低,发包速率取决于系统性能以及网络 IO
#
弊端- 频率过高的数据包容易被中间路由丢包,损失准确率
- 网络状况越差,丢包概率越大,扫描效果越差
#
最简单最高效的扫描接口#
核心扫描函数fn synscan.Scan(hosts: string, ports: string, vars: ...tools.scanOpt): (chan *tools.SynScanResult, error)
核心扫描函数,参数hosts
可以支持 IP/IP+掩盖码,域名等;ports
支持端口组,例如22.443.80,8080-8084
,或者1-65535
#
扫描额外参数fn synscan.outputFile(var_1: string): tools.scanOpt
设置输出的文件,输出文件为var_1
的值fn synscan.outputPrefix(var_1: string): tools.scanOpt
设置输出文件内容每一行的前缀,例如http://
,或者redis://
等,方便后续处理文件fn synscan.wait(var_1: float64): tools.scanOpt
全部数据包发送完之后,等待多少时间?单位秒
tools.SynScanResult
扫描结果结构#
type palm/common/yak/yaklib/tools.(SynScanResult) struct { Fields(可用字段): // 扫描到的 IP Host: string
// 这个 IP 开放的端口 Port: int
PtrStructMethods(指针结构方法/函数): // 展示 SynScanResult demo: `OPEN: 127.0.0.1:6341 from synscan` func Show()}
#
执行案例:最经典/最简单的使用方法res, err := synscan.Scan("127.0.0.1", "1-65535")die(err)
for result := range res { result.Show()}
当我们执行完上面脚本之后,我们发现扫描结果如下:
OPEN: 127.0.0.1:60012 from synscanOPEN: 127.0.0.1:6341 from synscanOPEN: 127.0.0.1:7891 from synscanOPEN: 127.0.0.1:9090 from synscanOPEN: 127.0.0.1:10000 from synscanOPEN: 127.0.0.1:49159 from synscanOPEN: 127.0.0.1:63342 from synscanOPEN: 127.0.0.1:7890 from synscanOPEN: 127.0.0.1:3306 from synscanOPEN: 127.0.0.1:10800 from synscanOPEN: 127.0.0.1:33060 from synscanOPEN: 127.0.0.1:6942 from synscanOPEN: 127.0.0.1:8080 from synscanOPEN: 127.0.0.1:49922 from synscanOPEN: 127.0.0.1:16090 from synscanOPEN: 127.0.0.1:16308 from synscanOPEN: 127.0.0.1:6342 from synscanOPEN: 127.0.0.1:50031 from synscanOPEN: 127.0.0.1:16067 from synscan
#
执行案例:自定义等待时间// 扫描本地 1-65535 号端口,全部数据包发送完毕的时候,等待 3.5 秒res, err := synscan.Scan("127.0.0.1", "1-65535", synscan.wait(3.5))die(err)
for result := range res { result.Show()}
#
执行案例:输出到文件res, err := synscan.Scan("127.0.0.1", "1-65535", synscan.wait(3.5), synscan.outputFile("test.txt"),)die(err)
for result := range res { result.Show()}
当我们执行完上面的代码之后,cat test.txt
,我们发现了文件内容结果如下
127.0.0.1:60012127.0.0.1:6341127.0.0.1:7891127.0.0.1:9090127.0.0.1:10000127.0.0.1:49159127.0.0.1:63342127.0.0.1:7890127.0.0.1:3306127.0.0.1:10800127.0.0.1:33060127.0.0.1:6942127.0.0.1:8080127.0.0.1:49922127.0.0.1:16090127.0.0.1:16308127.0.0.1:6342127.0.0.1:50031127.0.0.1:16067