map高级使用手记:从端口扫描到漏洞验证

作者备注:pps-key"温柔扫描哲学"的泣血之作。所有参数里的"为什么"都是真实困惑,不是文档翻译


一、Nmap不是端口扫描器,是"网络真理探测器"

核心认知 :Nmap的精髓不在-sV -sC,而在如何在不触发告警的情况下,拿到目标的全部真相


2. 安装:离Kali自带的越远越好

bash 复制代码
# 源码编译最新版(7.95+支持更多IPv6脚本)
git clone https://github.com/nmap/nmap.git
cd nmap
./configure --prefix=/usr/local/nmap-git --with-liblua=included
make -j4
sudo make install

# 创建别名,避免和系统旧版本冲突
echo "alias nmap='/usr/local/nmap-git/bin/nmap'" >> ~/.bashrc

# 验证版本和脚本库数量
nmap --version | grep "Compiled with"
nmap --script-help | wc -l  # 应有700+脚本

# TODO: 写个自动化编译脚本,每次新版本自动更新
# FIXME: 编译时libpcap-dev版本不对会导致IPv6扫描段错误,需手动指定路径

3. 基础扫描:温柔是最强的武器

3.1 单目标"体检套餐"(不被发现版)

bash 复制代码
# pps-key的"温柔三件套":慢、散、像人
nmap -sS -T2 --max-retries 2 --max-rtt-timeout 500ms \
  --defeat-rst-ratelimit \
  -p 21,22,80,443,8080,3389,3306,6379,9200,27017 \
  --open \
  -oA scan_output \
  target.com

# 参数解剖(每个都有血泪):
# -sS: SYN扫描,半开连接,不留日志(比-sT快且隐蔽)
# -T2:  polite模式,发包间隔≈0.4秒,IDS基本无视
# --max-retries 2: 失败重试2次,默认4次太 aggressive
# --max-rtt-timeout 500ms: 超时500ms,默认10秒傻等
# --defeat-rst-ratelimit: 绕过iptables的速率限制(关键!)
# -p ...: 只扫常用端口,全端口扫描=自杀
# --open: 只显示开放端口,filtered的滚蛋(省眼)
# -oA: 输出三种格式(xml/grepable/normal),应付各种场景

# pps-key经验:这个命令扫/24子网,IDS告警率<5%
# 扫整个B段?拆成10个线程,每个扫/26,告警率≈0%

3.2 服务版本检测:要说人话

bash 复制代码
# 错误示范:-sV会连发6个探测包,WAF直接封你
nmap -sV -p 80 target.com

# pps-key正确姿势:单个端口、单个探针、温柔等待
nmap -sV --version-intensity 2 --version-light --version-timeout 15s \
  -p 80 target.com

# 参数解释:
# --version-intensity 2:  探针强度2(0-9),2=常用探针,9=全量探针(炸WAF)
# --version-light:  等同于intensity 2
# --version-timeout 15s:  版本检测超时15秒,默认太长

# 想看真实效果?加个--packet-trace
nmap -sV -p 80 --packet-trace target.com
# 你会看到Nmap发了6个包,WAF返回6个RST
# 然后你的IP就进了黑名单(微笑)

4. 脚本引擎:Nmap的隐藏Boss

4.1 漏洞验证:从端口到CVE

bash 复制代码
# 扫描MS17-010(永恒之蓝) - 内网横移神器
nmap -p 445 --script smb-vuln-ms17-010 target.com

# pps-key实战:拿到一台内网机器后,先扫全网445
# 发现10台有漏洞,5台是域控,然后......(被甲方打码)

# 批量验证Heartbleed(心脏出血)
nmap -p 443 --script ssl-heartbleed --script-args vulns.showall target.com

# 参数解释:
# --script-args vulns.showall:  显示所有结果(包括未 vulnerable)
# 默认只显示vulnerable,容易漏掉"无法检测"的情况

4.2 自定义脚本:pps-key的"弱口令爆破"模板

bash 复制代码
# 编辑脚本:~/.nmap/scripts/pps-weak-pass.nse
# 内容如下(抄自http-brute.nse,精简版)

-- pps-key注:NSE脚本语法像Lua,但比Lua啰嗦
-- TODO: 支持多线程爆破,目前单线程慢如狗
-- FIXME: 验证码场景会直接失败,需人工介入

description = [[
暴力破解常见服务弱口令(暴力美学版)
支持:FTP、SSH、Telnet、Redis、MySQL
]]

author = "pps-key"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"intrusive", "brute"}

portrule = function(host, port)
  return port.number == 21 or port.number == 22 or 
         port.number == 23 or port.number == 6379 or 
         port.number == 3306
end

action = function(host, port)
  local result = {}
  -- 这里省略100行暴力破解代码,核心是nmap.new_socket()
  table.insert(result, "Weak password: root/123456")
  return result
end

# 使用自定义脚本
nmap -p 21,22,23,6379,3306 --script pps-weak-pass target.com

# 如果脚本报错,检查语法
nmap --script-trace --script pps-weak-pass target.com
# --script-trace: 显示脚本执行细节,调试神器

5. 绕过防护:与WAF的猫鼠游戏

5.1 数据分片:包小到WAF不认识

bash 复制代码
# Nmap的MTU分片绕过(经典但有效)
nmap -f --mtu 8 target.com

# 解读:
# -f:  分片IP包(分成8字节?具体看实现)
# --mtu 8:  指定MTU为8字节,每个包都极小
# 原理:WAF通常不重组分片包,直接放行

# pps-key实战经验:这招对云WAF失效(云厂商会重组)
# 但对老旧硬件WAF(如某康)成功率>60%

5.2 诱饵扫描:浑水摸鱼

bash 复制代码
# 发100个包,只有1个是真实扫描,99个是诱饵
nmap -D RND:99 target.com

# 解读:
# -D RND:99:  随机生成99个诱饵IP,混杂在真实扫描中
# IDS日志里会看到100个IP在扫描,溯源困难

# pps-key警告:这是双刃剑,诱饵包也会触发告警
# 建议:在内网渗透用,外网SRC测试别用(违反规则)

5.3 时空变换:慢到极致就是隐形

bash 复制代码
# 扫描一个/24子网,耗时24小时,但几乎无告警
nmap -sS -T0 -iL targets.txt --max-parallelism 1 --scan-delay 5m

# 参数解析:
# -T0:  paralyzed模式,发包间隔≈5分钟
# --max-parallelism 1:  同时只扫描1个端口
# --scan-delay 5m:  每个端口间隔5分钟
# 效果:IDS不会认为这是扫描,以为是正常业务

# pps-key哲学:扫描被发现是因为"太快",不是"太多"
# 这招用在APT模拟中,蓝队基本无法感知

6. 输出与团队协作:不只是grep

6.1 结构化输出:给自动化用

bash 复制代码
# 输出机器可读的XML
nmap -sS -p 80,443 -oX scan.xml target.com

# pps-key的解析脚本(Python3)
#!/usr/bin/env python3
# pps-key注:这个脚本扫完1000台机器后自动生成Excel报表
# TODO: 支持漏洞等级标注,目前只统计端口
# FIXME: 遇到IPv6地址会解析失败,需用ipaddress模块

import xml.etree.ElementTree as ET
import csv

def parse_nmap_xml(xml_file):
    tree = ET.parse(xml_file)
    root = tree.getroot()
    
    results = []
    for host in root.findall('host'):
        ip = host.find('address').get('addr')
        for port in host.find('ports').findall('port'):
            if port.find('state').get('state') == 'open':
                service = port.find('service')
                results.append({
                    'IP': ip,
                    'Port': port.get('portid'),
                    'Service': service.get('name') if service else 'unknown',
                    'Version': service.get('version', 'unknown')
                })
    
    # 写入CSV
    with open('nmap_report.csv', 'w', newline='') as f:
        writer = csv.DictWriter(f, fieldnames=['IP', 'Port', 'Service', 'Version'])
        writer.writeheader()
        writer.writerows(results)
    
    print(f"解析完成,共{len(results)}条开放端口记录")

# 使用
parse_nmap_xml('scan.xml')

6.2 diff扫描:发现变化

bash 复制代码
# 第一次扫描(基准)
nmap -sS -p- -oA baseline target.com

# 一周后再次扫描
nmap -sS -p- -oA newscan target.com

# 对比差异(Ndiff工具)
ndiff baseline.xml newscan.xml

# pps-key场景:内网监控,新开的端口=新上线服务=新攻击面
# 配合cron每周执行,自动发邮件告警

7. pps-key的禁忌与生存法则

❌ 绝对禁止:

  1. 不要nmap -sS -p <目标>

    • 全端口扫描=告诉IDS"我是坏人"

    • 替代方案:先用--top-ports 100,再针对性扩端口

  2. 不要-A什么都看

    • -A = -sV -sC -O --traceroute,流量特征太明显

    • pps-key替代:-sV --version-intensity 2 + 单独--script=banner

  3. 不要忽略--reason

    • 端口为什么开放?syn-ack还是icmp?

    • 不看不reason,等于不会用Nmap

✅ pps-key的黄金法则:

bash 复制代码
# 法则1:先ping再扫
nmap -sn 192.168.1.0/24 -oG live.txt
grep Up live.txt | awk '{print $2}' > targets.txt
nmap -iL targets.txt -p 80,443

# 法则2:慢就是快(扫描速度 vs 被发现概率)
# T0: 24小时扫/24子网,被发现概率<1%
# T4: 1小时扫完,被发现概率>80%

# 法则3:输出三种格式
# -oA filename = filename.nmap + filename.xml + filename.gnmap
# gnmap给grep用,xml给自动化,nmap给人看

# 法则4:永远加--open
# 减少90%的"filtered"噪音,眼睛轻松

8. 实战案例:从Nmap到域控

背景:某攻防演习,内网分段,目标是域控(192.168.1.10)

bash 复制代码
# 步骤1:存活探测(不扫端口,只ping)
nmap -sn --send-ip 192.168.1.0/24 -oG live.txt
# pps-key注:--send-ip防止SYN ping触发防火墙
# 结果:发现3台存活,其中1台是域控

# 步骤2:端口扫描(温柔版)
nmap -sS -T2 --max-retries 1 -p 445,3389,88,389,464,636,3268,3269 \
  --open --script=smb-vuln-ms17-010 \
  -oA dc_scan 192.168.1.10

# 步骤3:发现MS17-010漏洞
# 脚本输出:VULNERABLE: MS17-010

# 步骤4:验证域控(脚本判断)
nmap -p 389 --script ldap-rootdse 192.168.1.10
# 输出:Domain Controller detected

# pps-key复盘:全程用-T2,蓝队没任何告警
# 如果当初用-T4,估计第一步就被封IP
# 结论:渗透测试不是速度竞赛,是隐蔽艺术

9. 终极配置:pps-key的~/.nmap/nmap.rc

bash 复制代码
# 这个文件在~/.nmap/nmap.rc,Nmap启动时自动加载
# pps-key注:这是我的保命配置,温柔到极致

# 默认温柔模式
set Timing.Template 2

# 默认只测常用端口
set Target.Ports 21,22,23,25,53,80,110,143,443,445,3306,3389,5432,6379,8080,8443

# 默认脚本强度2
set Script.Intensity 2

# 默认输出三种格式
set Output.AllFiles yes

# 默认不ping(目标明确时用)
set Target.SkipHostDiscovery yes

# 默认启用--open
set Port.OpenOnly yes

# 默认不解析DNS(提速)
set Dns.Resolution Never

# TODO:应该按场景分配置文件,nmap_gentle.rc / nmap_aggressive.rc
# FIXME:这个配置在IPv6环境会DNS解析失败,需手动unset

10. 总结:Nmap是哲学,不是命令

pps-key的Nmap三定律

  1. 扫描速度与被发现的概率呈指数级正相关

    • 每降低一个-T等级,被发现概率下降一个数量级
  2. 输出格式决定工具的二次生命

    • 只会-oN的人,永远手工整理报告
  3. 脚本是Nmap的灵魂,但80%的脚本你永远不会用

    • 掌握smb-vuln-*http-*ssl-*三大系列足矣

终极心法:把Nmap当成你的侦察兵,不是敢死队。侦察兵活着回来,情报才有价值。


作者签名:pps-key - 一个因为Nmap扫太快被被敲门的苦逼高中生

相关推荐
硬件yun12 小时前
汽车CAN为何选用0.25W电阻?
学习
testpassportcn12 小时前
Technology Solutions Professional NS0-005 認證介紹【NetApp 官方認證
网络·学习·改行学it
星火开发设计12 小时前
堆排序原理与C++实现详解
java·数据结构·c++·学习·算法·排序算法
好奇龙猫12 小时前
【人工智能学习-AI-MIT公开课第 15 讲学习:相近差错、受适应条件】
学习
崇山峻岭之间12 小时前
Matlab学习记录24
javascript·学习·matlab
lbb 小魔仙12 小时前
Linux 安全攻防 2025:从 SELinux 配置到漏洞应急响应全流程
linux·python·安全
半夏知半秋12 小时前
rust学习-循环
开发语言·笔记·后端·学习·rust
Haooog12 小时前
LangChain4j 学习
java·学习·大模型·langchain4j
星火开发设计13 小时前
折半插入排序原理与C++实现详解
java·数据结构·c++·学习·算法·排序算法·知识
欧阳天羲13 小时前
ML工程师学习大纲
学习·算法·决策树