基于原理分析Nmap——活跃主机发现、端口扫描、服务探测、伪装技术、NSE脚本

参考书籍《诸神之眼——Nmap网络安全审计技术揭秘》 李华峰 著 清华大学出版社

1. 活跃主机发现技术

1.1 基于ARP协议

原理:

如果想要知道处在同一网段的IP地址为*.*.*.*的主机是否为只需要构造一个ARP请求数据包,并广播出去,如果得到回应,则说明该主机为活跃主机。

条件:

当目标主机与我们处于同一个网段的时候,使用ARP协议扫描技术就是最佳的选择,不仅速度最快,扫描结果也是最为精准的。

命令:

nmap -PR [目标]
nmap -sn -PR [目标]

1.2 基于ICMP协议

原理:

ICMP的报文可以分为两类:差错和查询。查询报文是用一对请求和应答定义的。也就是说,主机A为了获得一些信息,可以向主机B发送ICMP数据包,主机B在收到这个数据包之后,会给出应答。ICMP中适合使用的查询报文包括响应请求和应答、时间戳请求和应答以及地址掩码请求和应答

使用ICMP协议进行主机发现:

1.2.1 通过ICMP响应请求和应答进行主机发现

原理:

发送ICMP响应请求,如果得到目标主机发回的ICMP响应,则说明该主机处于活跃状态。请求包的Type字段为8,响应包的Type字段为0。

命令:

nmap -PE [目标]   #实际上效果等同于ping命令
nmap -sn -PE [目标]
1.2.2 通过ICMP时间戳请求和应答进行主机发现

原理:

ping命令在很多防火墙上都被隔绝了,因此需要使用其他的方法。nmap的选项-PP可以实现ICMP协议的时间戳主机发现。请求包的Type字段为13,响应包的Type字段为14。

命令:

nmap -sn -PP [目标]
1.2.3 通过ICMP地址掩码请求和应答进行主机发现

原理:

使用nmap的选择-PM可以实现ICMP协议的地址掩码主机发现。请求包的Type字段为17,响应包的Type字段为18。

命令:

nmap -PM [目标]
nmap -sn -PM

1.3 基于TCP协议

1.3.1 TCP SYN扫描

原理:

nmap使用-PS选项来向目标主机发送一个设置了SYN标志的数据包,这个数据包的内容部分为空。

目标主机在收到这个SYN数据包之后,会认为nmap所在主机想要和自己的一个端口建立连接,如果这个端口是开放的,目标主机就会按照TCP三次握手的规定,发回一个SYN/ACK数据包,表示同意建立连接。

如果这个端口是关闭的,目标主机就会拒绝这次连接,向nmap所在的主机发送一个RST数据包。

命令:

nmap -sn -PS [端口1,端口2…] [目标]
1.3.2 TCP ACK扫描

原理:

nmap发送的数据包中使用TCP/ACK标志位,按照TCP三次握手的规则,目标主机显然无法清除这是怎么回事,当然也不可能成功建立TCP连接,因此只能向nmap所在主机发送一个RST标志位的数据包,表示无法建立这个TCP连接。

命令:

nmap -sn -PA [目标]

1.4 基于UDP协议

原理:

当一个UDP端口收到一个UDP数据包时,如果它是关闭的,就会给源端发回一个ICMP端口不可达数据包;如果它是开放的,就会忽略这个数据包,也就是将它丢弃而不返回任何信息。

因为当发出一个UDP数据包而没有收到任何的应答时,有可能因为这个UDP端口是开放的,也有可能是因为这个数据包在传输过程中丢失了,因此UDP端口扫描的可靠性不高。

命令:

nmap -PU [目标]

1.5 基于SCTP协议

原理:

在SCTP中,客户端使用一个INIT报文发起一个连接,服务器端使用一个INIT-ACK报文进行应答,其中就包括了cookie。然后客户端使用一个COOKIE-ECHO报文进行响应,其中包含了服务器端所发发送的cookie。服务器端要为这个连接分配资源,并通过向客户端发送一个COOKIE-ACK报文对其进行响应。

这个协议的存活扫描是不准确的,因为目前支持这个协议的主机并不多,因此这种方法只能作为一种备用手段。

命令:

nmap -sn -PY [目标]

2. 端口扫描技术

2.1 端口状态

nmap中对于端口给出了6种不同的状态:

  • open——在该端口有应用程序接收TCP连接或者UDP报文。
  • closed——closed并不意味着没有任何反应,状态为closed的端口是可访问的,这种端口可以接收nmap探测报文并做出响应。只是没有应用程序在open上监听。
  • filtered——存在目标网络数据包过滤,导致nmap无法确定该端口是否开放。
  • unfiltered——表明目标端口是可以访问的,但是nmap却无法判断它到底是open还是closed的。
  • open|filtered——无法确定端口是开放的还是被过滤了。
  • closed|filtered——无法确定端口是关闭的还是被过滤了。

2.2 扫描端口技术

2.2.1 SYN扫描

原理:

nmap会向目标主机的一个端口发送请求连接的SYN数据包,而目标计算机在接收到这个SYN数据包之后会以SYN/ACK进行应答,nmap在收到SYN/ACK后会发送RST包请求断开连接而不是ACK应答。这样,三次握手就没有完成,无法建立正常的TCP连接,因此这次扫描不会被记录到系统日志中。

SYN扫描是nmap所采用的默认扫描方式,扫描速度极快,可以在一秒钟扫描上千个端口,也不容易被网络中的安全设备发现。

命令:

nmap -sS [目标]
2.2.2 TCP Connect扫描

原理:

这种扫描方式其实和SYN扫描很像,只是这种扫描方式完成了TCP三次握手。这种扫描方式无须root或者administrator权限。

命令:

nmap -sT [目标]
2.2.3 UDP扫描

原理:

使用UDP进行扫描。

注意UDP扫描的速度是相当慢的。

扫描端口状态:

目标主机的应答目标主机的状态
从目标端口得到任意的UDP应答open
如果目标主机没有给出应答open|filtered
ICMP端口无法抵达错误closed
ICMP无法抵达错误filtered

命令:

nmap -sU [目标]
2.2.4 TCP FIN扫描

原理:

TCP FIN扫描方法向目标端口发送一个FIN数据包,对于所有关闭的端口,目标系统应该返回RST标志。

命令:

nmap -sF [目标]
2.2.5 NULL扫描

原理:

向目标端口发送一个不包含任何标志的数据包,对于所有关闭的端口,目标系统应该返回RST标志。

命令:

nmap -sN [目标]
2.2.6 Xmas Tree扫描

原理:

向目标端口发送一个含有FIN、URG和PUSH标志的数据包,对于所有关闭的端口,目标系统应该返回RST标志。

命令:

nmap -sX [目标]
2…2.7 idle扫描

原理:

idle扫描无需向目标主机发送任何数据包,它借助一个“第三方主机”来向目标端口发送数据包。

优点在于可以绕过waf,缺点在于扫描用时较长。

命令:

nmap -sI [目标]

2.3 指定扫描的端口

1、扫描常见的100个端口

nmap -F [目标]

2、指定某一个端口

nmap -p [端口号] [目标IP地址]

3、使用名字来指定扫描端口

nmap -p [协议名称] [目标IP地址]nmap -p smtp,http 192.168.1.1

4、使用协议指定扫描端口

nmap -p U:[UDP ports],T:[TCP ports] [目标]nmap -p U:53,T:25 192.168.1.1

5、扫描所有端口

nmap -p "*" [目标]

6、扫描常用端口

nmap --top-ports [number] [目标]

3. 远程操作系统与服务检测技术

3.1 操作系统指纹扫描

远程判断目标计算机操作系统的方法一般可以分成两类:

  • 被动式方法:并不向目标系统发送任何数据包,而是通过各种抓包工具来收集流经网络的数据报文,再从这些报文中得到目标计算机的操作系统信息。
  • 主动式方法:指客户端主动向远程主机发送信息,远程主机一般要对这些信息做出反应,回复一些信息,发送者对这些返回的信息进行分析,就有可能得知远程主机的操作系统类型。这些信息可以是通过正常的网络程序如Telnet、FTP等与主机交互的信息,也可以是一些经过精心构造、正常的或残缺的数据报文。

在nmap中可以使用-O选项来完成对目标操作系统的扫描。

nmap -F -O [目标]  #F表示fast,O表示OS系统

猜测认为最接近目标匹配操作系统类型。

nmap -O -F --fuzzy --osscan-guess [目标]

3.2 如何使用nmap进行服务发现

问题:使用nmap [目标]nmap -sV [目标]两次扫描出现的端口对应的服务版本为何不一样?

回答:前者使用了nmap-services数据库中常用的端口-服务,可能并不是真实的服务;而使用-sV之后,才是真正的对目标服务进行了扫描。

进行服务发现的顺序

1.首先进行端口扫描:默认情况下使用SYN扫描。

2.其次进行服务识别:发送探针报文,得到返回确认值,确认服务。

3.最后进行版本识别:发送探针报文,得到返回的报文信息,分析得出服务的版本。

可以使用以下选项打开和控制版本检测:

  • -sV——进行版本探测
  • --allports——不为版本探测排除任何端口。nmap在进行版本探测时不会对目标的全部端口进行扫描,而是会跳过一些端口,如果确实有必要的话,可以使用这个参数来扫描所有的端口。
  • --version-intensity [数字]——设置版本扫描强度,数值越高,服务越有可能被正确设别。然而,高强度扫描花更多的时间。强度值必须在0~9之间,默认值为7。
  • --version-light——打开轻量级模式,相当于--version-intensity 2
  • --version-all——尝试每个探测,相当于--version-intensity 9
  • --version-trace——跟踪版本扫描活动,打印出关于正在进行的扫描的详细调试信息。
  • -sR——RPC扫描,判断端口是否为RPC端口,是则可以确定版本号。

4. 伪装技术

4.1 包分段

1.namp -f [目标]

使用-f选项可以对nmap发送的探测数据包进行分段。这样将原来的数据包分成几个部分,目标网络的防御机制例如包过滤、防火墙等在对这些数据包进行检测的时候就会变得更加困难。另外必须谨慎使用这个选项,一些老旧的系统在处理分段的包时经常会出现死机的情况。

2.nmap -mtu [目标]

最大传输单元(Maximum Transmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。一般来说,以太网的MTU值默认为1500bytes,当数据报文的大小大于1500bytes时,就被分片。这里MTU的值必须是8的整数倍。

4.2 诱饵主机

nmap -D decoy1,[decoy2,decoy3…] [目标]

同时伪造大量的主机地址对目标进行扫描。由于扫描数据包来自多个主机,即使是IDS也只能知道目前正在收到扫描,并不知道到底是哪台主机在进行扫描。使用选项-D来指定诱饵主机,使用逗号来分隔每个诱饵IP地址,也可用ME来代表自己真实的IP地址。

使用范围:

在初始的ping扫描阶段或真正的端口扫描,以及远程操作系统检测阶段都可以使用诱饵主机选项。

4.3 源端口欺骗

nmap -g [端口号] [目标] / nmap --source-port [端口号] [目标]

-g--source-port两个选项相同,只需要有一个被目标检测机制遗忘的端口号,nmap就可以从这个端口发送数据。

4.4 发送报文时附加随机数据

nmap --data-length [number] [目标]

默认情况下,nmap发送的报文中只包含头部,内容部分是空的,因此TCP数据包的大小只有40字节,而ICMP ECHO请求只有28字节。这种内容为空的报文很容易被目标网络检测机制所发现,因此在试图通过这些目标网络的检测机制时,可以在数据包上附加指定数量的随机字节。这个选项会使大部分ping和端口扫描变慢,但是影响不大。

4.5 设置IP time-to-live域

nmap --ttl [value] [目标]

nmap中可以设置IPv4数据包的time-to-live域为指定的值,指定的参数为--ttl,例如它的值可以为25。

4.6 MAC地址欺骗

nmap --spoof-mac [mac address,prefix, or vendor name] [目标]

通过这个选项可以人为指定nmap在进行扫描工作时发送以太网帧的MAC地址。这个选项隐含地使用了--send-eth选项,这样nmap发送的才是真正的以太网包。如果value值为0,nmap选择一个完全随机的MAC地址。如果给定的字符是一个使用分号分隔的十六进制偶数,nmap将使用这个MAC地址。

5. NSE脚本技术

5.1 NSE脚本基础

介绍:

NSE中的脚本采用Lua语言编写。使用NSE脚本可以完成许多功能,包括:对各种网络口令强度的审计、对各种服务器安全性配置的审计、对各种服务器漏洞的审计等。

5.1.1 default分类

利用default分类中所有脚本对目标进行探测,default分类中的脚本包括如下:

  • banner.NSE:这是一个用来收集目标banner信息的脚本,它会连接到目标的一个开放的TCP端口,然后输出任何在5秒内接收到的数据。
  • broadcast-ping.NSE:这个脚本使用广播ping来发现网络中的主机。
  • bns-recursion.NSE:这个脚本用来检测一个DNS服务器是否允许第三方的擦汗寻,允许这种查询可能导致服务器收到DNS放大攻击。
  • upnp-info.NSE:这个脚本尝试通过UPnP服务来提取系统服务。
  • Firewalk.NSE:这个脚本通过使用IP协议中的TTL过期机制来完成对防火墙设备的发现。

命令如下:

nmap -sV -sC -O [目标]  #-O对操作系统进行检测,-sV对服务进行检测,-sC利用default分类中的所有脚本对目标进行检测
5.1.2 其他分类

nmap中的脚本按照功能分为了以下14个种类

分类描述
auth这个分类中包含的都是负责处理鉴权证书的脚本
broadcast这个分类中包含的都是在局域网内探查更多服务开启状况,如CHCP、DNS。SQL Server等服务的脚本
brute这些都是针对常见的应用,如HTTP/FTP等使用暴力破解密码的脚本
default这是使用-sC或-A参数扫描时默认的脚本,提供基本脚本扫描能力
discovery对网络进行更多的信息收集。如SMB枚举、SNMP查询等
dos用来发起拒绝服务攻击的脚本
exploit用来完成对目标系统安全漏洞渗透的脚本
external针对第三方服务的脚本
fuzzer进行模糊测试的脚本,发送异常的包到目标机,探测出潜在漏洞
intrusive可能会引起目标系统崩溃或者对目标网络造成极大负担的脚本。这类脚本很容易被对方的防火墙或者IDS发现
malware用来检测恶意软件的脚本
safe在任何情况下都是安全无害的脚本
version负责增强服务于版本扫描功能的脚本
vuln负责检查目标机是否有常见的漏洞,如是否有著名的MS08_067

在nmap中可以在命令行中输入--script选项来完成对脚本的选择,选项后面的参数值可以是脚本的名字、脚本的种类、某一个脚本的存放路径等。

例如:

nmap -p 80,443 --script http-methods [目标]            #通过使用脚本的名字来调用脚本

nmap --script safe,discovery [目标]                    #使用种类的名字来调用一个分类中的全部脚本

nmap --script /Nmap/scripts/banner.NSE [目标]          #使用指定路径的方式来执行NSE脚本

nmap --script /NSE/user-defined/ [目标]                #执行文件夹中的全部脚本

nmap -sV --script "not exploit" [目标]                 #使用除了exploit分类意外的所有脚本对目标进行检测

nmap --script "snmp-*" [目标]                          #使用所有与SNMP相关的脚本

5.1.3 向NSE脚本中传递参数

nmap使用--script-args来指定NSE脚本运行时的参数。

例如:

nmap -p 80 --script http-methods --script-args http.useragent="Mozilla 42" [目标]  #使用--script-args修改这个客户端为Mozilla 42

如果系统一次性执行多个脚本,参数的数量就会变得很多,此时可以使用--script-args-file来指定一个文本文件,然后将所有需要参数的值都写在这个文本中。但是要注意这个文本文件中的所有参数都要使用换行符分隔开。

#myargs.txt
http.useragent="Mozilla 42"
http.max-connections=100
userdb= /data/user-defined/users.lst
passdb= /data/user-defined/passwords.lst

nmap --script "http-*" --script-args-file myargs.txt [目标]
5.1.4 NSE脚本调试

如果不仅仅想利用nmap脚本的强大实力,还想进一步了解脚本的原理,例如查看exploit种类中脚本所发送的payload就可以使用这个命令。

nmap --script http-methods --script-trace [目标]

也可以使用-d[1-9]切换到调试模式,使用-d意味着进入调试模式,后面的数字是一个从1到9的值,这个数越大,输出就越详细。

使用--packet-trace选项可以查看所有发送和收到的数据包。

nmap --script http-methods --packet-trace [目标]
5.1.5 NSE常见脚本分类
  1. 信息收集类脚本
    http-methods的使用:

    • 审计方法:脚本http-methods的原理就是通过nmap向目标服务器发送请求,来判断目标服务器所支持的HTTP方法。
  2. 高级主机发现类脚本
    broadcast-ping的使用:

    • 审计方法:通过向本地网络中的每一个IP地址发送广播探针数据包来发现本地网络中的活跃主机。这个脚本不需要任何的目标,默认以你所在的网络为目标。

    targets-sniffer的使用:

    • 审计方法:它会对你所在的网络进行嗅探,然后发现网络中的所有主机。这个脚本需要特权模式,也可以使用-e来执行网络监听的网卡设备。
  3. 密码审计类脚本
    mysql-brute.NSE的使用:

    • 审计方法:在nmap中有两个数据文件,一个文件中包含一些常见的用户名,另一个文件中包含有一些常见的密码,这个脚本将这两个文件中的用户名和密码进行组合然后尝试登录。

    smtp-brute.NSE的使用:

    • 审计方法:采用暴力穷解的方式。
  4. 漏洞扫描类脚本

5.2 NSE编写基础

5.2.1 NSE脚本的基本格式

一个完整的NSE包括如下几个部分。

  • description字段——这部分内容介绍该NSE的功能,在nmap中考研使用--script-help选项来阅读其中的内容。
  • categories字段——这部分内容给出了该NSE所在的分类,nmap中有14个分类。
  • action字段——脚本执行的具体内容。当脚本通过rule字段的检查被触发执行时,就会调用action字段定义的函数。
  • rule字段——描述脚本执行的规则,也就是确定触发脚本执行的条件。这个规则是一个Lua函数,返回值只有true和false两种。只有当rule字段返回true时,action中的函数才会执行。
5.2.2 NSE脚本的规则

NSE脚本的执行要与nmap中的扫描相结合,因此两者执行的先后顺序必须做出规定。通常这两者的执行顺序要由设定的规则来决定,目前一共有4种规则。

  • Prerule()规则:这个规则的执行要早于nmap的扫描,因此这类脚本不会调用nmap扫描得到的任何结果。执行的顺序是先脚本,后nmap扫描。
  • Hostrule()规则:这个规则是在nmap已经完成了主机发现之后执行的,根据主机发现的结果来触发该类脚本。执行的顺序是先nmap主机发现,后脚本。
  • Portrule()规则:这个规则与Hostrule()相类似,不过是在执行了端口扫描或版本侦测时才会触发的脚本,这个规则的执行与端口的状态联系紧密。执行的顺序是先nmap端口扫描,后脚本。
  • Postrule()规则:这个规则是在nmap已经完成所有的扫描之后才执行,一般用来处理扫描结果。执行的顺序是当所有的扫描都结束以后才执行脚本。

5.3 NSE中的API

nmap中API的核心功能就是向脚本提供关于主机和端口的信息。nmap中的引擎会向脚本传递如下两个Lua table类型的参数:

  • host table
  • port table
5.3.1 host table参数详解

接下来分别介绍其中包含的字段内容。

  1. host.os——该字段中包含了目标的操作系统类型。包括操作系统的供应商、所属系列、具体型号等。
  2. ost.ip——包含了目标的IP地址。
  3. host.name——包含了目标的反向DNS主机名。
  4. host.targetname——包含了目标在命令行中的名字。
  5. host.directly_connected——该字段是一个布尔值,表示目标计算机是否与我们同在一个子网。
  6. host.mac_addr——该字段是目标的MAC地址,注意只有处于同一个子网的设备,这个参数才有效。
  7. host.mac_addr_src——该字段是使用的计算机的MAC地址。
  8. host.interface_mtu——该字段是网络中的MTU值。
  9. host.bin_ip——该字段中的内容是使用4-byte字符串表示的IPv4目标地址以及使用16-byte字符串表示的IPv6目标地址。
  10. host.bin_ip_src——该字段中包含两个地址,一个是使用IPv4格式表示所使用的计算机地址,另一个是用IPv6格式表示所使用的计算机地址。
  11. host.times——该字段中的内容是目标的时序数据。
  12. host.traceroute——该字段中的数据只有在只当--traceroute时才有用。
5.3.2 port table参数详解
  1. port.number——该字段标识了目标端口的编号。
  2. port.protocol——该字段标识了目标端口的类型。
  3. port.service——该字段保存了端口上运行的服务。
  4. port.version——该字段保存了通过服务扫描发现的版本信息。
  5. port.state——该字段保存了端口上运行的状态。

5.4 NSE中的默认文件

5.4.1 NSE中的库文件

nmap中的库文件实现了代码的分离和重构,这有助于对脚本的开发。

NSE库文件的默认存储位置为nmap安装目录下的/NSElib/的文件。

5.4.2 NSE中的数据文件

数据文件的目录:

在Linux中,nmap的数据文件在usr/local/share/Nmap/NSElib/datausr/share/Nmap/NSElib/data中。

数据文件的优先级:

NSE会自动地从指定位置读取数据文件,当多个目录中都存在数据文件时,Nmap选择的优先级如下。

  • 优先级1:选项--datadir所指定的目录
  • 优先级2:环境变量中指定的位置
  • 优先级3:安装目录
  • 优先级4:在编译时定义的目录
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Merrill He

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值