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
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
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
-sV 版本探测,强度可从 0 到 9 调节,默认 7。
--version-intensity
-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
--script-trace ---> 提供脚本执行的进展信息
--script-updatedb
要使用脚本,只需输入: nmap --script Script_Name target --> 使用脚本时,脚本与扫描器都会执行,因此也可添加扫描器选项。可加入 "safe=1" 以只执行安全脚本。
时间控制
Nmap 可以接受以秒、分钟、毫秒为单位的时间参数:--host-timeout 参数 900000ms, 900, 900s, 和 15m 都等效。
Nmap 会将要扫描的主机总数分成若干组并分块分析,只有当一个块的所有主机均分析完成后才进入下一块(且用户在该块分析完前不会收到更新)。因此对 Nmap 来说使用大块更为高效。默认在 C 类网络使用 256。
可用选项修改该行为: --min-hostgroup
可以控制并行扫描器的数量,但通常不建议这样做(Nmap 已根据网络状况自动控制): --min-parallelism
可以修改 RTT 超时,但通常无需: --min-rtt-timeout ,--max-rtt-timeout ,--initial-rtt-timeout
可以修改重试次数: --max-retries
可以修改主机扫描时间: --host-timeout
可以修改每次测试间的延时以减慢速度: --scan-delay ;--max-scan-delay
可以修改每秒数据包数: --min-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: nmap -D RND:10 Target_IP
-S IP 当 Nmap 无法识别你的 IP 时可手动指定。也可让目标误以为另一个主机在扫描它们。
-e
许多管理员为便于工作会打开某些入口端口,这比寻找其它解决办法更省事。这些端口可能是 DNS 或 FTP 端口……为发现这类配置错误,Nmap 提供: --source-port
--data
--data-string
--data-length
要完整配置 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
-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 的脚本,用离线数据库(从其它重要来源下载)比对服务版本并返回可能的漏洞
其使用的数据库有:
- Scipvuldb.csv | http://www.scip.ch/en/?vuldb
- Cve.csv | http://cve.mitre.org
- Osvdb.csv | http://www.osvdb.org
- Securityfocus.csv | http://www.securityfocus.com/bid/
- Securitytracker.csv | http://www.securitytracker.com
- Xforce.csv | http://xforce.iss.net
- Exploitdb.csv | http://www.exploit-db.com
- 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 文件中修改 totalwaitms 和 tcpwrappedms 的值,可以编辑 解析代码,使得该文件中的这些值被完全忽略。
为受限环境构建静态 Nmap
在强化或最小化的 Linux 环境(容器、appliances)中,动态链接的 Nmap 二进制可能因为缺少运行时加载器或共享库(例如 /lib64/ld-linux-x86-64.so.2、libc.so)而无法运行。构建静态链接的 Nmap 并打包 NSE 数据可以在不安装系统包的情况下执行。
高级方法
- 使用干净的 amd64 Ubuntu 构建器(通过 Docker)。
- 将 OpenSSL 和 PCRE2 构建为静态库。
- 构建 Nmap 时静态链接并使用内置的 libpcap/libdnet 以避免动态依赖。
- 将 NSE 脚本和数据目录与二进制一起打包。
发现目标架构(示例)
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步 — 准备工具链
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)
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)
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)
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 数据
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 信息
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
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
HackTricks