nmap还用介绍吗?搞安全的人还有不知道或者不会用nmap的吗?据我观察,能够全面灵活运用nmap的人其实并不多见。其实nmap早已经不再是你眼中那个网络层的扫描器软件了,早在十年前它就已经进化成为一个全功能的安全评估框架。今天,利用nmap强大的脚本功能,你可以轻松开发出任何漏洞检测和利用的功能,甚至完全不需要掌握那些常见的编程语言。本课我向你介绍了nmap几乎全部参数功能,同时演示了如何自己开发一个脚本的过程。
本文使用的nmap版本是7.92

TCP syn扫描,利用TCP的三次握手机制,当发送syn包后,如果目标主机的那个端口是开着的,就会返回syn+ack数据包,同时nmap接收到之后不再返回ack的确认包,不会建立完成的TCP连接,节约扫描发起者机器的资源1000个常用端口,包括http、https、ftp、smtp、ssh等等| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.1,2,25 | 扫描10.0.2.1、10.0.2.2、10.0.2.25这3个IP |
sudo nmap 10.0.1,2.23,25 | 扫描10.0.1.23、10.0.1.25、10.0.2.23、10.0.2.25这4个IP |
sudo nmap 10.0,1.2,3.23,25 | 扫描10.0.2.23、10.0.2.25、10.0.3.23、10.0.3.25、10.1.2.23、10.1.2.25、10.1.3.23、10.1.3.25这8个IP |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.20-25 | 扫描10.0.2.20-25这一段的IP |
sudo nmap 10.0.2-10,25 | 扫描10.0.2-10,25这几段的IP |
sudo nmap 10.0.2-10.20-25 | 扫描10.0.2-10.20-25这几段的IP |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25/24 | 扫描10.0.2.1/24这个网段中的所有IP |
sudo nmap 10.0.2.1/16 | 扫描10.0.2.1/16这个网段中的所有IP |

| 例子 | 含义 |
|---|---|
sudo nmap -iL ip.txt | 扫描ip.txt这个文件内容中所有的IP,注意IP得是一个一行的形式写入文件中 |

| 例子 | 含义 |
|---|---|
sudo nmap www.baidu.com | 扫描www.baidu,com这个域名对应的IP |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25/24 --exclude 10.0.2.2,3,4 | 扫描10.0.2.1/24这个网段中除10.0.2.2、10.0.2.3、10.0.2.4外的所有IP |
sudo nmap 10.0.2.25/24 --exclude 10.0.2.2-10 | 扫描10.0.2.1/24这个网段中除10.0.2.2-10这一段外的所有IP |
sudo nmap 10.0.2.25/16 --exclude 10.0.2.0/24 | 扫描10.0.2.1/16这一大段中除10.0.2.0/24这一小段外的所有IP |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25/24 --excludefile exip.txt | 扫描10.0.2.25/24这个网段中除exip.txt文件内容中包含的IP外的所有IP |

| 例子 | 含义 |
|---|---|
sudo nmap 220.181.38.251 -R -sn | 在扫描时一定要做DNS反向域名查询,也就是查询IP地址对应的域名,并且只做主机发现 |


| 例子 | 含义 |
|---|---|
sudo nmap 220.181.38.251 -n -sn | 在扫描时不做DNS反向域名查询,也就是不查询IP地址对应的域名,并且只做主机发现 |


| 例子 | 含义 |
|---|---|
sudo nmap 220.181.38.251 -R --dns-servers 114.114.114.114 -sn | 在扫描时做DNS反向域名查询,指定DNS服务器为114.114.114.114,并且只做主机发现 |


| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -e eth0 | 指定发扫描数据包的网卡为eth0 |

如果没有指定发包网卡,nmap就会使用本机序号为第一个的网卡发扫描包
做扫描的时候,先做主机发现,别一上来就对所有的
IP发送大量数据包进行端口扫描,不要做这种莽撞的行为,因为在扫描的时候经常会触发安全机制的报警,所以做扫描的时候要越隐蔽越好,先做主机发现再做端口扫描,不仅节省自己的时间,还能避免被发现,何乐而不为呢?
向目标系统的80或443端口发送ICMP和TCP ping扫描,如果目标系统返回了ICMP响应包、SYN+ACK包、RST+ACK包,就认为这个IP是活着的
并且判断完IP是否是活着的之后,就会结束,不会再发送端口扫描数据包
| 例子 | 含义 |
|---|---|
sudo nmap -sn 192.168.123.2 | 扫描192.168.123.2是否是活着的 |


跳过主机发现环节,直接将IP视为在线状态,直接发送大量的端口扫描数据包;不加此参数的情况是:若发现此IP不在线,则不进行端口扫描
因为会发出大量的扫描数据包,一点也不隐蔽,所以用此参数来进行主机发现是不可取的
| 例子 | 含义 |
|---|---|
sudo nmap -Pn 192.168.123.2 | 扫描192.168.123.2,不管此IP是否是活着的状态 |

| 例子 | 含义 |
|---|---|
sudo nmap www.baidu.com --traceroute -sn | 在扫描结果种显示每一跳经过的路由IP,而且只做主机发现这一步 |
加入这个参数之后只会发送TCP SYN数据包包
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -PS -sn | 只发送TCP SYN 包进行主机发现 |


加入这个参数之后只会发送TCP ACK数据包
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -PA -sn -n | 只发送TCP ACK 包进行主机发现,并且跳过DNS反向域名解析环节 |


加入这个参数之后只会发送UDP 数据包
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -PU -sn -n | 只发送UDP 包进行主机发现,并且跳过DNS反向域名解析环节 |


加入这个参数之后只会发送SCTP 数据包
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -PY -sn -n | 只发送SCTP 包进行主机发现,并且跳过DNS反向域名解析环节 |


加入这个参数之后只会发送ICMP 数据包,跟使用ping命令是完全一回事
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -PE -sn -n | 只发送ICMP 包进行主机发现,并且跳过DNS反向域名解析环节 |


请求目标系统时间戳,如果返回的话则说明这个IP是活着的
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -PP -sn -n | 请求目标系统时间戳,如果返回的话则说明这个IP是活着的,并且跳过DNS反向域名解析环节 |


抓包结果显示发送了两次 ICMP 数据包请求目标系统时间戳都没有得到回复,但其实这个IP是活着的
注意:每个参数的使用场景不一样,没有哪个参数可以全场景覆盖,要针对当前扫描的环境使用相对应的扫描参数
请求目标子网掩码,如果返回的话则说明这个IP是活着的
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -PM -sn -n | 请求目标系统子网掩码,如果返回的话则说明这个IP是活着的,并且跳过DNS反向域名解析环节 |


抓包结果显示发送了两次 ICMP 数据包请求目标系统子网掩码都没有得到回复,但其实这个IP是活着的
注意:每个参数的使用场景不一样,没有哪个参数可以全场景覆盖,要针对当前扫描的环境使用相对应的扫描参数
指定IP协议包探测目标主机是否开启,如果返回的话则说明这个IP是活着的
| 数值 | 值描述 |
|---|---|
| 0 | 保留字段,用于IPv6(跳跃点到跳跃点选项) |
| 1 | Internet控制消息 (ICMP) |
| 2 | Internet组管理 (IGMP) |
| 3 | 网关到网关 (GGP) |
| 4 | IP中的IP(封装) |
| 5 | 流 |
| 6 | 传输控制 (TCP) |
| 7 | CBT |
| 8 | 外部网关协议 (EGP) |
| 9 | 任何私有内部网关(Cisco在它的IGRP实现中使用) (IGP) |
| 10 | BBNRCC监视 |
| 11 | 网络语音协议 |
| 12 | PUP |
| 13 | ARGUS |
| 14 | EMCON |
| 15 | 网络诊断工具 |
| 16 | 混乱(Chaos) |
| 17 | 用户数据报文 (UDP) |
| 18 | 复用 |
| 19 | DCN测量子系统 |
| 20 | 主机监视 |
| 21 | 包无线测量 |
| 22 | XEROXNSIDP |
| 23 | Trunk-1 |
| 24 | Trunk-2 |
| 25 | leaf-1 |
| 26 | 1eaf-2 |
| 27 | 可靠的数据协议 |
| 28 | Internet可靠交易 |
| 29 | 1SO传输协议第四类 (TP4) |
| 30 | 大块数据传输协议 |
| 31 | MFE网络服务协议 |
| 32 | MERIT节点之间协议 |
| 33 | 序列交换协议 |
| 34 | 第三方连接协议 |
| 35 | 域之间策略路由协议 |
| 36 | XTP |
| 37 | 数据报文传递协议 |
| 38 | IDPR控制消息传输协议 |
| 39 | TP+ +传输协议 |
| 40 | IL传输协议 |
| 41 | IPv6 |
| 42 | 资源命令路由协议 |
| 43 | IPv6的路由报头 |
| 44 | IPv6的片报头 |
| 45 | 域之间路由协议 |
| 46 | 保留协议 |
| 47 | 通用路由封装 |
| 48 | 可移动主机路由协议 |
| 49 | BNA |
| 50 | IPv6封装安全有效负载 |
| 51 | IPv6验证报头 |
| 52 | 集成的网络层安全TUBA |
| 53 | 带加密的IP |
| 54 | NBMA地址解析协议 |
| 55 | IP可移动性 |
| 56 | 使用Kryptonet钥匙管理的传输层安全协议 |
| 57 | SKIP |
| 58 | IPv6的ICMP |
| 59 | IPv6的无下一个报头 |
| 60 | IPv6的信宿选项 |
| 61 | 任何主机内部协议 |
| 62 | CFTP |
| 63 | 任何本地网络 |
| 64 | SATNET和BackroomEXPAK |
| 65 | Kryptolan |
| 66 | MIT远程虚拟磁盘协议 |
| 67 | Internet Pluribus包核心 |
| 68 | 任何分布式文件系统 |
| 69 | SATNET监视 |
| 70 | VISA协议 |
| 71 | Internet包核心工具 |
| 72 | 计算机协议Network Executive |
| 73 | 计算机协议Heart Beat |
| 74 | Wang Span网络 |
| 75 | 包视频协议 |
| 76 | Backroom SATNET监视 |
| 77 | SUN ND PROTOCOL—临时 |
| 78 | WIDEBAND监视 |
| 79 | WIDEBAND EXPAK |
| 80 | ISO Internet协议 |
| 81 | VMTP |
| 82 | SECURE—VMTP(安全的VMTP) |
| 83 | VINES |
| 84 | TTP |
| 85 | NSFNET—IGP |
| 86 | 不同网关协议 |
| 87 | TCF |
| 88 | EIGRP |
| 89 | OSPF IGP |
| 90 | Sprite RPC协议 |
| 9] | Locus地址解析协议 |
| 92 | 多播传输协议 |
| 93 | AX.25帧 |
| 94 | IP内部的IP封装协议 |
| 95 | 可移动网络互连控制协议 |
| 96 | 旗语通讯安全协议 |
| 97 | IP中的以太封装 |
| 98 | 封装报头 |
| 99 | 任何私有加密方案 |
| 100 | GMTP |
| 101 | Ipsilon流量管理协议 |
| 102 | PNNI over IP |
| 103 | 协议独立多播 |
| 104 | ARIS |
| 105 | SCPS |
| 106 | QNX |
| 107 | 活动网络 |
| 108 | IP有效负载压缩协议 |
| 109 | Sitara网络协议 |
| 110 | Compaq对等协议 |
| 111 | IP中的IPX |
| 112 | 虚拟路由器冗余协议 |
| 113 | PGM可靠传输协议 |
| 114 | 任何0跳跃协议 |
| 115 | 第二层隧道协议 |
| 116 | D-II数据交换(DDX) |
| 117 | 交互式代理传输协议 |
| 118 | 日程计划传输协议 |
| 119 | SpectraLink无线协议 |
| 120 | UTI |
| 121 | 简单消息协议 |
| 122 | SM |
| 123 | 性能透明性协议 |
| 124 | ISIS over IPv4 |
| 125 | FIRE |
| 126 | Combat无线传输协议 |
| 127 | Combat无线用户数据报文 |
| 128 | SSCOPMCE |
| 129 | IPLT |
| 130 | 安全包防护 |
| 131 | IP中的私有IP封装 |
| 132 | 流控制传输协议 |
| 133~254 | 未分配 |
| 255 | 保留 |
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -PO1 -sn -n | 指定IP协议包探测目标主机是否开启,-PO1表示使用ICMP协议,如果返回的话则说明这个IP是活着的,并且跳过DNS反向域名解析环节 |


| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --top-ports 100 | 扫描前100个最常用的端口 |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -p22,80,443,5000 | 扫描10.0.2.25的22、80、443、5000端口 |
sudo nmap 10.0.2.25 -p1-100 | 扫描10.0.2.25的1-100端口 |
sudo nmap 10.0.2.25 -p- | 扫描10.0.2.25的全部端口,也就是1-65535端口 |

| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -sS | 发TCP的SYN数据包进行扫描 |


| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -sA | 发TCP的ACK数据包进行扫描 |


有些特殊的应用可能会拒绝SYN扫描,拒绝半开的连接,所以这时候必须要通过三次握手建立完成的TCP连接才能发现端口是否是开放的
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -sT | 通过三次握手建立完整的TCP连接,来判断端口是否开放 |


目标主机收到包之后丢弃掉,即不做响应代表这个端口是开放的,如果返回RST数据包则表示这个端口是开放的;当然这和目标主机的安全配置有关,只是一般情况下是这样的
所以使用此参数进行端口扫描时要先确保目标IP是活着的
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -sN | 发送的TCP包flag位全设置为0,进行端口扫描 |


目标主机收到包之后丢弃掉,即不做响应代表这个端口是开放的,如果返回RST数据包则表示这个端口是开放的;当然这和目标主机的安全配置有关,只是一般情况下是这样的
所以使用此参数进行端口扫描时要先确保目标IP是活着的
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -sF | 发送的TCP数据包flag中Fin设置为1 |


目标主机收到包之后丢弃掉,即不做响应代表这个端口是开放的,如果返回RST数据包则表示这个端口是开放的;当然这和目标主机的安全配置有关,只是一般情况下是这样的
所以使用此参数进行端口扫描时要先确保目标IP是活着的
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -sX | 发送的TCP数据包flag中Urgent、Push、Fin设置为1 |


| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --scanflags syn,ack,fin | 自定义发送的TCP数据包flag中syn、ack、Fin设置为1 |


参数:-sI <zombie host[:probeport]> 僵尸扫描
是非常非常隐蔽的扫描方式
原理
首先需要在被扫描的网络中找一台符合下面两个要求的计算机
非常非常空闲的计算机,空闲到没有和别的任何计算机进行通信(在一个大型的网络中这种空闲的机器还是比较好找的)
这台计算机的IPID必须是递增的,且增长方式是有规律的,比方说每次递增1(IPID即是IP头部的ID字段)
很多的计算机的
IPID都是递增的,比方说一天中的第一个数据包的IPID是随即的,下一个数据包的IPID则会在前一个的IPID上加1或加2或者加一些有规律的数值
nmap先探测僵尸机当前的IPID是多少,并记录下来
然后nmap将自己的IP地址伪装成僵尸机的IP地址,向要目标主机的端口发送SYN包
目标主机端口接收到SYN包之后
如果目标端口是开放的则会向僵尸机发送SYN+ACK,但是僵尸机从头到尾都没有发送过SYN包,凭空接收到了目标主机的向它发送SYN+ACK,僵尸机就会返回RST数据包,此时僵尸机的IPID递增1

如果目标端口是关闭的则会向僵尸机发送RST包,僵尸机莫名其妙的接收到这个RST包之后会将这个包丢弃掉,此时僵尸机的IPID不变化

这时候nmap再次向僵尸机发送数据包,探测僵尸机当前的IPID,如果数值为之前探测的基础上+2,则表明目标主机的目标端口是开放的;如果数值为之前探测的基础上+1,则表明目标主机的目标端口是关闭的
在整个过程中扫描者是完全隐蔽的,安全性很高。但是反向做路由追踪还是有可能发现的,不过难度特别大。
例子
IP:10.0.2.11IP:10.0.2.25实施僵尸扫描
执行命令:sudo nmap 10.0.2.25 -sI 10.0.2.11 -Pn

注:利用此命令可以单独探测僵尸机的IPID变化规律
执行命令:sudo nmap 10.0.2.11 -p445 --script=ipidseq.nse 使用nmap专门用来扫描IPID变化的脚本ipidseq.nse
因为UDP是不建立连接的,没有办法像TCP那样在建立连接的过程中就可以判断出端口是否开放,所以扫UDP端口挺不靠谱的
扫UDP端口一般需要建立基于UDP以上的应用层连接,发送应用层报文才可以判断UDP端口是否开放
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -sU | 发送UDP数据包,扫描UDP 端口 |


如果目标主机和kali不在同一网段中
执行命令:sudo nmap 192.168.123.1,2 -p80,5000
一图胜千言

如果目标主机和kali在同一网段中
执行命令:sudo nmap 10.0.2.2,25 -p22,5000
一图胜千言

结合多种方式,包括banner,指纹等技术,判断目标端口上运行的到底是什么服务,准确率很高的
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -p22,5000 -sV | 探测22和5000端口运行的是什么服务 |

| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -p53 -sU -sV | 探测UDP 53端口运行的是什么服务 |

很多情况下没有办法100%判断出系统的具体版本,就会给出所有可能的结果
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -O | 探测系统版本 |

0最慢,5最快,不过最快速度可能会更容易被发现
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -T3 | 限定扫描速度为等级3 |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --scan-delay 10s | 每个扫描间隔10秒 |
sudo nmap 10.0.2.25 --scan-delay 10m | 每个扫描间隔10分钟 |
sudo nmap 10.0.2.25 --scan-delay 10h | 每个扫描间隔10小时 |
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --min-rate | 最小扫描速度 |
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --max-rate | 最大扫描速度 |
nmap扫描大范围地址块时经常会被卡死在中间的一个IP中。
绝大多数是由于目标系统的安全机制造成的,目标系统发现你在扫描时就估计将你的扫描请求挂在那不响应,让扫描进行不下去
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.0/24 --host-timeout 10m | 设置扫描超时时间为10分钟,超过了设置的时间就会扫描下一个 |
将IP数据段分片发送,使目标的安全机制IPS等设备无法还原数据包的原始内容,从而使安全检测机制失效
比方说
标准的TCP包头是20个字节,加入了-f参数后会将这个20字节分3个包发出去,第一个包8字节,第二个包8字节,第三个包4字节再加上4字节TCP数据段的内容(如果有数据段的话也是每次发8字节)
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -f | 将 IP 数据段分片(8字节一片) |
ME代表自己的IP
伪造多个源IP发送扫描数据包,将真实的扫描IP隐藏起来
据有些安全资料上说,当
ME位于第6个*或者再之后时,有些知名厂家安全设备不会记录到安全日志中
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -D 10.0.2.22,10.0.2.23,10.0.2.24,ME | 伪造10.0.2.22 10.0.2.23 10.0.2.24和自己的真实IP ME对目标10.0.2.25进行扫描 |
将源IP进行伪造,使用此参数的话还需要别的方法判断伪造的源IP是否接收到了回包
此参数需要搭配-e <iface>指定网卡,-Pn跳过主机发现这两个参数
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -S 10.0.2.11 -e eth0 -Pn | 伪造源IP为10.0.2.11进行探测,并且指定了发包网卡为eth0,跳过主机发现环节 |
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -g 3333 | 指定扫描数据包发送的端口为3333 |
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --proxies http://10.0.2.11:8080 | 使用HTTP代理进行发包扫描 |
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --data "AABB02" | 在扫描数据包附加16进制数据AABB02 |
sudo nmap 192.168.123.1 --data "\xAA\xBB\x02" | 在扫描数据包附加16进制数据\xAA\xBB\x02 |
sudo nmap 192.168.123.1 --data "0xaabb02" | 在扫描数据包附加16进制数据0xaabb02 |


| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --data-string aabbccdd | 在扫描数据包附加ASCII数据aabbccdd |
sudo nmap 192.168.123.1 --data-string "aa bb cc dd" | 在扫描数据包附加ASCII数据aa bb cc dd |


| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --ttl 25 | 指定发送扫描包的TTL值为25 |


可能会造成收不到回包的情况
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --spoof-mac AA:BB:CC:DD:EE:FF | 伪造数据包中的MAC地址AA:BB:CC:DD:EE:FF |


将IP包头中的checksum校验值故意写错,看看目标的安全检测机制会不会放弃这样的包,从而绕过安全机制
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --badsum | 故意使用错误的checksu |
三种主要的根式日志,分别是xml、nmap、gnmap
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -oA a | 将扫描结果保存为三种主要的根式日志,文件名为a |

a.nmap格式的内容就是屏幕输出的内容

a.gnmap格式的内容是为了方便用grep命令筛选结果的

比方说扫描了大量的IP后,现在想要提取所有开放80端口的IP地址
可以这样执行命令:cat a.gnmap | grep 80

a.xml格式就是xml格式喽
三种主要的根式日志,分别是xml、nmap、gnmap
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -oX a | 将扫描结果保存为XML格式文件,文件名为a.xml |
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -v | 显示详细信息 |
sudo nmap 192.168.123.1 -vv | 显示更详细信息 |
sudo nmap 192.168.123.1 -vvv | 显示更更详细信息 |
sudo nmap 192.168.123.1 -v3 | 等同于-vvv |
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 -d | 显示debug信息 |
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --reason | 在结果中显示判断端口状态的依据 |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --open | 只显示开放的端口 |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --packet-trace | 显示nmap都发了和都收了什么包 |

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 --script-trace | 只显示脚本都发了和都收了什么包 |
| 例子 | 含义 |
|---|---|
sudo nmap --iflist | 显示系统中都有哪些网卡 |

| 例子 | 含义 |
|---|---|
sudo nmap fe80::a00:27ff:fe6a:30e3 -6 | 开启IPV6扫描 |
2006年发布4.21 ALPHA1版本时加入的
在第二届Google summer code大会上创造的
由于具有NSE脚本引擎,所以nmap成为了全功能的扫描工具套件
基于lua语言特殊标记的脚本框架,脚本由NSE执行
lua是非常快速的解释性语言,很多waf上会使用lua
升级脚本文件:nmap --script-updatedb
脚本文件保存在:/usr/share/nmap/scripts
脚本的描述和使用方法:https://nmap.org/nsedoc/ 或者 在脚本中查看description部分
目前默认包含600多个脚本(14大类)
| 类型 | 中文 |
|---|---|
| Auth | 身份认证 |
| Broadcast | 广播 |
| Brute | 暴力 |
| Default | 默认 |
| Discovery | 发现类 |
| Dos | 拒绝服务 |
| Exploit | 漏洞利用 |
| External | 外部类(查询第三方接口获取信息,比方说有的网站会公布这个IP是否已经中招了、遭泄露了等等) |
| Fuzzer | 模糊测试 |
| Intrusive | 入侵性探测 |
| Malware | 恶意软件类 |
| Safe | 安全 |
| Version | 获取版本信息类 |
| Vuln | 漏洞类 |
一般在企业中建议使用Default,Safe类型的脚本进行扫描,尽量避免使用Intrusive、Dos、Exploit类型的脚本,尽量对自己家的服务器温柔一点
| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --script=http-title | 使用http-title.nse这个脚本 |
sudo nmap 10.0.2.25 -sC | 使用所有的Default类脚本 |
sudo nmap 10.0.2.25 --script=default | 使用所有的Default类脚本,与-sC相同 |
sudo nmap 10.0.2.25 --script=vuln | 使用所有的Vuln类脚本 |
sudo nmap 10.0.2.25 --script=dos,exploit,vuln | 使用所有的Dos、Exploit、Vuln类脚本 |
sudo nmap 10.0.2.25 --script="not(dos or exploit or vuln)" | 使用除Dos、Exploit、Vuln类外的所有脚本 |
sudo nmap 10.0.2.25 --script="whois-ip,banner,upnp-info" | 使用whois-ip.nse、banner.nse、upnp-info.nse这三个脚本 |
sudo nmap 10.0.2.25 --script="http-*" | 使用所有的以http-开头的脚本 |
sudo nmap 10.0.2.25 --script="http-* and not(http-slowloris or http-brute or http-enum or http-form-fuzzer)" | 使用除http-slowloris.nse、http-brute.nse、http-enum.nse、http-form-fuzzer.nse外所有以http-开头的脚本 |
sudo nmap 10.0.2.25 --script=+vuln -p4343 | 使用所有的Vuln类脚本扫描4343端口;当服务不工作在非标准端口时,部分脚本就不工作了,使用+来强制Vuln类所有脚本都要对4343端口进行扫描 |

| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --script=http-title --script-args=http.useragent="w00l00" | 使用http-title.nse这个脚本,并设置其中的useragent参数值为w00l00 |


| 例子 | 含义 |
|---|---|
sudo nmap 192.168.123.1 --script=http-majordomo2-dir-traversal,http-axis2-dir-traversal --script-args=http-axis2-dir-traversal.uri=/axis2/,uri=/majordomo/ | 分别指定http-majordomo2-dir-traversal.nse和http-axis2-dir-traversal.nse两个脚本中的uri参数值 |
| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -sL --script=targets-sniffer -e eth0 | targets-sniffer.nse脚本的功能是做被动侦听 |
sudo nmap 10.0.2.25 -p3306 -script=mysql-brute | 针对mysql 3306端口做简单的暴力破解密码 |
sudo nmap 10.0.2.25 -p25 -script=smtp-brute | 针对smtp 25端口做简单的暴力破解密码 |
sudo nmap 10.0.2.25 -p3306 -script=mysql-audit --script-args='mysql-audit.username="root"',mysql-audit.password="pass",mysql-audit.filename=/usr/share/nmap/nselib/data/mysql-cis.audit | 提供mysql账号root密码pass,连接之后,按照/usr/share/nmap/nselib/data/mysql-cis.audit文件内容做相应的审计,检测是否存在漏洞 |
sudo nmap 10.0.2.25 -p445 -n --open --script=smb-vuln-ms17-010.nse | 检测ms17-010漏洞 |

使用Lua的语法写就行,注意要把TAB键改成2个空格长度
先来看一个现成的smb-vuln-ms17-010.nse
----------------------------------------------------------- 头部 ---------------------------------------------------------------------------------------------------------------------- 头部 ---------------------------------------------------------------------------------------------------------------------- 头部 ------------------------------------------------------------- 变量定义,应用模块local nmap = require "nmap"local smb = require "smb"local vulns = require "vulns"local stdnse = require "stdnse"local string = require "string"-- 描述,我这个脚本干嘛用的;[[ ]] 是多行注释description = [[Attempts to detect if a Microsoft SMBv1 server is vulnerable to a remote code execution vulnerability (ms17-010, a.k.a. EternalBlue). The vulnerability is actively exploited by WannaCry and Petya ransomware and other malware.The script connects to the $IPC tree, executes a transaction on FID 0 and checks if the error "STATUS_INSUFF_SERVER_RESOURCES" is returned to determine if the target is not patched against ms17-010. Additionally it checks for known error codes returned by patched systems.Tested on Windows XP, 2003, 7, 8, 8.1, 10, 2008, 2012 and 2016.References:* https://technet.microsoft.com/en-us/library/security/ms17-010.aspx* https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/* https://msdn.microsoft.com/en-us/library/ee441489.aspx* https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/smb/smb_ms17_010.rb* https://github.com/cldrn/nmap-nse-scripts/wiki/Notes-about-smb-vuln-ms17-010]]----- 告诉你这个脚本怎么用,怎么样执行命令-- @usage nmap -p445 --script smb-vuln-ms17-010 <target>-- @usage nmap -p445 --script vuln <target>---- @see smb-double-pulsar-backdoor.nse---- @output-- Host script results:-- | smb-vuln-ms17-010:-- | VULNERABLE:-- | Remote Code Execution vulnerability in Microsoft SMBv1 servers (ms17-010)-- | State: VULNERABLE-- | IDs: CVE:CVE-2017-0143-- | Risk factor: HIGH-- | A critical remote code execution vulnerability exists in Microsoft SMBv1-- | servers (ms17-010).-- |-- | Disclosure date: 2017-03-14-- | References:-- | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0143-- | https://technet.microsoft.com/en-us/library/security/ms17-010.aspx-- |_ https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/---- @xmloutput-- <table key="CVE-2017-0143">-- <elem key="title">Remote Code Execution vulnerability in Microsoft SMBv1 servers (ms17-010)</elem>-- <elem key="state">VULNERABLE</elem>-- <table key="ids">-- <elem>CVE:CVE-2017-0143</elem>-- </table>-- <table key="description">-- <elem>A critical remote code execution vulnerability exists in Microsoft SMBv1
 servers (ms17-010).
</elem>-- </table>-- <table key="dates">-- <table key="disclosure">-- <elem key="month">03</elem>-- <elem key="year">2017</elem>-- <elem key="day">14</elem>-- </table>-- </table>-- <elem key="disclosure">2017-03-14</elem>-- <table key="refs">-- <elem>https://technet.microsoft.com/en-us/library/security/ms17-010.aspx</elem>-- <elem>https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0143</elem>-- <elem>https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/</elem>-- </table>-- </table>---- @args smb-vuln-ms17-010.sharename Share name to connect. Default: IPC$----- 作者是谁author = "Paulino Calderon <paulino()calderonpale.com>"-- 这个脚本遵循的许可license = "Same as Nmap--See https://nmap.org/book/man-legal.html"-- 这个脚本属于哪些类categories = {"vuln", "safe"}----------------------------------------------------------- 规则 ---------------------------------------------------------------------------------------------------------------------- 规则 ---------------------------------------------------------------------------------------------------------------------- 规则 -----------------------------------------------------------[[ Rule:决定在什么情况下运行后续的Action,满足设置的条件才运行后续的Action 有Prerule、Postrule、Portrule、Hostrule 比如 Portrule 通常用于检测服务匹配的特征字符串]]hostrule = function(host) return smb.get_port(host) ~= nilendlocal function check_ms17010(host, port, sharename) local status, smbstate = smb.start_ex(host, true, true, "\\\\".. host.ip .. "\\" .. sharename, nil, nil, nil) if not status then stdnse.debug1("Could not connect to '%s'", sharename) return false, string.format("Could not connect to '%s'", sharename) else local overrides = {} local smb_header, smb_params, smb_cmd stdnse.debug1("Connected to share '%s'", sharename) overrides['parameters_length'] = 0x10 --SMB_COM_TRANSACTION opcode is 0x25 smb_header = smb.smb_encode_header(smbstate, 0x25, overrides) smb_params = string.pack(">I2 I2 I2 I2 B B I2 I4 I2 I2 I2 I2 I2 B B I2 I2 I2 I2 I2 I2", 0x0, -- Total Parameter count (2 bytes) 0x0, -- Total Data count (2 bytes) 0xFFFF, -- Max Parameter count (2 bytes) 0xFFFF, -- Max Data count (2 bytes) 0x0, -- Max setup Count (1 byte) 0x0, -- Reserved (1 byte) 0x0, -- Flags (2 bytes) 0x0, -- Timeout (4 bytes) 0x0, -- Reserved (2 bytes) 0x0, -- ParameterCount (2 bytes) 0x4a00, -- ParameterOffset (2 bytes) 0x0, -- DataCount (2 bytes) 0x4a00, -- DataOffset (2 bytes) 0x02, -- SetupCount (1 byte) 0x0, -- Reserved (1 byte) 0x2300, -- PeekNamedPipe opcode 0x0, -- 0x0700, -- BCC (Length of "\PIPE\") 0x5c50, -- \P 0x4950, -- IP 0x455c -- E\ ) stdnse.debug2("SMB: Sending SMB_COM_TRANSACTION") local result, err = smb.smb_send(smbstate, smb_header, smb_params, '', overrides) if(result == false) then stdnse.debug1("There was an error in the SMB_COM_TRANSACTION request") return false, err end local result, smb_header, _, _ = smb.smb_read(smbstate) if not result then stdnse.debug1("Error reading SMB response: %s", smb_header) -- error can happen if an (H)IPS resets the connection return false, smb_header end local _ , smb_cmd, err = string.unpack("<c4 B I4", smb_header) if smb_cmd == 37 then -- SMB command for Trans is 0x25 stdnse.debug1("Valid SMB_COM_TRANSACTION response received") --STATUS_INSUFF_SERVER_RESOURCES indicate that the machine is not patched if err == 0xc0000205 then stdnse.debug1("STATUS_INSUFF_SERVER_RESOURCES response received") return true elseif err == 0xc0000022 then stdnse.debug1("STATUS_ACCESS_DENIED response received. This system is likely patched.") return false, "This system is patched." elseif err == 0xc0000008 then stdnse.debug1("STATUS_INVALID_HANDLE response received. This system is likely patched.") return false, "This system is patched." end stdnse.debug1("Error code received:%s", stdnse.tohex(err)) else stdnse.debug1("Received invalid command id.") return false, string.format("Unexpected SMB response:%s", stdnse.tohex(err)) end endend----------------------------------------------------------- Action ---------------------------------------------------------------------------------------------------------------------- Action ---------------------------------------------------------------------------------------------------------------------- Action -----------------------------------------------------------action = function(host,port) local vuln_status, err local vuln = { title = "Remote Code Execution vulnerability in Microsoft SMBv1 servers (ms17-010)", IDS = {CVE = 'CVE-2017-0143'}, risk_factor = "HIGH", description = [[A critical remote code execution vulnerability exists in Microsoft SMBv1 servers (ms17-010). ]], references = { 'https://technet.microsoft.com/en-us/library/security/ms17-010.aspx', 'https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/' }, dates = { disclosure = {year = '2017', month = '03', day = '14'}, } } local sharename = stdnse.get_script_args(SCRIPT_NAME .. ".sharename") or "IPC$" local report = vulns.Report:new(SCRIPT_NAME, host, port) vuln.state = vulns.STATE.NOT_VULN vuln_status, err = check_ms17010(host, port, sharename) if vuln_status then stdnse.debug1("This host is missing the patch for ms17-010!") vuln.state = vulns.STATE.VULN else vuln.state = vulns.STATE.NOT_VULN vuln.check_results = err end return report:make_output(vuln)end编写自己的脚本,内容如下
----------------------------------------------------------- Header ---------------------------------------------------------------------------------------------------------------------- Header ---------------------------------------------------------------------------------------------------------------------- Header -----------------------------------------------------------local http = require "http"local nmap = require "nmap"description = [[ 检查网站根目录下是否有 "robots.txt" 这个文件]]author = "w00l00"license = "Same as Nmap--See https://nmap.org/book/man-legal.html"categories = {"default", "discovery", "safe"}----------------------------------------------------------- Rules ---------------------------------------------------------------------------------------------------------------------- Rules ---------------------------------------------------------------------------------------------------------------------- Rules ------------------------------------------------------------- 规则是 判断端口是否开放,开放则返回Trueportrule = function(host, port) return port.state == "open"end----------------------------------------------------------- Action ---------------------------------------------------------------------------------------------------------------------- Action ---------------------------------------------------------------------------------------------------------------------- Action ------------------------------------------------------------- 如果规则函数返回的是True,做下面的Actionaction = function(host, port) -- 请求目标主机目标端口下的 robots.txt 文件 local robots = http.get(host, port, "/robots.txt") -- 如果返回的http状态码是200则表明文件存在 if robots.status == 200 then return "robots.txt status 200" else return "robots.txt status: " .. robots.status endend执行自己编写的脚本

| 例子 | 含义 |
|---|---|
sudo nmap 10.0.2.25 -A | -A综合参数,相当于-O、-sV、-sC、traceroute 参数结合体 |