nmap(Network Mapper)是 Linux 中最强大的网络探测和安全审计工具。它可以发现网络上的主机、扫描开放端口、检测服务版本、识别操作系统,甚至进行漏洞检测。
⚠️ 法律和道德声明
重要:仅扫描你拥有或获得明确授权的网络。未经授权的扫描可能违法。
📦 基本语法
bash
nmap [扫描类型] [选项] {目标规范}
目标规范可以是:
- IP 地址:
192.168.1.1 - IP 范围:
192.168.1.1-100 - CIDR 表示法:
192.168.1.0/24 - 主机名:
example.com - 从文件读取:
-iL hosts.txt
🎯 常用扫描类型
| 扫描类型 | 命令选项 | 说明 |
|---|---|---|
| TCP SYN 扫描 | -sS |
半开放扫描,最常用,不易被检测 |
| TCP Connect 扫描 | -sT |
完全连接扫描,无需 root 权限 |
| UDP 扫描 | -sU |
UDP 端口扫描,速度较慢 |
| ACK 扫描 | -sA |
用于检测防火墙规则 |
| 窗口扫描 | -sW |
利用 TCP 窗口大小差异 |
| MAIMON 扫描 | -sM |
发送 FIN/ACK 包 |
| NULL 扫描 | -sN |
发送无标志包 |
| FIN 扫描 | -sF |
发送 FIN 包 |
| XMAS 扫描 | -sX |
发送 FIN/URG/PSH 包 |
| 空闲扫描 | -sI |
使用僵尸主机进行隐蔽扫描 |
| IP 协议扫描 | -sO |
扫描 IP 协议号 |
🔧 常用选项
| 选项类别 | 选项 | 说明 |
|---|---|---|
| 目标指定 | -iL <文件> |
从文件读取目标列表 |
-iR <数量> |
随机选择目标 | |
--exclude <主机> |
排除主机 | |
--excludefile <文件> |
从文件读取排除列表 | |
| 主机发现 | -sn |
仅进行主机发现,不扫描端口 |
-Pn |
跳过主机发现,假定所有主机在线 | |
-PS/PA/PU/PY[端口] |
TCP SYN/ACK、UDP、SCTP 发现 | |
-PE/PP/PM |
ICMP echo、timestamp、netmask 请求 | |
-PO[协议列表] |
IP 协议 ping | |
| 端口规范 | -p <端口范围> |
指定端口范围 |
-p- |
扫描所有端口(1-65535) | |
-F |
快速扫描(100个常用端口) | |
--top-ports <数量> |
扫描最常见的前 N 个端口 | |
-p U:53,111,T:21-25 |
混合 TCP/UDP 端口 | |
| 服务版本 | -sV |
探测服务/版本信息 |
--version-intensity <0-9> |
版本检测强度(0-9) | |
--version-all |
尝试所有版本检测(强度9) | |
--version-trace |
显示版本检测过程 | |
| 操作系统 | -O |
启用操作系统检测 |
--osscan-limit |
仅对确定的主机进行 OS 检测 | |
--osscan-guess |
更积极地猜测 OS | |
--max-os-tries |
设置 OS 检测尝试次数 | |
| 脚本扫描 | -sC |
使用默认脚本进行扫描 |
--script=<脚本> |
使用指定脚本 | |
--script-args=<参数> |
提供脚本参数 | |
--script-trace |
显示脚本执行过程 | |
--script-updatedb |
更新脚本数据库 | |
| 时序选项 | -T<0-5> |
时序模板(0-5,数字越大越快) |
-T0(偏执) |
非常慢,用于 IDS 规避 | |
-T1(鬼祟) |
慢速扫描,减少带宽消耗 | |
-T2(文雅) |
降低速度,减少干扰 | |
-T3(正常) |
默认速度 | |
-T4(激进) |
快速扫描,可能丢失信息 | |
-T5(疯狂) |
极快,可能被检测 | |
| 输出格式 | -oN <文件> |
标准输出到文件 |
-oX <文件> |
XML 格式输出 | |
-oS <文件> |
Script kiddie 格式输出 | |
-oG <文件> |
Grepable 格式输出 | |
-oA <基本名> |
所有格式输出(.nmap, .xml, .gnmap) | |
| 其他选项 | -v / -vv |
增加详细程度 |
-d / -dd |
增加调试级别 | |
--reason |
显示端口状态原因 | |
--open |
仅显示开放端口 | |
--packet-trace |
显示发送/接收的所有包 | |
--iflist |
显示主机接口和路由 | |
-A |
启用 OS 检测、版本检测、脚本扫描、路由追踪 |
💡 核心用法示例
1. 基本主机发现
bash
# 发现本地网络中的活动主机(不扫描端口)
nmap -sn 192.168.1.0/24
# 发现特定 IP 范围的主机
nmap -sn 192.168.1.1-100
# 从文件读取目标列表进行发现
nmap -sn -iL hosts.txt
# 使用多种发现技术
nmap -sn -PE -PS22,80,443 192.168.1.0/24
2. 端口扫描
bash
# 快速扫描(100个常用端口)
nmap -F 192.168.1.1
# 扫描特定端口
nmap -p 22,80,443 192.168.1.1
# 扫描端口范围
nmap -p 1-1000 192.168.1.1
# 扫描所有端口(1-65535)
nmap -p- 192.168.1.1
# 扫描最常见的 1000 个端口
nmap --top-ports 1000 192.168.1.1
# 混合 TCP/UDP 扫描
nmap -p U:53,67,T:21-25,80,443 192.168.1.1
3. 服务版本检测
bash
# 检测服务版本
nmap -sV 192.168.1.1
# 高强度版本检测
nmap -sV --version-intensity 9 192.168.1.1
# 快速版本检测
nmap -sV --version-light 192.168.1.1
# 显示版本检测过程
nmap -sV --version-trace 192.168.1.1
4. 操作系统检测
bash
# 操作系统检测
nmap -O 192.168.1.1
# 操作系统检测(更积极猜测)
nmap -O --osscan-guess 192.168.1.1
# 仅对确定的主机进行 OS 检测
nmap -O --osscan-limit 192.168.1.1
5. 脚本扫描
bash
# 使用默认脚本扫描
nmap -sC 192.168.1.1
# 使用特定脚本
nmap --script=http-title 192.168.1.1
# 使用多个脚本
nmap --script=http-title,ssl-cert 192.168.1.1
# 使用脚本类别
nmap --script=vuln 192.168.1.1
# 带参数的脚本扫描
nmap --script=smb-enum-shares --script-args=smbuser=admin,smbpass=password 192.168.1.1
6. 综合扫描
bash
# 全面扫描(OS检测、版本检测、脚本扫描)
nmap -A 192.168.1.1
# 全面扫描 + 路由追踪
nmap -A --traceroute 192.168.1.1
# 全面扫描 + 所有端口
nmap -A -p- 192.168.1.1
🔍 输出解读示例
bash
nmap -sS -sV -O 192.168.1.1
典型输出:
Starting Nmap 7.80 ( https://nmap.org ) at 2024-01-01 12:00 CST
Nmap scan report for 192.168.1.1
Host is up (0.0020s latency).
Not shown: 995 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
80/tcp open http nginx 1.14.2
443/tcp open ssl/http nginx 1.14.2
3306/tcp open mysql MySQL 5.5.60
8080/tcp open http-proxy Squid http proxy 3.5.27
MAC Address: 00:11:22:33:44:55 (Vendor Name)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.34 seconds
🔧 实用场景示例
场景 1:网络资产发现
bash
#!/bin/bash
# 网络资产发现脚本
NETWORK="192.168.1.0/24"
OUTPUT_FILE="network_inventory_$(date +%Y%m%d_%H%M%S).txt"
echo "=== 网络资产发现扫描 ==="
echo "网络: $NETWORK"
echo "开始时间: $(date)"
echo "输出文件: $OUTPUT_FILE"
echo ""
# 1. 主机发现
echo "1. 主机发现..."
nmap -sn "$NETWORK" -oG "hosts_scan.gnmap"
# 提取活动主机IP
grep "Status: Up" hosts_scan.gnmap | cut -d' ' -f2 > active_hosts.txt
HOST_COUNT=$(wc -l < active_hosts.txt)
echo "发现 $HOST_COUNT 个活动主机"
# 2. 端口扫描(快速)
echo -e "\n2. 快速端口扫描..."
nmap -F -iL active_hosts.txt -oG "ports_scan.gnmap"
# 3. 详细扫描(对开放端口的主机)
echo -e "\n3. 详细服务扫描..."
while read -r host; do
echo "扫描主机: $host"
nmap -sV -O --script=banner "$host" >> "$OUTPUT_FILE"
echo "---" >> "$OUTPUT_FILE"
done < active_hosts.txt
# 4. 生成报告
echo -e "\n4. 生成摘要报告..."
echo "=== 网络资产摘要 ===" > "summary_$(date +%Y%m%d).txt"
echo "扫描时间: $(date)" >> "summary_$(date +%Y%m%d).txt"
echo "网络范围: $NETWORK" >> "summary_$(date +%Y%m%d).txt"
echo "活动主机数: $HOST_COUNT" >> "summary_$(date +%Y%m%d).txt"
echo "" >> "summary_$(date +%Y%m%d).txt"
# 按服务统计
echo "开放端口统计:" >> "summary_$(date +%Y%m%d).txt"
grep -E "^[0-9]+/tcp.*open" "$OUTPUT_FILE" | \
awk '{print $3}' | sort | uniq -c | sort -rn >> "summary_$(date +%Y%m%d).txt"
echo -e "\n扫描完成!"
echo "详细报告: $OUTPUT_FILE"
echo "摘要报告: summary_$(date +%Y%m%d).txt"
# 清理临时文件
rm -f hosts_scan.gnmap ports_scan.gnmap active_hosts.txt
场景 2:安全审计扫描
bash
#!/bin/bash
# 安全审计扫描脚本
TARGET="$1"
OUTPUT_DIR="security_audit_$(date +%Y%m%d_%H%M%S)"
if [ -z "$TARGET" ]; then
echo "用法: $0 <目标IP/范围>"
exit 1
fi
mkdir -p "$OUTPUT_DIR"
cd "$OUTPUT_DIR" || exit
echo "=== 安全审计扫描 ==="
echo "目标: $TARGET"
echo "开始时间: $(date)"
echo "输出目录: $OUTPUT_DIR"
echo ""
# 1. 全面扫描
echo "1. 执行全面扫描..."
nmap -A -T4 -p- "$TARGET" -oA "full_scan"
# 2. 漏洞扫描
echo -e "\n2. 执行漏洞扫描..."
nmap --script=vuln "$TARGET" -oN "vuln_scan.txt"
# 3. Web 应用扫描
echo -e "\n3. 执行 Web 应用扫描..."
nmap --script=http-* "$TARGET" -oN "web_scan.txt"
# 4. 数据库扫描
echo -e "\n4. 执行数据库扫描..."
nmap --script=mysql-*,postgresql-* "$TARGET" -oN "db_scan.txt"
# 5. SSH 安全扫描
echo -e "\n5. 执行 SSH 安全扫描..."
nmap --script=ssh-* "$TARGET" -oN "ssh_scan.txt"
# 6. 防火墙检测
echo -e "\n6. 执行防火墙检测..."
nmap -sA "$TARGET" -oN "firewall_scan.txt"
# 7. 生成报告
echo -e "\n7. 生成综合报告..."
cat > "security_report.md" << EOF
# 安全审计报告
## 基本信息
- 目标: $TARGET
- 扫描时间: $(date)
- 扫描工具: Nmap $(nmap --version | head -1)
## 扫描结果摘要
### 开放端口
\`\`\`
$(grep -E "^[0-9]+/tcp.*open" full_scan.nmap | head -20)
\`\`\`
### 发现的服务
\`\`\`
$(grep -E "^\|_[0-9]+/tcp" full_scan.nmap | head -20)
\`\`\`
### 操作系统信息
\`\`\`
$(grep -A5 "OS details" full_scan.nmap)
\`\`\`
### 潜在漏洞
\`\`\`
$(grep -E "(VULNERABLE|CVE)" vuln_scan.txt | head -10)
\`\`\`
## 建议
1. 关闭不必要的端口
2. 更新发现的服务到最新版本
3. 检查并修复发现的漏洞
EOF
echo -e "\n扫描完成!"
echo "报告文件: $OUTPUT_DIR/security_report.md"
echo "原始数据文件在: $OUTPUT_DIR/"
场景 3:网络监控
bash
#!/bin/bash
# 网络监控脚本
TARGETS_FILE="monitor_targets.txt"
LOG_DIR="monitor_logs"
INTERVAL=300 # 5分钟
mkdir -p "$LOG_DIR"
echo "=== 网络监控开始 ==="
echo "监控目标: $(cat "$TARGETS_FILE" | wc -l) 个主机"
echo "检查间隔: $INTERVAL 秒"
echo "日志目录: $LOG_DIR"
echo "按 Ctrl+C 停止"
echo ""
while true; do
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$LOG_DIR/scan_$TIMESTAMP.txt"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始扫描..."
# 执行快速扫描
nmap -T4 -F -iL "$TARGETS_FILE" -oN "$LOG_FILE" > /dev/null 2>&1
# 检查变化
if [ -f "$LOG_DIR/last_scan.txt" ]; then
CHANGES=$(diff "$LOG_DIR/last_scan.txt" "$LOG_FILE" | grep -E "^[<>]" | head -5)
if [ -n "$CHANGES" ]; then
echo "检测到变化:"
echo "$CHANGES"
# 发送警报(示例:记录到文件)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 网络变化检测" >> "$LOG_DIR/alerts.log"
echo "$CHANGES" >> "$LOG_DIR/alerts.log"
echo "---" >> "$LOG_DIR/alerts.log"
fi
fi
# 保存本次扫描结果
cp "$LOG_FILE" "$LOG_DIR/last_scan.txt"
# 统计信息
UP_HOSTS=$(grep -c "Status: Up" "$LOG_FILE")
OPEN_PORTS=$(grep -c "open" "$LOG_FILE")
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 扫描完成 - 活动主机: $UP_HOSTS, 开放端口: $OPEN_PORTS"
# 等待下一次扫描
sleep "$INTERVAL"
done
⚙️ Nmap 脚本引擎(NSE)
Nmap 脚本引擎提供了强大的扩展功能:
常用脚本类别
bash
# 查看所有脚本类别
ls /usr/share/nmap/scripts/ | xargs -I {} basename {} .nse | sort -u
# 常用脚本示例
nmap --script=auth 192.168.1.1 # 身份认证检查
nmap --script=brute 192.168.1.1 # 暴力破解
nmap --script=default 192.168.1.1 # 默认脚本
nmap --script=vuln 192.168.1.1 # 漏洞检测
nmap --script=safe 192.168.1.1 # 安全脚本
nmap --script=intrusive 192.168.1.1 # 侵入式脚本
nmap --script=discovery 192.168.1.1 # 发现脚本
nmap --script=dos 192.168.1.1 # 拒绝服务检测
nmap --script=exploit 192.168.1.1 # 漏洞利用
nmap --script=external 192.168.1.1 # 外部脚本
自定义脚本扫描
bash
# 扫描特定服务
nmap --script=ftp-* 192.168.1.1
nmap --script=http-* 192.168.1.1
nmap --script=smb-* 192.168.1.1
nmap --script=ssh-* 192.168.1.1
nmap --script=ssl-* 192.168.1.1
# 使用多个脚本
nmap --script=http-title,http-headers,http-methods 192.168.1.1
# 带参数的脚本
nmap --script=http-brute --script-args userdb=users.txt,passdb=passwords.txt 192.168.1.1
⚠️ 重要注意事项
- 法律合规:仅扫描你有权扫描的网络。
- 扫描速度 :避免过快的扫描(使用
-T选项控制)。 - 隐蔽性:某些扫描类型可能被入侵检测系统发现。
- 资源消耗:全面扫描可能消耗大量网络和系统资源。
- 准确性:防火墙、IDS 可能影响扫描结果准确性。
- 版本更新:定期更新 nmap 和脚本数据库。
🔄 相关工具
| 工具 | 用途 | 说明 |
|---|---|---|
masscan |
高速端口扫描 | 比 nmap 更快,但功能较少 |
zmap |
互联网范围扫描 | 专为快速互联网扫描设计 |
netdiscover |
ARP 发现工具 | 局域网主机发现 |
hping3 |
数据包构造工具 | 高级网络测试 |
nc (netcat) |
网络瑞士军刀 | 端口测试和连接 |
tcpdump |
网络抓包工具 | 流量分析 |
🎯 最佳实践
- 分阶段扫描:先主机发现,再端口扫描,最后服务检测。
- 保存结果 :使用
-oA保存所有格式的结果。 - 使用脚本:合理使用 NSE 脚本增强扫描能力。
- 定时扫描:定期扫描监控网络变化。
- 结果分析:结合其他工具分析 nmap 结果。
nmap 是网络管理员、安全专家和渗透测试人员的必备工具。掌握其用法可以帮助你更好地了解网络状况、发现安全漏洞和监控网络变化。