W00L00

0x00 简介

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

本文使用的nmap版本是7.92

image-20220325162247098

0x01 历史进程

  • 诞生于1997年
    • 最早的版本只有2000行代码,没有版本号
    • 只作为端口扫描工具
    • 6个月后成为黑客社区中网路扫描的事实标准
  • 2003年发布3.45版本
    • Fyodor开始全职维护nmap
    • 增加了服务检测、OS检测、时间控制等功能
    • 进入成熟期
  • 2006年集成NSE
    • 从单一的网络扫描工具,转变为可扩展的全功能漏洞评估引擎

0x02 默认扫描参数

  • 默认TCP syn扫描,利用TCP的三次握手机制,当发送syn包后,如果目标主机的那个端口是开着的,就会返回syn+ack数据包,同时nmap接收到之后不再返回ack的确认包,不会建立完成的TCP连接,节约扫描发起者机器的资源
  • 默认扫描1000个常用端口,包括httphttpsftpsmtpssh等等

0x03 指定扫描IP

0x03-1 指定多个扫描IP

例子 含义
sudo nmap 10.0.2.1,2,25 扫描10.0.2.110.0.2.210.0.2.25这3个IP
sudo nmap 10.0.1,2.23,25 扫描10.0.1.2310.0.1.2510.0.2.2310.0.2.25这4个IP
sudo nmap 10.0,1.2,3.23,25 扫描10.0.2.2310.0.2.2510.0.3.2310.0.3.2510.1.2.2310.1.2.2510.1.3.2310.1.3.25这8个IP

image-20220325004733347

例子 含义
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

image-20220325005544670

例子 含义
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

image-20220325005758883

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

image-20220325010055774

0x03-2 指定扫描域名

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

image-20220324233643718

0x03-3 排除要扫描的IP

例子 含义
sudo nmap 10.0.2.25/24 --exclude 10.0.2.2,3,4 扫描10.0.2.1/24这个网段中除10.0.2.210.0.2.310.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

image-20220325010237185

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

image-20220325010426850

0x04 反向域名查询

0x04-1 -R 一定要做DNS反向域名查询

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

image-20220325175418772

image-20220325175533234

0x04-2 -n 不做DNS反向域名查询

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

image-20220325175746724

image-20220325175858216

0x04-3 --dns-servers 指定 DNS 服务器做反向域名查询

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

image-20220325180430896

image-20220325180523385

0x05 -e <iface> 指定发包网卡

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

image-20220325004329043

如果没有指定发包网卡,nmap就会使用本机序号为第一个的网卡发扫描包

0x06 主机发现

做扫描的时候,先做主机发现,别一上来就对所有的IP发送大量数据包进行端口扫描,不要做这种莽撞的行为,因为在扫描的时候经常会触发安全机制的报警,所以做扫描的时候要越隐蔽越好,先做主机发现再做端口扫描,不仅节省自己的时间,还能避免被发现,何乐而不为呢?

0x06-1 -sn 使用ICMP,TCP ping扫描,只做主机发现

向目标系统的80443端口发送ICMPTCP ping扫描,如果目标系统返回了ICMP响应包、SYN+ACK包、RST+ACK包,就认为这个IP是活着的

并且判断完IP是否是活着的之后,就会结束,不会再发送端口扫描数据包

例子 含义
sudo nmap -sn 192.168.123.2 扫描192.168.123.2是否是活着的

image-20220326231805062

image-20220325160918236

0x06-2 -Pn 跳过主机发现环节

跳过主机发现环节,直接将IP视为在线状态,直接发送大量的端口扫描数据包;不加此参数的情况是:若发现此IP不在线,则不进行端口扫描

因为会发出大量的扫描数据包,一点也不隐蔽,所以用此参数来进行主机发现是不可取的

例子 含义
sudo nmap -Pn 192.168.123.2 扫描192.168.123.2,不管此IP是否是活着的状态

image-20220325161634733

0x06-3 --traceroute 显示经过的路由

例子 含义
sudo nmap www.baidu.com --traceroute -sn 在扫描结果种显示每一跳经过的路由IP,而且只做主机发现这一步

0x06-4 -PS 发送 TCP SYN 包

加入这个参数之后只会发送TCP SYN数据包包

例子 含义
sudo nmap 192.168.123.1 -PS -sn 只发送TCP SYN 包进行主机发现

image-20220325163818274

image-20220325164116669

0x06-5 -PA 发送 TCP SYN 包

加入这个参数之后只会发送TCP ACK数据包

例子 含义
sudo nmap 192.168.123.1 -PA -sn -n 只发送TCP ACK 包进行主机发现,并且跳过DNS反向域名解析环节

image-20220325164456252

image-20220325164346257

0x06-6 -PU 发送 UDP 包

加入这个参数之后只会发送UDP 数据包

例子 含义
sudo nmap 192.168.123.1 -PU -sn -n 只发送UDP 包进行主机发现,并且跳过DNS反向域名解析环节

image-20220325165255590

image-20220325165216711

0x06-7 -PY 发送 SCTP 包

加入这个参数之后只会发送SCTP 数据包

例子 含义
sudo nmap 192.168.123.1 -PY -sn -n 只发送SCTP 包进行主机发现,并且跳过DNS反向域名解析环节

image-20220325170549306

image-20220325170706245

0x06-8 -PE 发送 ICMP 包

加入这个参数之后只会发送ICMP 数据包,跟使用ping命令是完全一回事

例子 含义
sudo nmap 192.168.123.1 -PE -sn -n 只发送ICMP 包进行主机发现,并且跳过DNS反向域名解析环节

image-20220325172513655

image-20220325171616497

0x06-9 -PP 请求目标系统时间戳

请求目标系统时间戳,如果返回的话则说明这个IP是活着的

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

image-20220325172358857

image-20220325172318373

抓包结果显示发送了两次 ICMP 数据包请求目标系统时间戳都没有得到回复,但其实这个IP是活着的

注意:每个参数的使用场景不一样,没有哪个参数可以全场景覆盖,要针对当前扫描的环境使用相对应的扫描参数

0x06-10 -PM 请求目标系统子网掩码

请求目标子网掩码,如果返回的话则说明这个IP是活着的

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

image-20220325173245931

image-20220325173340517

抓包结果显示发送了两次 ICMP 数据包请求目标系统子网掩码都没有得到回复,但其实这个IP是活着的

注意:每个参数的使用场景不一样,没有哪个参数可以全场景覆盖,要针对当前扫描的环境使用相对应的扫描参数

0x06-11 -PO[protocol list] 指定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反向域名解析环节

image-20220325174506504

image-20220325174726816

0x07 端口扫描

0x07-1 --top-ports <number> 扫描最常用的端口

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

image-20220325003844196

0x07-2 指定扫描端口

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

image-20220325011539720

0x07-3 -sS 发 TCP SYN 包扫描

例子 含义
sudo nmap 192.168.123.1 -sS TCPSYN数据包进行扫描

image-20220325214137025

image-20220325213922402

0x07-4 -sA 发 TCP ACK 包扫描

例子 含义
sudo nmap 192.168.123.1 -sA TCPACK数据包进行扫描

image-20220325215110697

image-20220325215223870

0x07-5 -sT 三次握手建立完整的 TCP 连接

有些特殊的应用可能会拒绝SYN扫描,拒绝半开的连接,所以这时候必须要通过三次握手建立完成的TCP连接才能发现端口是否是开放的

例子 含义
sudo nmap 192.168.123.1 -sT 通过三次握手建立完整的TCP连接,来判断端口是否开放

image-20220325214414172

image-20220325214607733

0x07-6 -sN 发送的 TCP 包 flag 位为空

目标主机收到包之后丢弃掉,即不做响应代表这个端口是开放的,如果返回RST数据包则表示这个端口是开放的;当然这和目标主机的安全配置有关,只是一般情况下是这样的

所以使用此参数进行端口扫描时要先确保目标IP是活着的

例子 含义
sudo nmap 192.168.123.1 -sN 发送的TCPflag位全设置为0,进行端口扫描

image-20220325221857670

image-20220325222314871

0x07-7 -sF 发送的 TCP 包 flag 位的 Fin 设置为1

目标主机收到包之后丢弃掉,即不做响应代表这个端口是开放的,如果返回RST数据包则表示这个端口是开放的;当然这和目标主机的安全配置有关,只是一般情况下是这样的

所以使用此参数进行端口扫描时要先确保目标IP是活着的

例子 含义
sudo nmap 192.168.123.1 -sF 发送的TCP数据包flagFin设置为1

image-20220325222400871

image-20220325222841696

0x07-8 -sX 发送的 TCP 包 flag 位的 Urgent、Push、Fin 设置为1

目标主机收到包之后丢弃掉,即不做响应代表这个端口是开放的,如果返回RST数据包则表示这个端口是开放的;当然这和目标主机的安全配置有关,只是一般情况下是这样的

所以使用此参数进行端口扫描时要先确保目标IP是活着的

例子 含义
sudo nmap 192.168.123.1 -sX 发送的TCP数据包flagUrgentPushFin设置为1

image-20220325222941303

image-20220325223212540

0x07-9 --scanflags <flags> 自定义 TCP Flags设置

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

image-20220325224957370

image-20220325225147970

0x07-10 重头戏:-sI <zombie host[:probeport]> 僵尸扫描

参数:-sI <zombie host[:probeport]> 僵尸扫描

是非常非常隐蔽的扫描方式

原理

  1. 首先需要在被扫描的网络中找一台符合下面两个要求的计算机

    • 非常非常空闲的计算机,空闲到没有和别的任何计算机进行通信(在一个大型的网络中这种空闲的机器还是比较好找的)

    • 这台计算机的IPID必须是递增的,且增长方式是有规律的,比方说每次递增1IPID即是IP头部的ID字段)

    很多的计算机的IPID都是递增的,比方说一天中的第一个数据包的IPID是随即的,下一个数据包的IPID则会在前一个的IPID上加1或加2或者加一些有规律的数值

  2. nmap先探测僵尸机当前的IPID是多少,并记录下来

  3. 然后nmap将自己的IP地址伪装成僵尸机的IP地址,向要目标主机的端口发送SYN

  4. 目标主机端口接收到SYN包之后

    1. 如果目标端口是开放的则会向僵尸机发送SYN+ACK,但是僵尸机从头到尾都没有发送过SYN包,凭空接收到了目标主机的向它发送SYN+ACK,僵尸机就会返回RST数据包,此时僵尸机的IPID递增1

      image-20220325234241313

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

      image-20220326003549102

  5. 这时候nmap再次向僵尸机发送数据包,探测僵尸机当前的IPID,如果数值为之前探测的基础上+2,则表明目标主机的目标端口是开放的;如果数值为之前探测的基础上+1,则表明目标主机的目标端口是关闭的

  6. 在整个过程中扫描者是完全隐蔽的,安全性很高。但是反向做路由追踪还是有可能发现的,不过难度特别大。

例子

  • 僵尸机IP10.0.2.11
  • 目标IP10.0.2.25

实施僵尸扫描

执行命令:sudo nmap 10.0.2.25 -sI 10.0.2.11 -Pn

image-20220326014920327

注:利用此命令可以单独探测僵尸机的IPID变化规律

执行命令:sudo nmap 10.0.2.11 -p445 --script=ipidseq.nse 使用nmap专门用来扫描IPID变化的脚本ipidseq.nse

0x07-11 -sU 发 UDP 数据包扫 UDP 端口

因为UDP是不建立连接的,没有办法像TCP那样在建立连接的过程中就可以判断出端口是否开放,所以扫UDP端口挺不靠谱的

UDP端口一般需要建立基于UDP以上的应用层连接,发送应用层报文才可以判断UDP端口是否开放

例子 含义
sudo nmap 192.168.123.1 -sU 发送UDP数据包,扫描UDP 端口

image-20220325221720774

image-20220325220157336

0x07-12 默认配置下端口扫描在做什么

如果目标主机和kali不在同一网段中

执行命令:sudo nmap 192.168.123.1,2 -p80,5000

一图胜千言

image-20220325153132549

如果目标主机和kali在同一网段中

执行命令:sudo nmap 10.0.2.2,25 -p22,5000

一图胜千言

image-20220325015657489

0x08 -sV 扫描服务版本

结合多种方式,包括banner,指纹等技术,判断目标端口上运行的到底是什么服务,准确率很高的

例子 含义
sudo nmap 10.0.2.25 -p22,5000 -sV 探测225000端口运行的是什么服务

image-20220326162508601

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

image-20220326162715813

0x09 -O 扫描系统版本

很多情况下没有办法100%判断出系统的具体版本,就会给出所有可能的结果

例子 含义
sudo nmap 10.0.2.25 -O 探测系统版本

image-20220326162252716

0x0a 扫描速度控制

0x0a-1 -T<0-5> 设置扫描速度等级

0最慢,5最快,不过最快速度可能会更容易被发现

例子 含义
sudo nmap 10.0.2.25 -T3 限定扫描速度为等级3

image-20220326163057579

0x0a-2 --scan-delay <time> 设置探测间隔时间

例子 含义
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小时

0x0a-3 --min-rate 最小扫描速度

例子 含义
sudo nmap 10.0.2.25 --min-rate 最小扫描速度

0x0a-3 --min-rate 最大扫描速度

例子 含义
sudo nmap 10.0.2.25 --max-rate 最大扫描速度

0x0a-4 解决扫描被卡住的问题(大范围地址空间)

nmap扫描大范围地址块时经常会被卡死在中间的一个IP中。

绝大多数是由于目标系统的安全机制造成的,目标系统发现你在扫描时就估计将你的扫描请求挂在那不响应,让扫描进行不下去

例子 含义
sudo nmap 10.0.2.0/24 --host-timeout 10m 设置扫描超时时间为10分钟,超过了设置的时间就会扫描下一个

0x0b 躲避安全检测

0x0b-1 -f 将 IP 数据段分片(8字节一片)

IP数据段分片发送,使目标的安全机制IPS等设备无法还原数据包的原始内容,从而使安全检测机制失效

比方说

标准的TCP包头是20个字节,加入了-f参数后会将这个20字节分3个包发出去,第一个包8字节,第二个包8字节,第三个包4字节再加上4字节TCP数据段的内容(如果有数据段的话也是每次发8字节)

例子 含义
sudo nmap 10.0.2.25 -f 将 IP 数据段分片(8字节一片)

0x0b-2 -D <decoy1,decoy2[,ME],...> 伪造多个源IP,真实IP隐藏在其中

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进行扫描

0x0b-3 -S <IP_Address> 伪造源IP

将源IP进行伪造,使用此参数的话还需要别的方法判断伪造的源IP是否接收到了回包

此参数需要搭配-e <iface>指定网卡,-Pn跳过主机发现这两个参数

例子 含义
sudo nmap 10.0.2.25 -S 10.0.2.11 -e eth0 -Pn 伪造源IP10.0.2.11进行探测,并且指定了发包网卡为eth0,跳过主机发现环节

0x0b-4 -g <portnum> 指定发包端口

例子 含义
sudo nmap 10.0.2.25 -g 3333 指定扫描数据包发送的端口为3333

0x0b-5 --proxies <url1,[url2],...> 挂上HTTP或SOCKS4代理进行扫描

例子 含义
sudo nmap 10.0.2.25 --proxies http://10.0.2.11:8080 使用HTTP代理进行发包扫描

0x0b-6 --data <hex string> 在扫描包中数据段附加自定义的16进制数据

例子 含义
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

image-20220326173941948

image-20220326173911912

0x0b-7 --data-string <string> 在扫描数据包数据段中附加自定义的ASCII字符

例子 含义
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

image-20220326174433376

image-20220326174552510

0x0b-8 --ip-options <options> 指定IP OPTION数据(暂时不知道咋用)

0x0b-9 --ttl <val> 指定发送扫描包的TTL值

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

image-20220326180342686

image-20220326180303129

0x0b-10 --spoof-mac <mac address/prefix/vendor name> 伪造扫描数据包中的MAC地址

可能会造成收不到回包的情况

例子 含义
sudo nmap 192.168.123.1 --spoof-mac AA:BB:CC:DD:EE:FF 伪造数据包中的MAC地址AA:BB:CC:DD:EE:FF

image-20220326181220475

image-20220326181041082

0x0b-11 --badsum 使用错误的checksum

IP包头中的checksum校验值故意写错,看看目标的安全检测机制会不会放弃这样的包,从而绕过安全机制

例子 含义
sudo nmap 192.168.123.1 --badsum 故意使用错误的checksu

0x0c 输出格式

0x0c-1 -oA <basename> 将扫描结果保存为三种根式日志

三种主要的根式日志,分别是xmlnmapgnmap

例子 含义
sudo nmap 192.168.123.1 -oA a 将扫描结果保存为三种主要的根式日志,文件名为a

image-20220326181822411

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

image-20220326182027203

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

image-20220326182201250

比方说扫描了大量的IP后,现在想要提取所有开放80端口的IP地址

可以这样执行命令:cat a.gnmap | grep 80

image-20220326182434935

a.xml格式就是xml格式喽

0x0c-2 -oX <file> 将扫描结果保存为XML格式文件

三种主要的根式日志,分别是xmlnmapgnmap

例子 含义
sudo nmap 192.168.123.1 -oX a 将扫描结果保存为XML格式文件,文件名为a.xml

0x0c-3 显示详细信息

例子 含义
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

0x0c-4 -d 显示debug信息

例子 含义
sudo nmap 192.168.123.1 -d 显示debug信息

0x0c-5 --reason 显示判断端口状态的依据

例子 含义
sudo nmap 10.0.2.25 --reason 在结果中显示判断端口状态的依据

image-20220325004139695

0x07-6 --open 扫描结果中只显示开放的端口

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

image-20220325003945068

0x07-7 --packet-trace 显示 nmap 都发了或收了什么包

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

image-20220326183241345

0x07-8 --script-trace 只显示脚本都发了和都收了什么包

例子 含义
sudo nmap 10.0.2.25 --script-trace 只显示脚本都发了和都收了什么包

0x07-9 --iflist 显示系统中都有哪些网卡

例子 含义
sudo nmap --iflist 显示系统中都有哪些网卡

image-20220326183713489

0x0d -6 开启 IPV6 扫描

例子 含义
sudo nmap fe80::a00:27ff:fe6a:30e3 -6 开启IPV6扫描

0x0e NSE 脚本引擎(Nmap Scripting Engine)

0x0e-1 简介

  • 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 漏洞类

    一般在企业中建议使用DefaultSafe类型的脚本进行扫描,尽量避免使用IntrusiveDosExploit类型的脚本,尽量对自己家的服务器温柔一点

0x0e-2 脚本使用

例子 含义
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 使用所有的DosExploitVuln类脚本
sudo nmap 10.0.2.25 --script="not(dos or exploit or vuln)" 使用除DosExploitVuln类外的所有脚本
sudo nmap 10.0.2.25 --script="whois-ip,banner,upnp-info" 使用whois-ip.nsebanner.nseupnp-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.nsehttp-brute.nsehttp-enum.nsehttp-form-fuzzer.nse外所有以http-开头的脚本
sudo nmap 10.0.2.25 --script=+vuln -p4343 使用所有的Vuln类脚本扫描4343端口;当服务不工作在非标准端口时,部分脚本就不工作了,使用+来强制Vuln类所有脚本都要对4343端口进行扫描

image-20220326193441371

0x0e-3 脚本参数

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

image-20220326205943657

image-20220326210129956

例子 含义
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.nsehttp-axis2-dir-traversal.nse两个脚本中的uri参数值

0x0e-4 使用实例

例子 含义
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漏洞

image-20220326212312350

0x0e-5 写自己的脚本

使用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&#xa; servers (ms17-010).&#xa;</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) ~= nil
end

local 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
  end
end

----------------------------------------------------------- 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 -----------------------------------------------------------

-- 规则是 判断端口是否开放,开放则返回True
portrule = function(host, port)
    return port.state == "open"
end

----------------------------------------------------------- Action -----------------------------------------------------------
----------------------------------------------------------- Action -----------------------------------------------------------
----------------------------------------------------------- Action -----------------------------------------------------------

-- 如果规则函数返回的是True,做下面的Action
action = 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
    end
end

执行自己编写的脚本

image-20220326221752300

0x0f -A 综合参数,相当于 -O、-sV、-sC、traceroute 参数结合体

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

相关文章: