Nmap 总结 (ESP)

Reading time: 24 minutes

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks
nmap -sV -sC -O -n -oA nmapscan 192.168.0.1/24

参数

要扫描的 IPs

  • <ip>,<net/mask> 直接指定 IPs
  • -iL <ips_file> list_IPs
  • -iR <number>: 随机 IP 的数量,可以用 --exclude <Ips>--excludefile <file> 排除可能的 IPs。

设备发现

默认情况下 Nmap 发起的发现阶段包括:-PA80 -PS443 -PE -PP

  • -sL 非侵入式,会列出目标并发出 DNS 请求解析名称。用于确认例如 www.prueba.es/24 下的所有 IP 是否为我们的目标。
  • -Pn 不 ping。当你确定目标都在线时很有用(否则可能浪费大量时间,且该选项会产生误报认为它们不在线),它会跳过发现阶段。
  • -sn不扫描端口。完成勘察阶段后不扫描端口。相对隐蔽,适合小规模网络扫描。有权限时会向 80 发送 ACK(-PA),向 443 发送 SYN(-PS)并发送 echo request 和 Timestamp 请求;无权限时则总是完成连接。如果目标是网络,则只使用 ARP(-PR)。若与其它选项一起使用,则只会丢弃其它选项的数据包。
  • -PR ARP Ping。在分析本地网络中的主机时默认使用,速度比普通 ping 快。如果不希望使用 ARP 包,请使用 --send-ip
  • -PS <ports> 发送 SYN 包,若回复 SYN/ACK 则为 open(会以 RST 回应以不结束连接),若回复 RST 则为 closed,若无回复则为 unreachable。若无权限,则自动使用完整连接。若未指定端口,默认对 80 端口。
  • -PA <ports> 与上类似,但发送 ACK,结合两者可获得更好结果。
  • -PU <ports> 目标相反,发送到预期为 closed 的端口。有些防火墙只检测 TCP 连接。若 closed 会以 port unreachable 回应,若以其它 ICMP 或无响应则标记为 destination unreachable。
  • -PE, -PP, -PM ICMP PING:echo reply、timestamp 和 addresmask。用于判断目标是否存活。
  • -PY<ports> 发送 SCTP INIT 探针,默认到 80,可能回复 INIT-ACK(open)或 ABORT(closed)或无回复或 ICMP unreachable(inactive)。
  • -PO <protocols> 指定协议号,默认 1(ICMP)、2(IGMP) 和 4(Encap IP)。对于 ICMP、IGMP、TCP (6) 和 UDP (17) 会发送协议头,其它则只发送 IP 头。目的是通过异常头部导致 Protocol unreachable 或相同协议的响应以判断是否在线。
  • -n 不使用 DNS
  • -R 始终使用 DNS

端口扫描技术

  • -sS 不完成连接因此不留下痕迹,非常适合可用时使用。(需要权限)默认使用此方法。
  • -sT 完成连接,会留下痕迹,但在无权限时可使用。
  • -sU 更慢,用于 UDP。常见:DNS(53)、SNMP(161,162)、DHCP(67 和 68),使用 -sU53,161,162,67,68:open(有回复)、closed(port unreachable)、filtered(其它 ICMP)、open/filtered(无回复)。若为 open/filtered,-sV 会发送大量探测来检测 nmap 支持的版本并确定真实状态。会显著增加时间。
  • -sY SCTP,无法建立连接,因此无日志,工作方式类似 -PY
  • -sN,-sX,-sF Null, Fin, Xmas,可穿透部分防火墙并提取信息。基于标准合规主机应对缺少 SYN、RST 或 ACK 标志的请求以 RST 响应:open/filtered(无回复)、closed(RST)、filtered(ICMP unreachable)。在 Windows、Cisco、BSDI 和 OS/400 上不可靠,Unix 上可用。
  • -sM Maimon 扫描:发送 FIN 和 ACK 标志,曾用于 BSD,目前多数会返回 all closed。
  • -sA, sW ACK 和 Window,用于检测防火墙,判断端口是否被过滤。-sW 可以区分 open/closed,因为 open 的 RST 会带不同的 window 值:open(RST 且 window 非 0),closed(RST 且 window = 0),filtered(ICMP unreachable 或无回复)。并非所有主机如此工作:若全部显示 closed,说明方法无效;若少数 open,说明有效;若大量 open 少数 closed,可能回报相反结果。
  • -sI Idle scan。适用于存在活动防火墙但我们知道某个 IP 不会被其过滤(或需要匿名时),可使用 zombie 扫描(适用于所有端口)。可用脚本 ipidseq 或 exploit auxiliary/scanner/ip/ipidseq 查找可能的僵尸。该扫描基于 IP 包的 IPID 编号。
  • --badsum 发送错误的校验和,主机会丢弃数据包,但防火墙可能会有响应,用于检测防火墙。
  • -sZ “Weird” SCTP 扫描,发送带 cookie echo 片段的探针,若 open 应被丢弃或 closed 则用 ABORT 响应。可穿越某些 init 无法穿过的防火墙,但无法区分 filtered 与 open。
  • -sO IP 协议扫描。发送错误或空的头部,有时连协议都无法识别。若收到 ICMP protocol unreachable 则为 closed,若收到 unreachable port 则为 open,若其它错误则为 filtered,若无回复则 open|filtered。
  • -b <server> FTPhost --> 用于从另一台主机扫描目标,通过连接到另一台机器的 FTP 并要求其向你想扫描的端口发送文件,根据回复判断端口是否开放。[<user>:<password>@]<server>[:<port>]。几乎所有现代 FTP 服务器都不再允许此操作,因此实用性有限。

分析重点

-p: 指定要扫描的端口。若要选择全部 65,535 个端口:-p--p all。Nmap 使用基于流行度的内部分类,默认扫描 top 1000 端口。使用 -F(快速扫描)分析 top 100。使用 --top-ports 可以分析指定数量的 top 端口(1 到 65,335)。它以随机顺序检查端口;若要阻止此行为,请使用 -r。也可以选择特定端口:20-30,80,443,1024-(后者表示从 1024 起)。也可按协议分组端口:U:53,T:21-25,80,139,S:9。还可以在 Nmap 的流行端口列表中选择范围:-p [-1024] 会分析 nmap-services 中包含的最高到 1024 端口。--port-ratio 在 0 到 1 的比率内分析最常见的端口。

-sV 版本探测,强度可从 0 到 9 调节,默认 7。

--version-intensity 调节强度,数值越低只会发出最可能的探针,而不是全部。用它可以大幅缩短 UDP 扫描时间。

-O 操作系统识别

--osscan-limit 为了进行可靠的主机扫描,至少需要一个 open 端口和一个 closed 端口。若不满足此条件且启用了该选项,则不会尝试 OS 预测(节省时间)。

--osscan-guess 当 OS 探测不够精确时,启用此选项会让其更努力地尝试猜测。

脚本

--script |||[,...]

要使用默认脚本,使用 -sC 或 --script=default

可用类型有:auth, broadcast, default, discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, 和 vuln

  • Auth: 执行所有可用的认证脚本
  • Default: 执行基本的默认工具脚本
  • Discovery: 从目标或受害者处检索信息
  • External: 使用外部资源的脚本
  • Intrusive: 使用被认为对目标有侵入性的脚本
  • Malware: 检查恶意代码或后门打开的连接
  • Safe: 执行非侵入性脚本
  • Vuln: 发现最常见的漏洞
  • All: 执行所有可用的 NSE 扩展脚本

查找脚本:

nmap --script-help="http-*" -> 以 http- 开头的脚本

nmap --script-help="not intrusive" -> 除侵入性脚本外的全部

nmap --script-help="default or safe" -> 属于 default 或 safe 的脚本

nmap --script-help="default and safe" --> 同时属于两者的脚本

nmap --script-help="(default or safe or intrusive) and not http-*"

--script-args =,={=},={,}

--script-args-file

--script-help ||||all[,...]

--script-trace ---> 提供脚本执行的进展信息

--script-updatedb

要使用脚本,只需输入: nmap --script Script_Name target --> 使用脚本时,脚本与扫描器都会执行,因此也可添加扫描器选项。可加入 "safe=1" 以只执行安全脚本。

时间控制

Nmap 可以接受以秒、分钟、毫秒为单位的时间参数:--host-timeout 参数 900000ms, 900, 900s, 和 15m 都等效。

Nmap 会将要扫描的主机总数分成若干组并分块分析,只有当一个块的所有主机均分析完成后才进入下一块(且用户在该块分析完前不会收到更新)。因此对 Nmap 来说使用大块更为高效。默认在 C 类网络使用 256。

可用选项修改该行为: --min-hostgroup --max-hostgroup (调整并行扫描组大小)

可以控制并行扫描器的数量,但通常不建议这样做(Nmap 已根据网络状况自动控制): --min-parallelism --max-parallelism

可以修改 RTT 超时,但通常无需: --min-rtt-timeout --max-rtt-timeout --initial-rtt-timeout

可以修改重试次数: --max-retries

可以修改主机扫描时间: --host-timeout

可以修改每次测试间的延时以减慢速度: --scan-delay --max-scan-delay

可以修改每秒数据包数: --min-rate --max-rate

许多端口在被过滤或关闭时响应很慢。若我们只关心 open 的,可以通过: --defeat-rst-ratelimit 加快速度。

定义 Nmap 激进程度: -T paranoid|sneaky|polite|normal|aggressive|insane

-T(0-1)

-T0 --> 每次仅扫描 1 个端口并等待 5 分钟再进行下一个

-T1 和 T2 --> 非常相似,但分别只等待 15 秒和 0.4 秒

-T3 --> 默认操作,包含并行扫描

-T4 --> --max-rtt-timeout 1250ms --min-rtt-timeout 100ms --initial-rtt-timeout 500ms --max-retries 6 --max-scan-delay 10ms

-T5 --> --max-rtt-timeout 300ms --min-rtt-timeout 50ms --initial-rtt-timeout 250ms --max-retries 2 --host-timeout 15m --max-scan-delay 5ms

防火墙/IDS

它们会阻止对端口的访问并分析数据包。

-f 用于分片数据包,默认把头部后分成 8 字节片段;若要指定大小使用 ..mtu(在这种情况下不要使用 -f),偏移必须是 8 的倍数。版本探测器和脚本不支持分片

-D decoy1,decoy2,ME Nmap 发送扫描流量但源 IP 会伪装成其它地址,以此隐藏你的真实 IP。如果在列表中加入 ME,Nmap 会把你放在列表中,最好在你之前放 5 或 6 个 decoy 来完全掩盖你。可以用 RND: 生成随机 IP。对无连接的 TCP 版本探测器无效。如果你在网络内部,最好使用活动 IP,否则很容易判断你是唯一在线的那个。

使用随机 IP: nmap -D RND:10 Target_IP

-S IP 当 Nmap 无法识别你的 IP 时可手动指定。也可让目标误以为另一个主机在扫描它们。

-e 选择网络接口

许多管理员为便于工作会打开某些入口端口,这比寻找其它解决办法更省事。这些端口可能是 DNS 或 FTP 端口……为发现这类配置错误,Nmap 提供: --source-port -g (两者等价)

--data 发送十六进制数据:--data 0xdeadbeef 或 --data \xCA\xFE\x09

--data-string 发送普通文本:--data-string "Scan conducted by Security Ops, extension 7192"

--data-length Nmap 仅发送头部,使用此选项可额外添加指定字节数(随机生成)

要完整配置 IP 包,请使用 --ip-options

若想查看发送和接收的数据包选项,使用 --packet-trace。有关在 Nmap 中使用 IP options 的更多信息与示例,请参见 http://seclists.org/nmap-dev/2006/q3/52

--ttl

--randomize-hosts 使攻击更不明显

--spoof-mac <MAC address, prefix, or vendor name> 更改 MAC,例如:Apple, 0, 01:02:03:04:05:06, deadbeefcafe, 0020F2, Cisco

--proxies 使用代理,有时代理无法维持 Nmap 需要的并发连接数,因此需要调整并行度: --max-parallelism

-sP 通过 ARP 发现本地网络中的主机

许多管理员创建规则允许来自特定端口的所有数据包通过(如 20、53、67),可以让 Nmap 使用这些端口发送数据: nmap --source-port 53 IP

输出

-oN file 普通输出

-oX file XML 输出

-oS file Script kiddies 输出

-oG file Greppable 输出

-oA file 除 -oS 外的全部输出

-v level 详细程度

-d level 调试级别

--reason 显示主机和状态的原因

--stats-every time 每隔该时间显示进度

--packet-trace 查看发出的数据包,可指定过滤如: --version-trace 或 --script-trace

--open 仅显示 open、open|filtered 和 unfiltered

--resume file 输出摘要以恢复扫描

杂项

-6 支持 IPv6

-A 等同于 -O -sV -sC --traceroute

运行时

在 Nmap 运行期间我们可以修改选项:

v / V 提高 / 降低详细级别

d / D 提高 / 降低调试级别

p / P 开启 / 关闭 packet tracing

? 打印运行时交互帮助界面

Vulscan

Nmap 的脚本,用离线数据库(从其它重要来源下载)比对服务版本并返回可能的漏洞

其使用的数据库有:

  1. Scipvuldb.csv | http://www.scip.ch/en/?vuldb
  2. Cve.csv | http://cve.mitre.org
  3. Osvdb.csv | http://www.osvdb.org
  4. Securityfocus.csv | http://www.securityfocus.com/bid/
  5. Securitytracker.csv | http://www.securitytracker.com
  6. Xforce.csv | http://xforce.iss.net
  7. Exploitdb.csv | http://www.exploit-db.com
  8. Openvas.csv | http://www.openvas.org

下载并安装到 Nmap 目录:

wget http://www.computec.ch/projekte/vulscan/download/nmap_nse_vulscan-2.0.tar.gz && tar -czvf nmap_nse_vulscan-2.0.tar.gz vulscan/ && sudo cp -r vulscan/ /usr/share/nmap/scripts/

还需要下载数据库包并将它们添加到 /usr/share/nmap/scripts/vulscan/ 中

使用方法:

使用所有数据库: sudo nmap -sV --script=vulscan HOST_TO_SCAN

使用特定数据库: sudo nmap -sV --script=vulscan --script-args vulscandb=cve.csv HOST_TO_SCAN

加速 Nmap 服务扫描 x16

根据 to this post 的说明,可以通过将 /usr/share/nmap/nmap-service-probes 中所有的 totalwaitms 值改为 300,以及将 tcpwrappedms 改为 200 来加速 nmap 服务分析。

此外,未为特定探针定义 servicewaitms 的探针会使用默认值 5000。因此我们可以为每个探针添加特定值,或者自己 编译 nmap 并在 service_scan.h 中更改默认值。

如果你不想在 /usr/share/nmap/nmap-service-probes 文件中修改 totalwaitmstcpwrappedms 的值,可以编辑 解析代码,使得该文件中的这些值被完全忽略。

为受限环境构建静态 Nmap

在强化或最小化的 Linux 环境(容器、appliances)中,动态链接的 Nmap 二进制可能因为缺少运行时加载器或共享库(例如 /lib64/ld-linux-x86-64.so.2、libc.so)而无法运行。构建静态链接的 Nmap 并打包 NSE 数据可以在不安装系统包的情况下执行。

高级方法

  • 使用干净的 amd64 Ubuntu 构建器(通过 Docker)。
  • 将 OpenSSL 和 PCRE2 构建为静态库。
  • 构建 Nmap 时静态链接并使用内置的 libpcap/libdnet 以避免动态依赖。
  • 将 NSE 脚本和数据目录与二进制一起打包。

发现目标架构(示例)

bash
uname -a
# If building from macOS/ARM/etc., pin the builder arch:
docker run --rm --platform=linux/amd64 -v "$(pwd)":/out -w /tmp ubuntu:22.04 bash -lc 'echo ok'

第1步 — 准备工具链

bash
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update && apt-get install -y --no-install-recommends \
build-essential ca-certificates curl bzip2 xz-utils pkg-config perl python3 file git \
automake autoconf libtool m4 zlib1g-dev

第2步 — 构建静态 OpenSSL (1.1.1w)

bash
OSSL="1.1.1w"
curl -fsSLO "https://www.openssl.org/source/openssl-$OSSL.tar.gz"
tar xzf "openssl-$OSSL.tar.gz" && cd "openssl-$OSSL"
./Configure no-shared no-zlib linux-x86_64 -static --prefix=/opt/ossl
make -j"$(nproc)" && make install_sw
cd /tmp

第3步 — 构建静态 PCRE2 (10.43)

bash
PCRE2=10.43
curl -fsSLO "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-$PCRE2/pcre2-$PCRE2.tar.bz2"
tar xjf "pcre2-$PCRE2.tar.bz2" && cd "pcre2-$PCRE2"
./configure --disable-shared --enable-static --prefix=/opt/pcre2
make -j"$(nproc)" && make install
cd /tmp

第4步 — 构建静态 Nmap (7.98)

bash
NMAP=7.98
curl -fsSLO "https://nmap.org/dist/nmap-$NMAP.tar.bz2"
tar xjf "nmap-$NMAP.tar.bz2" && cd "nmap-$NMAP"
export CPPFLAGS="-I/opt/ossl/include -I/opt/pcre2/include"
export LDFLAGS="-L/opt/ossl/lib -L/opt/pcre2/lib -static -static-libstdc++ -static-libgcc"
export LIBS="-lpcre2-8 -ldl -lpthread -lz"
./configure \
--with-openssl=/opt/ossl \
--with-libpcre=/opt/pcre2 \
--with-libpcap=included \
--with-libdnet=included \
--without-zenmap --without-ndiff --without-nmap-update
# Avoid building shared libpcap by accident
sed -i -e "s/^shared: /shared: #/" libpcap/Makefile || true
make -j1 V=1 nmap
strip nmap

要点

  • -static, -static-libstdc++, -static-libgcc 强制静态链接。
  • 使用 --with-libpcap=included/--with-libdnet=included 可以避免系统共享库。
  • sed 调整会在存在时使共享 libpcap 目标失效。

步骤 5 — 打包二进制和 NSE 数据

bash
mkdir -p /out/nmap-bundle/nmap-data
cp nmap /out/nmap-bundle/nmap-linux-amd64-static
cp -r scripts nselib /out/nmap-bundle/nmap-data/
cp nse_main.lua nmap-services nmap-protocols nmap-service-probes \
nmap-mac-prefixes nmap-os-db nmap-payloads nmap-rpc \
/out/nmap-bundle/nmap-data/ 2>/dev/null || true

tar -C /out -czf /out/nmap-linux-amd64-static-bundle.tar.gz nmap-bundle

验证与运维注意事项

  • 使用 artifact 上的文件确认它是 statically linked。
  • 将 NSE 数据与 binary 一并保留,以确保在未安装 Nmap 的主机上脚本行为一致。
  • 即便使用 static binary,执行仍可能被 AppArmor/seccomp/SELinux 阻止;DNS/egress 仍必须可用。
  • 确定性构建可降低供应链风险,相较于下载不透明的 “static” binaries。

One-liner (Dockerized)

构建、打包并打印 artifact 信息
bash
docker run --rm --platform=linux/amd64 -v "$(pwd)":/out -w /tmp ubuntu:22.04 bash -lc '
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update && apt-get install -y --no-install-recommends \
build-essential ca-certificates curl bzip2 xz-utils pkg-config perl python3 file git \
automake autoconf libtool m4 zlib1g-dev

OSSL="1.1.1w"; curl -fsSLO "https://www.openssl.org/source/openssl-$OSSL.tar.gz" \
&& tar xzf "openssl-$OSSL.tar.gz" && cd "openssl-$OSSL" \
&& ./Configure no-shared no-zlib linux-x86_64 -static --prefix=/opt/ossl \
&& make -j"$(nproc)" && make install_sw && cd /tmp

PCRE2=10.43; curl -fsSLO "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-$PCRE2/pcre2-$PCRE2.tar.bz2" \
&& tar xjf "pcre2-$PCRE2.tar.bz2" && cd "pcre2-$PCRE2" \
&& ./configure --disable-shared --enable-static --prefix=/opt/pcre2 \
&& make -j"$(nproc)" && make install && cd /tmp

NMAP=7.98; curl -fsSLO "https://nmap.org/dist/nmap-$NMAP.tar.bz2" \
&& tar xjf "nmap-$NMAP.tar.bz2" && cd "nmap-$NMAP" \
&& export CPPFLAGS="-I/opt/ossl/include -I/opt/pcre2/include" \
&& export LDFLAGS="-L/opt/ossl/lib -L/opt/pcre2/lib -static -static-libstdc++ -static-libgcc" \
&& export LIBS="-lpcre2-8 -ldl -lpthread -lz" \
&& ./configure --with-openssl=/opt/ossl --with-libpcre=/opt/pcre2 --with-libpcap=included --with-libdnet=included --without-zenmap --without-ndiff --without-nmap-update \
&& sed -i -e "s/^shared: /shared: #/" libpcap/Makefile || true \
&& make -j1 V=1 nmap && strip nmap

mkdir -p /out/nmap-bundle/nmap-data \
&& cp nmap /out/nmap-bundle/nmap-linux-amd64-static \
&& cp -r scripts nselib /out/nmap-bundle/nmap-data/ \
&& cp nse_main.lua nmap-services nmap-protocols nmap-service-probes nmap-mac-prefixes nmap-os-db nmap-payloads nmap-rpc /out/nmap-bundle/nmap-data/ 2>/dev/null || true \
&& tar -C /out -czf /out/nmap-linux-amd64-static-bundle.tar.gz nmap-bundle \
&& echo "===== OUTPUT ====="; ls -lah /out; echo "===== FILE TYPE ====="; file /out/nmap-bundle/nmap-linux-amd64-static || true
'

参考资料

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks