Nmap + Masscan + ffuf 实战:扫描流水线 + 自动化脚本
前言
Masscan 找"活的",Nmap 回答"是什么",ffuf 发现"藏了什么"。本文给出完整扫描流水线和可直接用的脚本。
一、Masscan(全端口秒扫)
1.1 基础用法
# 全端口扫描(1-65535)
masscan example.com -p1-65535 --rate=10000 -oL masscan.txt
# 网段扫描
masscan 10.0.0.0/24 -p1-65535 --rate=50000 -oL masscan.txt
# 高危端口快速扫
masscan example.com -p21,22,23,25,53,80,110,135,139,143,443,445,1433,1521,3306,3389,5432,6379,7001,8080,8443,9090 --rate=50000
# 从文件读 IP
masscan -iL targets.txt -p1-65535 --rate=50000 -oL masscan.txt
# 多种输出
masscan example.com -p1-65535 -oL a.txt -oJ b.json -oG c.gnmap
1.2 高级参数
# 设置源端口(某些防火墙会过滤)
masscan example.com -p80 --source-port 53 --rate=1000
# 设置源 IP(多网卡环境)
masscan example.com -p80 -e eth0 --adapter-ip 192.168.1.100
# 随机化扫描顺序
masscan example.com -p1-65535 --randomize-hosts
# 排除某些 IP
masscan example.com -p1-65535 --excludefile exclude.txt
# 等待所有响应后退出
masscan example.com -p1-65535 --wait=10
二、Nmap(服务识别 + 漏洞扫描)
2.1 基础用法
# 快速扫描常见端口 + 服务识别
nmap -sV -sC example.com -oN nmap.txt
# 全端口扫描(慢但全)
nmap -sV -sC -p- --min-rate 1000 example.com -oN nmap_full.txt
# 操作系统检测
nmap -O example.com
# 漏洞扫描脚本
nmap --script vuln example.com -oN nmap_vuln.txt
# Masscan -> Nmap 管道
masscan example.com -p1-65535 --rate=10000 -oL masscan.txt
PORTS=$(grep open masscan.txt | awk '{print $4}' | cut -d: -f2 | sort -un | tr '\n' ',')
nmap -sV -sC -p "$PORTS" example.com -oN nmap_targeted.txt
# 批量扫描多主机
nmap -iL alive.txt -sV -sC -oN nmap_batch.txt
2.2 NSE 脚本速查
# 暴力破解
nmap --script ftp-brute,http-brute,mysql-brute,smb-brute example.com
# 漏洞检测
nmap --script vuln example.com
nmap --script http-vuln-cve2021-44228 example.com # Log4Shell
nmap --script http-vuln-cve2021-40444 example.com # MSHTML
# 信息收集
nmap --script http-headers,http-title,http-methods example.com
nmap --script dns-brute example.com
nmap --script smb-os-discovery,smb-enum-shares example.com
# SSL 检查
nmap --script ssl-enum-ciphers,ssl-cert example.com
# 完整高危漏洞扫描
nmap --script "vuln and safe" example.com
2.3 Nmap XML 解析脚本
#!/usr/bin/env python3
"""Parse Nmap XML output into structured report."""
import xml.etree.ElementTree as ET
import sys
def parse_nmap_xml(xml_path):
tree = ET.parse(xml_path)
root = tree.getroot()
results = []
for host in root.findall("host"):
ip = host.find("address").get("addr")
ports = []
for port in host.findall(".//port"):
portid = port.get("portid")
proto = port.get("protocol")
state = port.find("state").get("state")
svc = port.find("service")
service = svc.get("name", "") if svc is not None else ""
product = svc.get("product", "") if svc is not None else ""
version = svc.get("version", "") if svc is not None else ""
ports.append({
"port": int(portid), "proto": proto, "state": state,
"service": service, "product": product, "version": version
})
results.append({"ip": ip, "ports": ports})
return results
if __name__ == "__main__":
data = parse_nmap_xml(sys.argv[1])
for host in data:
print()
print("=" * 60)
print("Host:", host["ip"])
print("=" * 60)
for p in host["ports"]:
banner = (p["product"] + " " + p["version"]).strip()
print(f" {p['port']:>5}/{p['proto']} {p['state']:>7} {p['service']:<15} {banner}")
三、ffuf(目录 + 参数 Fuzz)
3.1 目录爆破
# 基础
ffuf -u "http://example.com/FUZZ" -w ~/wordlists/directory-list-2.3-medium.txt -mc 200,301,302,403,500 -t 50 -o ffuf_dir.txt
# 带扩展名 + 大小写变体
ffuf -u "http://example.com/FUZZ" -w dirs.txt -e php,asp,aspx,jsp,html,txt,bak,zip,swp
# 过滤已知 404 页面大小
ffuf -u "http://example.com/FUZZ" -w dirs.txt -fs 1234 -t 50
# HTTPS + 忽略证书
ffuf -u "https://example.com/FUZZ" -w dirs.txt -k
# 自定义 Header
ffuf -u "http://example.com/FUZZ" -w dirs.txt -H "Authorization: Bearer xxx"
# POST Body Fuzz
ffuf -u "http://example.com/api/FUZZ" -w api.txt -X POST -d "data=FUZZ"
# 递归(爬一层再爬一层)
ffuf -u "http://example.com/FUZZ" -w dirs.txt -mc 200 -t 50 -of json -o l1.json
jq -r ".results[].input.FUZZ" l1.json | while read d; do
ffuf -u "http://example.com/$d/FUZZ" -w subdirs.txt -mc 200 -t 50 -o "l2_$d.txt"
done
3.2 参数枚举
# GET 参数
ffuf -u "http://example.com/page?FUZZ=test" -w params.txt -mc 200 -fs 0
# POST 参数
ffuf -u "http://example.com/api/user" -w params.txt -X POST -d "FUZZ=test" -H "Content-Type: application/x-www-form-urlencoded"
# JSON 参数
ffuf -u "http://example.com/api/user" -w params.txt -X POST -d '{"FUZZ":"test"}' -H "Content-Type: application/json"
# Arjun(专门的参数发现工具)
python3 arjun.py -u http://example.com --rate-limit 10
python3 arjun.py -i urls.txt --output json -o params.json
3.3 字典推荐
综合目录字典:
- directory-list-2.3-medium.txt(22 万条,够用)
- raft-medium-directories.txt
- wordlist/raft-large-directories.txt
子域名 / API / 敏感文件:
- subdomains-top10000.txt
- PayloadsAllTheThings 里的 API 字典
- Seclists: https://github.com/danielmiessler/SecLists
四、完整扫描流水线脚本
#!/bin/bash
# full_scan.sh - Masscan + Nmap + ffuf 流水线
DOMAIN=$1
OUT="./scan_$DOMAIN"
mkdir -p "$OUT" && cd "$OUT"
echo "[1/5] 子域名枚举..."
subfinder -d "$DOMAIN" -silent > subs.txt
echo " -> $(wc -l < subs.txt) 个子域名"
echo "[2/5] 存活探测..."
cat subs.txt | httpx -silent -title -o alive_web.txt
echo " -> $(wc -l < alive_web.txt) 个活跃 Web"
echo "[3/5] 端口扫描..."
cat subs.txt | httpx -silent -ip | awk '{print $NF}' | sort -u > ips.txt
masscan -iL ips.txt -p1-65535 --rate=50000 -oL masscan.txt
echo " -> Masscan 完成"
echo "[4/5] Nmap 服务识别..."
grep open masscan.txt | awk '{print $4}' | cut -d: -f1 | sort -u | while read ip; do
ports=$(grep "Open.*${ip}" masscan.txt | awk '{print $NF}' | cut -d/ -f1 | sort -un | tr '\n' ',')
nmap -sV -sC -p "${ports%,}" "$ip" -oN "nmap_${ip}.txt" &
done
wait
echo " -> Nmap 完成"
echo "[5/5] 目录爆破..."
while read url; do
ffuf -u "${url}/FUZZ" -w ~/wordlists/directory-list-2.3-medium.txt -mc 200,301,302,403 -t 30 -o "ffuf_$(echo $url | sed 's|https\?://||;s|/$||').txt" &
done < alive_web.txt
wait
echo " -> ffuf 完成"
echo ""
echo "===== 扫描完成 ====="
echo "活跃 Web: $(wc -l < alive_web.txt)"
echo "开放端口: $(grep -c open masscan.txt)"
echo "Nmap 文件: $(ls nmap_*.txt 2>/dev/null | wc -l)"
echo "ffuf 结果: $(ls ffuf_*.txt 2>/dev/null | wc -l)"
五、各工具职责 + 常见坑
Masscan 常见坑:
- masscan -p1-65535 example.com 扫的是 C 段,不是该域名的所有 IP
应该先解析域名到 IP 再扫
- --rate 太高会丢包,生产环境建议 1000-5000
- masscan 不会做 DNS 反查
Nmap 常见坑:
- -p- 全端口扫很慢,先用 masscan 筛出开放端口再用 nmap
- --min-rate 不要太大,会丢包
- -sV 服务识别是探测包,生产环境慎用
ffuf 常见坑:
- -fs 响应大小过滤很重要
- -fw 过滤特定字数也好用
- FUZZ 和 fuzz 的位置要对(大小写敏感)
- 先跑小字典验证,再跑大字典
三者配合:
Masscan 快速找出开放端口
-> Nmap 识别是什么服务
-> ffuf 找隐藏路径
六、推荐资源
- Masscan: https://github.com/robertdavidgraham/masscan
- Nmap Docs: https://nmap.org/docs.html
- ffuf: https://github.com/ffuf/ffuf
- PayloadsAllTheThings: https://github.com/swisskyrepo/PayloadsAllTheThings
- Seclists: https://github.com/danielmiessler/SecLists