nabbu 端口扫描源码学习

前言:nabbu 端口扫描源码学习,github仓库推送了注释版的naabu项目作为记录保存

参考文章:https://github.com/xiaoyuer11223344/nabbu-fix
参考文章:https://cloud.tencent.com/developer/article/1075805
参考文章:https://blog.lyle.ac.cn/2023/11/25/single-tcp-service-probe/

记录关于如何设置最佳扫描器rate速度参数

相关端口扫描器--rate参数定义了每秒发送的数据包数量,如何选择最佳的rate参数值,需要考虑多个因素,包括但不限于你的网络带宽、目标网络的承受能力以及你是否希望避免被检测到。

如果你有 100 Mbps(兆比特每秒)的带宽,首先需要将这个值转换成字节,因为数据包大小是以字节为单位计算的。100 Mbps 等于 12.5 MBps(兆字节每秒)。

你需要估计每个扫描数据包的大小。Masscan 发送的数据包通常非常小(例如,最小的TCP SYN数据包大约是60字节,加上以太网帧头等开销后可能接近100字节)。

假设每个数据包的总大小是 100 字节,那么理论上你可以每秒发送大约 125,000 个数据包(即 12.5 MB / 0.0001 MB = 125,000)。然而,这只是一个粗略的估计,实际中你还需要考虑到网络协议的额外开销,如IP头部和TCP头部,以及其他可能的网络延迟和拥塞。

所以在硬件配置相关是最佳的状态的话,那么当带宽为100 Mbps(兆比特每秒),我们可以设置rate参数为 --rate 10000,当然实际上肯定是这个低的,这里只是作为一个参考学习。

参数初始化

main.go中执行options := runner.ParseOptions(),对应的文件在options.go中,可以看到通过用户可控相关参数进行初始化操作,如下图所示

  • 数据源输入方式

  • 扫描端口选项

  • 扫描速率限制

  • 结果输出方式

  • 扫描配置选项

  • 主机发现方式

  • 扫描优化选项

NewRunner

main.go中执行runner.NewRunner(options),如下图所示

端口解析

ParsePorts端口解析的操作

  • 支持指定端口扫描文件
  • 支持快捷方式选择要扫描的端口,比如TOP100 TOP1000
  • 支持自定义扫描端口,比如1-65535

主机发现配置初始化

configureHostDiscovery根据端口扫描数量来开启主机发现功能

  • 当开启主机发现选项,后期扫描主机端口之前会先进行主机存活,发送相关的IcmpEcho,IcmpTimestamp,TcpSynPing(针对80和443),TcpAckPing(针对80和443)请求包

DNS解析客户端

初始化dnsClient,后期用来解析输入源为主机名的数据

IP排除过滤

用户通过调用parseExcludedIps方法实现自定义过滤不想要扫描的IP,如下图所示

扫描配置选项及数据回调onReceive处理

  • 根据相关选项生成scan.Options对象,然后进行初始化runner对象

  • onReceive自定义实现处理扫描端口的发现情况,默认的话就是当相关的IP扫描到了开放端口的情况就会默认在命令行终端输出展示

RunEnumeration

进入naabuRunner.RunEnumeration(context.TODO())之后就正式开始对输入源的数据进行端口扫描开放处理

SYN半开放式服务启动

在首先进入会判断是否开启SYN半开放式扫描,如下图所示

  • 伪造来源IP和端口

  • 指定发包接口Interface

注:nabbu的SYN半开放式扫描是通过gopacket第三方库实现,可自定义来源IP,端口和发包接口

同时会执行r.BackgroundWorkers(ctx),开启三种类型的数据包监听器

  • ICMPResultWorker

  • TCPResultWorker

  • UDPResultWorker

比如在TCPResultWorker中,它会持续监听s.ListenHandler.TcpChan通道中的数据来判断端口存活的情况

当开启SYN半开放式服务之后,在scan_unix.go会有一段初始化监听器和通道,用于后续发包使用,其中包括如下

  • transportPacketSend通道,监听接受然后转发SYN半开放扫描要发送的TCP/UDP的数据
  • icmpPacketSend通道,监听接受ICMP数据然后转发ICMP请求数据
  • ethernetPacketSend通道,未使用

上面三个通道的数据在下面三个函数中进行处理

// 读取解析TransportWriteWorker发包之后返回的结果
go TransportReadWorker()
// 将要发送的请求封装存储到对应的通道中
go TransportWriteWorker()
// 将要发送的ICMP请求封装存储到对应的通道中
go ICMPWriteWorker()

  • 启动IPV4/IPV6 ICMP监听器,用于发包使用
icmpConn4, err = icmp.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
gologger.Debug().Msgf("could not setup ip4:icmp: %s", err)
}
icmpConn6, err = icmp.ListenPacket("ip6:icmp", "::")
if err != nil {
gologger.Debug().Msgf("could not setup ip6:icmp: %s", err)
}

  • buildListenHandler启动IPV4/IPV6的TCP和UDP监听器
listenHandler.TcpConn4, err = net.ListenIP("ip4:tcp", &net.IPAddr{IP: net.ParseIP(fmt.Sprintf("0.0.0.0:%d", listenHandler.Port))})
if err != nil {
return nil, fmt.Errorf("could not setup ip4:tcp: %s", err)
}
listenHandler.UdpConn4, err = net.ListenIP("ip4:udp", &net.IPAddr{IP: net.ParseIP(fmt.Sprintf("0.0.0.0:%d", listenHandler.Port))})
if err != nil {
return nil, fmt.Errorf("could not setup ip4:udp: %s", err)
}

用于处理上述的ICMP和TCP,UDP监听到的数据

go listenHandler.ICMPReadWorker4()
go listenHandler.ICMPReadWorker6()
go listenHandler.TcpReadWorker4()
go listenHandler.TcpReadWorker6()
go listenHandler.UdpReadWorker4()
go listenHandler.UdpReadWorker6()

加载要扫描的目标

Load方法用于解析要扫描的目标

PreProcessTargets中会调用AddTarget方法将所要要扫描的目标进行解析,等待后续的扫描

  • 支持解析ASN对应的CIDR地址

  • 支持解析CIDR地址

  • 支持IP输入

  • 支持域名输入

注意:域名输入的情况下,还会先进行resolveFQDN解析获取其IP,如下图所示

主机存活扫描

当开启了主机存活选项的话,那么则将对要扫描的目标先进行一次主机存活探测,如下图所示

主机存活扫描主要的逻辑是在handleHostDiscovery函数中,在前面的主机发现配置初始化部分中提及过,当开启主机发现选项,后期扫描主机端口之前会先进行主机存活,发送相关的IcmpEcho,IcmpTimestamp,TcpSynPing(针对80和443),TcpAckPing(针对80和443)请求包,如下图所示

端口开放扫描

支持三种扫描模式,分别是如下

  • r.options.Stream && !r.options.Passive
  • r.options.Stream && r.options.Passive
  • 默认扫描

这边主要就是学习Default默认扫描分支情况,如下图所示

  • 过滤防火墙目标IP
  • 高权限下使用SYN半开放式扫描
  • 低权限下使用TCP扫描,三次握手包

  • 当端口开放下支持Verify参数进行二次端口开放校验
  • 当端口开放下支持Nmap调用进行指纹服务探测

posted @   zpchcbd  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2020-01-08 Mssql绕过360拿到webshell
点击右上角即可分享
微信分享提示