发布于1小时前1小时 背景在授权渗透测试中,资产发现和漏洞验证不能简单等同于“全端口扫描加模板全跑”。扫描范围失控、并发过高或验证请求带有写入动作,都可能影响业务,也会让后续复盘缺少可信依据。本文以 Kali Linux 为操作端,使用 Nmap 完成端口与服务识别,再用 Nuclei 对已确认的 Web 服务做低影响验证,同时保留命令、原始结果和时间信息。以下操作仅适用于已取得书面授权的目标。开始前应明确 IP、域名、测试时段、允许的协议、速率上限和禁止触碰的系统。场景与问题定位假设授权范围为 10.20.30.0/24,但其中仅 10.20.30.40 至 10.20.30.60 可以测试;任务是确认对外服务、识别 TLS 与 HTTP 配置问题,并验证已知漏洞线索。常见问题包括:直接扫描整个网段,越过授权边界。依赖默认端口,遗漏 8080、8443 等实际 Web 服务。把 Nmap 的版本识别结果直接当作漏洞结论,没有进行二次验证。Nuclei 模板来源和版本不可追溯,导致结果无法复现。只保存截图,不保留 XML、JSONL 和原始响应证据。工具安装与完整性检查Kali 仓库中的 Nmap 可以直接通过 APT 安装。Nuclei 建议使用发行包或官方 Go 模块安装,并记录版本。不要从不明网盘下载二进制文件。sudo apt update sudo apt install -y nmap curl jq git # 已配置 Go 环境时安装 Nuclei CGO_ENABLED=0 go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest install -m 0755 "$HOME/go/bin/nuclei" "$HOME/.local/bin/nuclei" nmap --version $HOME/.local/bin/nuclei -version sha256sum "$HOME/.local/bin/nuclei" | tee nuclei.sha256执行前建立独立工作目录,并记录 UTC 时间、操作人员和授权单编号。这样可以把每次测试结果与具体工具版本绑定。CASE_ID="PT-2025-017" WORKDIR="$HOME/pt-logs/$CASE_ID" mkdir -p "$WORKDIR"/{scope,nmap,nuclei,evidence} date -u +'%Y-%m-%dT%H:%M:%SZ' | tee "$WORKDIR/start_time.txt" printf '%s\n' '10.20.30.40-60' > "$WORKDIR/scope/authorized-range.txt" nmap --version > "$WORKDIR/nmap/version.txt" nuclei -version > "$WORKDIR/nuclei/version.txt" 2>&1第一步:固化授权范围不要直接把整个 CIDR 交给扫描器。先生成允许测试的目标清单,再人工复核。Nmap 的 -sL 只做目标枚举,不发送端口探测包,适合检查范围是否符合授权。nmap -sL -n 10.20.30.40-60 \ -oN "$WORKDIR/scope/enumerated-targets.txt" # 确认清单后提取 IP,后续所有命令只读取该文件 grep 'Nmap scan report for' "$WORKDIR/scope/enumerated-targets.txt" \ | awk '{print $NF}' \ > "$WORKDIR/scope/targets.txt" cat "$WORKDIR/scope/targets.txt"如果域名也在范围内,应另建域名白名单,不建议在扫描过程中自动跟随重定向到授权范围之外的主机。第二步:低速率端口与服务识别先探测常见业务端口,再根据结果决定是否扩大范围。以下命令关闭 DNS 解析,设置主机超时和重试次数,并同时输出普通文本、XML 与 grepable 格式。-Pn 仅适用于已确认在线但禁用 ICMP 的主机,否则可能增加无效流量。sudo nmap -sS -sV --version-light -n \ -p 22,80,443,445,3389,8080,8443 \ --max-retries 2 --host-timeout 5m \ --max-rate 100 \ -iL "$WORKDIR/scope/targets.txt" \ -oA "$WORKDIR/nmap/service-baseline" # 检查已识别的开放端口 grep '/open/' "$WORKDIR/nmap/service-baseline.gnmap"这里不建议一开始使用 -A。该选项会启用操作系统识别、脚本扫描和路由跟踪,动作多且不利于控制测试面。若需全端口检查,可以在业务低峰期对单个目标执行,并继续限制速率:sudo nmap -sS -n -p- --max-rate 200 --max-retries 1 \ --host-timeout 15m 10.20.30.45 \ -oA "$WORKDIR/nmap/10.20.30.45-allports"第三步:针对性使用 Nmap NSENSE 脚本应按服务选择,避免直接运行 --script all。对于 TLS 服务,可以检查证书和密码套件;对于 HTTP 服务,可以读取标题和响应头。以下脚本以信息采集为主,不执行口令猜测或写入操作。sudo nmap -sV -n -p 80,443,8080,8443 \ --script http-title,http-headers,ssl-cert,ssl-enum-ciphers \ --script-timeout 30s --max-rate 50 \ -iL "$WORKDIR/scope/targets.txt" \ -oA "$WORKDIR/nmap/web-validation"分析时要区分“事实”和“推断”:开放端口、证书有效期、服务返回头属于直接证据;根据 Banner 推断的软件版本可能受代理、伪装或回传错误影响,不能直接作为漏洞成立依据。第四步:生成 Web 目标并人工复核可以从 Nmap XML 中提取候选服务,但建议先人工确认协议。8443 不一定使用 HTTPS,8080 也可能是其他 TCP 服务。以下示例使用 Nmap 自带的 XSL 转换结果辅助排查,最终 URL 写入白名单文件。cat > "$WORKDIR/nuclei/urls.txt" <<'EOF' EOF # 先确认状态码、跳转位置和目标 IP,不自动跟随跳转 while read -r url; do printf '\n== %s ==\n' "$url" curl -k -sS -I --max-time 10 --connect-timeout 5 "$url" \ | sed -n '1,10p' done < "$WORKDIR/nuclei/urls.txt" \ | tee "$WORKDIR/evidence/http-head-check.txt"若响应中的 Location 指向第三方域名,应从自动验证中移除,除非该域名也明确写入授权范围。第五步:受控运行 Nuclei更新模板后记录模板版本或 Git 提交号。首次验证建议限定为配置错误、暴露面和已知 CVE 等类别,并排除 fuzz、dos、headless 等可能产生较大影响的标签。并发和速率应按业务承载能力调整。nuclei -update-templates TEMPLATE_DIR="$HOME/nuclei-templates" git -C "$TEMPLATE_DIR" rev-parse HEAD \ | tee "$WORKDIR/nuclei/template-commit.txt" nuclei \ -l "$WORKDIR/nuclei/urls.txt" \ -severity medium,high,critical \ -tags cve,misconfig,exposure \ -exclude-tags fuzz,dos,headless,intrusive \ -rate-limit 20 -concurrency 5 -bulk-size 5 \ -timeout 8 -retries 1 \ -jsonl-export "$WORKDIR/nuclei/findings.jsonl" \ -stats不要把模板命中直接写成“已成功利用”。Nuclei 结果需要检查匹配条件、响应状态、响应体特征和目标实际版本。对高危结果应使用单模板、单目标重新验证,并降低速率:nuclei \ -u ' \ -t "$TEMPLATE_DIR/http/cves/2024/example.yaml" \ -rate-limit 1 -concurrency 1 -retries 0 \ -debug -debug-req -debug-resp \ > "$WORKDIR/evidence/manual-recheck.txt" 2>&1调试文件可能包含 Cookie、Authorization 头和页面敏感内容,应按敏感证据管理,不要直接附在公开报告中。结果判定与排查方法现象排查重点结论要求Nmap 识别出旧版本检查反向代理、Banner 准确性、厂商补丁回移不能仅凭版本字符串确认漏洞Nuclei 命中 CVE核对模板 matcher、响应证据和适用版本至少完成一次低影响人工复核大量超时或 429检查 WAF、限流、并发和业务负载立即降速,必要时暂停并通知窗口负责人扫描结果前后不一致核对负载均衡节点、DNS、扫描时间和源地址记录环境差异,不强行合并结果日志留痕与证据保护测试结束后计算文件哈希,保证交付结果未被修改。XML 和 JSONL 适合后续解析,普通文本便于人工复核,两类文件都应保留。find "$WORKDIR" -type f -print0 \ | sort -z \ | xargs -0 sha256sum \ > "$WORKDIR/SHA256SUMS" chmod -R go-rwx "$WORKDIR" tar -czf "$CASE_ID.tar.gz" -C "$(dirname "$WORKDIR")" "$CASE_ID" sha256sum "$CASE_ID.tar.gz" > "$CASE_ID.tar.gz.sha256"报告中建议记录:测试源 IP、时间窗口、目标清单、完整命令、工具版本、模板提交号、原始结果哈希、误报复核过程,以及是否触发 WAF 或业务告警。风险与修复建议对不必要的管理端口实施网络层收敛,只允许堡垒机或指定运维网段访问。对 8080、8443 等非标准端口执行与 80、443 相同的资产登记、证书检查和补丁管理。修复弱 TLS 配置时,优先禁用 TLS 1.0、TLS 1.1 和已知弱密码套件,同时评估旧客户端兼容性。发现版本暴露时,不要只隐藏 Banner;应先确认受影响组件并安装厂商补丁,隐藏版本只能降低信息泄露。对 Web 管理面启用强认证、最小权限和访问审计,并将扫描源 IP 纳入临时监控规则,便于区分授权测试与异常流量。修复后使用相同目标文件、相同模板版本和相近网络条件复测,避免因工具或模板变化造成结论漂移。总结Nmap 和 Nuclei 的价值不在于“跑得多”,而在于把授权范围、探测动作、验证证据和复测结果串成可审计链路。实际操作中应先固化目标白名单,再进行低速率服务识别;NSE 和 Nuclei 都按需选用,命中结果必须结合响应证据二次确认。保留 XML、JSONL、工具版本、模板提交号和哈希文件,才能让漏洞结论可复现,也便于防守方定位日志并完成修复闭环。 网络请求、日志与边界流量分析示意 漏洞成因、验证条件与修复闭环示意
刚才1分钟 这套流程里,建议重点补上“范围约束、输入归一化、结果留痕”三步。实际执行时不要直接把整段网段交给 Nuclei,否则容易混入非 Web 服务,也不利于后续复核。 1. 固化授权范围并先做端口、服务识别 mkdir -p evidence/{nmap,nuclei,meta} cat > scope.txt <<'EOF' 192.0.2.10 192.0.2.20 EOF date -u +"%FT%TZ" | tee evidence/meta/start_time.txt sha256sum scope.txt | tee evidence/meta/scope.sha256 sudo nmap -Pn -sS -sV --open \ -p 80,443,8080,8443,8000,8888 \ -T3 --max-rate 300 \ --script http-title,http-headers,ssl-cert \ -iL scope.txt \ -oA evidence/nmap/web-discovery -oA 会同时保存普通文本、XML 和 grepable 输出。后续应保留 XML,方便按主机、端口和服务重新解析,不要只截图。若授权范围明确禁止主机发现绕过,则去掉 -Pn;公网资产也应按授权书限制扫描速率。 2. 从 Nmap XML 生成 Nuclei 输入 不要仅根据端口号判断协议,优先读取 Nmap 识别出的 tunnel 和 service: python3 - <<'PY' import xml.etree.ElementTree as ET root = ET.parse("evidence/nmap/web-discovery.xml").getroot() urls = set() for host in root.findall("host"): addr_node = host.find("address") if addr_node is None: continue addr = addr_node.attrib["addr"] for port in host.findall("./ports/port"): state = port.find("state") service = port.find("service") if state is None or state.attrib.get("state") != "open": continue p = int(port.attrib["portid"]) name = service.attrib.get("name", "") if service is not None else "" tunnel = service.attrib.get("tunnel", "") if service is not None else "" if tunnel == "ssl" or name in {"https", "https-alt"}: scheme = "https" elif name.startswith("http"): scheme = "http" elif p in {443, 8443}: scheme = "https" elif p in {80, 8000, 8080, 8888}: scheme = "http" else: continue default = (scheme == "http" and p == 80) or (scheme == "https" and p == 443) urls.add(f"{scheme}://{addr}" if default else f"{scheme}://{addr}:{p}") with open("evidence/nuclei/targets.txt", "w") as f: for url in sorted(urls): f.write(url + "\n") PY cat evidence/nuclei/targets.txt 如果资产通过域名区分虚拟主机,直接使用 IP 会漏报,甚至命中错误站点。此时应把授权清单中的域名作为主要输入,并保留“域名—解析 IP—扫描时间”的对应关系。 3. Nuclei 先跑非侵入式模板 nuclei -version | tee evidence/meta/nuclei-version.txt nuclei -ut nuclei -tv | tee evidence/meta/templates-version.txt nuclei \ -l evidence/nuclei/targets.txt \ -severity info,low,medium,high,critical \ -tags tech,misconfig,exposure,cve \ -exclude-tags dos,fuzz,bruteforce,headless \ -rl 20 -c 5 -timeout 8 -retries 1 \ -jsonl-export evidence/nuclei/results.jsonl \ -o evidence/nuclei/results.txt 模板更新后结果可能变化,因此报告里至少记录 Nuclei 版本和 templates 版本。正式项目更稳妥的方式是固定 templates 的 Git commit,而不是扫描当天直接更新后不留版本信息。 4. 漏洞验证不要只看模板命中 复核 template-id、matcher-name、matched-at 和实际响应证据。 版本型 CVE 命中只能作为线索,需结合补丁回移、发行版公告和实际功能验证。 涉及写入、上传、认证绕过或命令执行的验证,应单独审批;默认排除 DoS、爆破和高副作用模板。 敏感响应中的 Cookie、Token、身份证号等内容应脱敏,不建议原样进入工单或报告。 5. 对证据文件做完整性校验 date -u +"%FT%TZ" | tee evidence/meta/end_time.txt find evidence -type f ! -name SHA256SUMS -print0 \ | sort -z \ | xargs -0 sha256sum \ > evidence/SHA256SUMS tar -czf evidence-$(date -u +%Y%m%dT%H%M%SZ).tar.gz evidence/ 如果还要做到可审计,建议同时保存执行账号、出口 IP、授权单编号、完整命令、开始结束时间以及 NTP 状态。这样出现告警或争议时,可以把某次请求准确关联到具体扫描任务,而不是只拿一份 Nuclei 文本结果作为依据。
创建帐户或登录后发表意见