【安全开发】Nmap主机探测技术详解(一)

目录

主机发现技术详解

碎碎念

最近在开发资产扫描器,决定梳理和深挖一下几款经典工具的实现方式,开源代码看了几套原理大同小异,于是决定从最基础的协议层开始深挖。用了好多年 Nmap,似乎一直没有深究过这款时代产物的运行原理,正好整理一番。因为目的是开发自己的扫描器,所以分类【安全开发】

本章只关注探活

讨论主机发现的时候 nmap 命令补充参数 -sn,用来禁用 nmap 端口扫描,我们只关注探活。

Nmap 基于协议实现主机发现,根据协议分类,依次有:

一、ARP 协议发现

  • 原理:构造一个arp 请求数据包,并广播出去,有回应包(arp-reply)则是活跃主机,迟迟收不到回应包则不是活跃主机
  • 优点:准确度高
  • 缺点:不能对不同网段的目标进行扫描
  • 适用场景:目标主机与扫描器(nmap)处在同一个广播域
  • 命令nmap -PR [Target]

二、ICMP 协议发现

  • 背景知识 :icmp 报文有两种:差错查询 报文,其中查询报文是用一对请求和应答定义的,可以通过发送特定的 icmp 请求报文,看对方在收到后回应什么类型的应答报文来判断主机是否存活。
  • 原理 :4种类型的查询报文,但是适合做探测的只有3种报文
    • i. 响应请求或应答
      • ping 命令,对方应答回复则是活跃主机,否则不活跃
    • ii. 时间戳请求或应答
      • 发送时间戳请求,有应答是活跃主机,否则不活跃
    • iii. 地址掩码请求或应答
      • 源主机发送,用于无盘(网吧等)系统在引导过程中获取自己子网掩码,发送地址掩码请求,有应答是活跃主机,否则不是
  • 命令 1nmap -PE [target]
    • (ping 发送 icmp type 8 等待 icmp type 0)
  • 命令 2nmap -PP [target]
    • (时间戳请求 发送 icmp type 13 等待 icmp type 14)
  • 命令 3nmap -PM [target]
    • (地址掩码请求 发送 icmp type 17 等待 icmp type 18)

三、TCP 协议发现

  • 背景知识:到 tcp 层有端口概念,tcp 三次握手过程。
  • 原理:利用 tcp 三次握手机制实现主机探活
  • 具体方式:TCP syn 扫描 和 TCP ack 扫描
  • syn 扫描 :nmap 发送一个设置了 SYN 标志位的数据包,默认发送给对方 80 端口,数据包内容为空,也可以通过参数修改默认端口,如果目标主机这个端口是开放的,会返回一个 syn/ack 数据包,端口不开放,会返回 rst 数据包,不论哪种数据包,返回了就说明主机活跃。nmap 探测完后会主动发送 rst。
    • 命令nmap -PS[port1,port2] [target]
    • 命令样例nmap -PS 8998 12.12.12.12
  • ack 扫描 :nmap 给目标发送 ack 包,主机搞不清情况,只能回复 rst 包,表示无法建立连接。(ack 扫描成功率很低,因为不少主机或安全机制会把这种莫名其妙的 ack 请求直接过滤掉)
    • 命令nmap -PA [target]

四、UDP 协议发现

  • 原理:发送 udp 数据包,如果端口返回 icmp 不可达数据包(icmp type 3),说明端口是关闭的,如果端口不返回,说明端口是开放的。
  • 缺点:端口不返回情况较复杂,可能是网络问题导致不回包,会被误判为端口开放,所以发现率低。而且速度慢,因为 icmp 错误报文生成速度有限制,每 4s 产生 80 个,超出会暂停 1/4s。
  • 命令nmap -PU [target]
  • 备注:基于 UDP 探测的特性,所以 tcp 扫描适合发现主机开放端口,udp 扫描适合发现主机关闭端口

五、SCTP 协议发现

SCTP(Stream Control Transmission Protocol,流控制传输协议)是一种可靠的、面向连接的、面向消息的传输层协议,位于 TCP/IP 协议栈中,与 TCP 和 UDP 处于同一层级。

  • 补充 :与 tcp 协议一样都是传输层协议,但是有很大区别:
    • 1.tcp 是单地址链接,sctp 可用于多地址链接
    • 2.tcp 是基于字节流传输,sctp 是基于消息流(stream),tcp 只能支持一个流,sctp 链接(association)同时可以支持多个流。
    • 3.tcp 三次握手,sctp 四次握手机制(互相问好并确认)
  • 在 SCTP中,客户端使用一个INIT报文发起一个连接,服务器端使用一个INIT-ACK报文进行应答,其中就包括了cookie(标识这个连接的唯一上下文)。然后客户端使用一个COOKIE-ECHO报文进行响应,其中包含了服务器端所发送的cookie。服务器端要为这个连接分配资源,并通过向客户端发送一个COOKIE-ACK报文对其进行响应。
  • 命令nmap -PY[port1,port2] [target]
  • 缺点:对方主机很有可能不支持 sctp 协议,所以命中率很低

六、IP 协议发现

头部中协议长度是 8 位,用来标识使用哪种协议进行数据传输。ICMP 是 1,IGMP(互联网组管理协议) 是 2,TCP 是 6,UDP 是 17,GRE 是 47 等。理论上 nmap 使用的协议可以包含上百个,如果不指定的话 nmap 默认使用 ICMP,IGMP 和 IP-in-IP (IP隧道协议,ip over ip)协议,对应的 IP 协议号分别为:1,2,4。也可以使用 -PO 指定使用的协议号

  • nmap -sP -PO [target] 使用默认的协议扫描 (等同于:nmap -sP -PO 1,2,4 [target]
  • nmap -sP -PO 6,17 [target] (编号 6 TCP 协议,编号 17 UDP 协议)

但是这种的形式发动的数据包都是空,非正常数据包,很容易被检测出来,可以使用 --data-length 参数添加随机数据填充

  • nmap --data-length 25 [target]

七、DNS 协议发现

Nmap 对目标主机进行扫描的时候如果发现目标主机是一台 web 服务器,那么他除了 IP 之外还会有一个域名,nmap 发现 ip 存在域名后,会向域名服务器(DNS server)提出请求来显示 IP 对应的域名,但这种行为仅会对活跃主机进行探测,同网段非活跃主机不会默认进行。如果希望 nmap 对所有探测出来的活跃 IP 都显示其对应的域名的话,可以使用 -R 参数

  • nmap -R [target] 强制对 IP 进行域名转换,显示 ip 对应的域名,这比较耗时
  • nmap -n [target] 强制不对 IP 进行域名装换,这样可以节省时间

如果不想 nmap 在扫描的时候查询 dns server 上留下查询记录,可以使用 --dns-servers 参数

  • nmap --dns-servers [server1,server2] [target]

补充

Nmap中提供了--packet-trace选项,通过它就可以观察Nmap发出了哪些数据包,收到了哪些数据包,有了这个研究方法,可以更深入地理解Nmap的运行原理。

发送数据包 - SENT

复制代码
SENT (0.0253s) TCP 192.168.1.10:54321 > 192.168.1.1:80 S ttl=56 id=45678 iplen=44 seq=123456789 win=1024

字段含义:

  • SENT (0.0253s):在扫描开始后 0.0253 秒发送了该包。
  • TCP:协议类型(也可能是 UDP、ICMP 等)。
  • 192.168.1.10:54321:本机 IP 和源端口。
  • 192.168.1.1:80:目标 IP 和目标端口。
  • S:TCP 标志位(这里是 SYN)。其他可能包括:
    • S = SYN
    • A = ACK
    • SA = SYN+ACK
    • R = RST
    • F = FIN
    • PA = PUSH+ACK 等
  • ttl=56:IP 生存时间(Time To Live)。
  • id=45678:IP 数据包标识符。
  • iplen=44:IP 包总长度(字节)。
  • seq=123456789:TCP 序列号。
  • win=1024:TCP 窗口大小。

接收数据包 - RCVD

复制代码
RCVD (0.0451s) TCP 192.168.1.1:80 > 192.168.1.10:54321 SA ttl=64 id=0 iplen=44 seq=987654321 ack=123456790 win=65535

字段含义

  • SA 表示目标返回了 SYN+ACK,说明该端口是开放的。
  • ack=123456790 是对之前发送的 SYN 包的确认(seq+1)【seq =123456789】

实操测试

nmap 扫描一个目标会先判断目标和自己是否在同一个网段,如果在同一个网段,会优先使用 arp 扫描,不在会默认进行其他扫描

目标 :流量层研究 nmap 的扫描具体做了哪些事
命令nmap 10.95.58.94

nmap返回结果

流量上看出nmap 做了如下动作:

    1. 向目标IP发送一个ICMP Echo Request (type 8); → 目标回包:ICMP Echo replay (type 0) → 存活(这一步已经能判断主机存活)
    1. 向目标IP的443端口发送一个TCP SYN请求 (seq=0); → 目标回包:TCP RST-ACK ,seq=1
    1. 向目标IP的80端口发送一个TCP ACK请求; → 目标回包:图未回复,正常会回一个 RST 包
    1. 向目标IP发送一个ICMP Timestamp Request(type 13); → 目标回包:Timestamp replay
    1. 查找目标IP反向DNS解析的地址(图中未体现出来) → (目标 IP 是 web 服务器有域名,会触发反查 DNS)
    1. 当目标IP回应了任何一个探测包,则nmap认为目标IP存活,则进行下一步(图中 4 个请求包回复了 3个);
    1. 向目标发送1000个常用端口发送SYN请求,判断存活端口;

注:

  • 前 4 个请求并不需要每个都有回应,任意 1个回应即可判定主机存活 (如下图可以看到目标回应ACK 1 个RST)

  • IP 反查是对 web 服务主机的默认行为,非 web 主机默认不会触发

  • 以上测试 nmap 和目标主机均不在同一个广播域

其他情况

根据运行 nmap 的用户权限不同,nmap 功能会有一定的区别

特性 特权用户 非特权用户
用户身份 root / 管理员 普通用户
能否发 ICMP 不能
能否发自定义 TCP 包 如 SYN、ACK 只能完整 connect()
主机发现方式 ICMP + TCP + ARP(跨网段用ICMP) 仅对 80/443 做 TCP connect()
端口扫描类型 SYN 扫描(半开)→ 然后断开 Connect 扫描(全连接)→ 然后断开
隐蔽性 更高 较低(会建立完整连接)
  • 非特权用户扫描

  • 特权用户扫描

Masscan 扫描工具不区分运行用户权限,均为半链接

经验之谈

内网主机存活探测最佳实践

复制代码
nmap -n -sn -PE -PS80,443,22,445,3389,12345 -PU40125
  • -n 禁止 IP 反向解析域名,优化项,加快探测速度
  • -sn 禁止端口扫描,仅用于存活探测,优化项,加快探测速度
  • -PE ICMP echo request 请求包 (type 8)
  • -PS [port1,port2] SYN 半链接指定端口探测
  • -PU 允许发送 UDP 探测包(为什么是 40125 端口?因为这个高端口没有标准服务,随机选的,UDP 探测期待端口关闭并返回 ICMP Timestamp replay,这个端口大概率是关闭的)

凡事都有特殊情况及注意的点:

    1. 不要启用强制ARP请求,跨网段ARP请求有可能会出现代理ARP应答的情况;
    1. 扫描结果一般只供参考,不能100%可信,如,当遇到蜜罐的时候,所有蜜罐网络中的IP都是存活的;

by 久违 2026.1.18

相关推荐
缘木之鱼2 小时前
CTFshow __Web应用安全与防护 第一章
前端·安全·渗透·ctf·ctfshow
txinyu的博客2 小时前
DNS 协议
网络
小小代码狗2 小时前
【无标题】
网络·sql·php
qq_336313932 小时前
java基础-网络编程-UDP
网络
2301_780789662 小时前
游戏行业抗 DDoS 方案:高并发场景下的 CC 攻击拦截与体验平衡
安全·web安全·游戏·ddos
乾元2 小时前
范式转移:从基于规则的“特征码”到基于统计的“特征向量”
运维·网络·人工智能·网络协议·安全
txinyu的博客2 小时前
手写 C++ 高性能 Reactor 网络服务器
服务器·网络·c++
华普微HOPERF2 小时前
BLE6.0规范,如何助力智能门锁突破性能极限?
网络·智能家居·解决方案·智能门锁·芯片模组·蓝牙6.0
快降重2 小时前
效率与安全的平衡:面向毕业季的论文“降AI”应急方案对比研究
人工智能·安全·aigc·ai写作·降重·降ai