参考书籍《诸神之眼——Nmap网络安全审计技术揭秘》 李华峰 著 清华大学出版社
原理:
如果想要知道处在同一网段的IP地址为
*.*.*.*
的主机是否为只需要构造一个ARP请求数据包,并广播出去,如果得到回应,则说明该主机为活跃主机。
条件:
当目标主机与我们处于同一个网段的时候,使用ARP协议扫描技术就是最佳的选择,不仅速度最快,扫描结果也是最为精准的。
命令:
nmap -PR [目标]
nmap -sn -PR [目标]
原理:
ICMP的报文可以分为两类:差错和查询。查询报文是用一对请求和应答定义的。也就是说,主机A为了获得一些信息,可以向主机B发送ICMP数据包,主机B在收到这个数据包之后,会给出应答。ICMP中适合使用的查询报文包括响应请求和应答、时间戳请求和应答以及地址掩码请求和应答。
使用ICMP协议进行主机发现:
原理:
发送ICMP响应请求,如果得到目标主机发回的ICMP响应,则说明该主机处于活跃状态。请求包的Type字段为8,响应包的Type字段为0。
命令:
nmap -PE [目标] #实际上效果等同于ping命令
nmap -sn -PE [目标]
原理:
ping命令在很多防火墙上都被隔绝了,因此需要使用其他的方法。nmap的选项
-PP
可以实现ICMP协议的时间戳主机发现。请求包的Type字段为13,响应包的Type字段为14。
命令:
nmap -sn -PP [目标]
原理:
使用nmap的选择
-PM
可以实现ICMP协议的地址掩码主机发现。请求包的Type字段为17,响应包的Type字段为18。
命令:
nmap -PM [目标]
nmap -sn -PM
原理:
nmap使用
-PS
选项来向目标主机发送一个设置了SYN标志的数据包,这个数据包的内容部分为空。目标主机在收到这个SYN数据包之后,会认为nmap所在主机想要和自己的一个端口建立连接,如果这个端口是开放的,目标主机就会按照TCP三次握手的规定,发回一个SYN/ACK数据包,表示同意建立连接。
如果这个端口是关闭的,目标主机就会拒绝这次连接,向nmap所在的主机发送一个RST数据包。
命令:
nmap -sn -PS [端口1,端口2…] [目标]
原理:
nmap发送的数据包中使用TCP/ACK标志位,按照TCP三次握手的规则,目标主机显然无法清除这是怎么回事,当然也不可能成功建立TCP连接,因此只能向nmap所在主机发送一个RST标志位的数据包,表示无法建立这个TCP连接。
命令:
nmap -sn -PA [目标]
原理:
当一个UDP端口收到一个UDP数据包时,如果它是关闭的,就会给源端发回一个ICMP端口不可达数据包;如果它是开放的,就会忽略这个数据包,也就是将它丢弃而不返回任何信息。
因为当发出一个UDP数据包而没有收到任何的应答时,有可能因为这个UDP端口是开放的,也有可能是因为这个数据包在传输过程中丢失了,因此UDP端口扫描的可靠性不高。
命令:
nmap -PU [目标]
原理:
在SCTP中,客户端使用一个INIT报文发起一个连接,服务器端使用一个INIT-ACK报文进行应答,其中就包括了cookie。然后客户端使用一个COOKIE-ECHO报文进行响应,其中包含了服务器端所发发送的cookie。服务器端要为这个连接分配资源,并通过向客户端发送一个COOKIE-ACK报文对其进行响应。
这个协议的存活扫描是不准确的,因为目前支持这个协议的主机并不多,因此这种方法只能作为一种备用手段。
命令:
nmap -sn -PY [目标]
nmap中对于端口给出了6种不同的状态:
原理:
nmap会向目标主机的一个端口发送请求连接的SYN数据包,而目标计算机在接收到这个SYN数据包之后会以SYN/ACK进行应答,nmap在收到SYN/ACK后会发送RST包请求断开连接而不是ACK应答。这样,三次握手就没有完成,无法建立正常的TCP连接,因此这次扫描不会被记录到系统日志中。
SYN扫描是nmap所采用的默认扫描方式,扫描速度极快,可以在一秒钟扫描上千个端口,也不容易被网络中的安全设备发现。
命令:
nmap -sS [目标]
原理:
这种扫描方式其实和SYN扫描很像,只是这种扫描方式完成了TCP三次握手。这种扫描方式无须root或者administrator权限。
命令:
nmap -sT [目标]
原理:
使用UDP进行扫描。
注意UDP扫描的速度是相当慢的。
扫描端口状态:
目标主机的应答 | 目标主机的状态 |
---|---|
从目标端口得到任意的UDP应答 | open |
如果目标主机没有给出应答 | open|filtered |
ICMP端口无法抵达错误 | closed |
ICMP无法抵达错误 | filtered |
命令:
nmap -sU [目标]
原理:
TCP FIN扫描方法向目标端口发送一个FIN数据包,对于所有关闭的端口,目标系统应该返回RST标志。
命令:
nmap -sF [目标]
原理:
向目标端口发送一个不包含任何标志的数据包,对于所有关闭的端口,目标系统应该返回RST标志。
命令:
nmap -sN [目标]
原理:
向目标端口发送一个含有FIN、URG和PUSH标志的数据包,对于所有关闭的端口,目标系统应该返回RST标志。
命令:
nmap -sX [目标]
原理:
idle扫描无需向目标主机发送任何数据包,它借助一个“第三方主机”来向目标端口发送数据包。
优点在于可以绕过waf,缺点在于扫描用时较长。
命令:
nmap -sI [目标]
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] [目标]
远程判断目标计算机操作系统的方法一般可以分成两类:
在nmap中可以使用-O
选项来完成对目标操作系统的扫描。
nmap -F -O [目标] #F表示fast,O表示OS系统
猜测认为最接近目标匹配操作系统类型。
nmap -O -F --fuzzy --osscan-guess [目标]
问题:使用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端口,是则可以确定版本号。1.namp -f [目标]
:
使用-f选项可以对nmap发送的探测数据包进行分段。这样将原来的数据包分成几个部分,目标网络的防御机制例如包过滤、防火墙等在对这些数据包进行检测的时候就会变得更加困难。另外必须谨慎使用这个选项,一些老旧的系统在处理分段的包时经常会出现死机的情况。
2.nmap -mtu [目标]
:
最大传输单元(Maximum Transmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。一般来说,以太网的MTU值默认为1500bytes,当数据报文的大小大于1500bytes时,就被分片。这里MTU的值必须是8的整数倍。
nmap -D decoy1,[decoy2,decoy3…] [目标]
:
同时伪造大量的主机地址对目标进行扫描。由于扫描数据包来自多个主机,即使是IDS也只能知道目前正在收到扫描,并不知道到底是哪台主机在进行扫描。使用选项-D来指定诱饵主机,使用逗号来分隔每个诱饵IP地址,也可用ME
来代表自己真实的IP地址。
使用范围:
在初始的ping扫描阶段或真正的端口扫描,以及远程操作系统检测阶段都可以使用诱饵主机选项。
nmap -g [端口号] [目标]
/ nmap --source-port [端口号] [目标]
:
-g
和--source-port
两个选项相同,只需要有一个被目标检测机制遗忘的端口号,nmap就可以从这个端口发送数据。
nmap --data-length [number] [目标]
:
默认情况下,nmap发送的报文中只包含头部,内容部分是空的,因此TCP数据包的大小只有40字节,而ICMP ECHO请求只有28字节。这种内容为空的报文很容易被目标网络检测机制所发现,因此在试图通过这些目标网络的检测机制时,可以在数据包上附加指定数量的随机字节。这个选项会使大部分ping和端口扫描变慢,但是影响不大。
nmap --ttl [value] [目标]
:
nmap中可以设置IPv4数据包的time-to-live域为指定的值,指定的参数为--ttl
,例如它的值可以为25。
nmap --spoof-mac [mac address,prefix, or vendor name] [目标]
:
通过这个选项可以人为指定nmap在进行扫描工作时发送以太网帧的MAC地址。这个选项隐含地使用了--send-eth
选项,这样nmap发送的才是真正的以太网包。如果value值为0,nmap选择一个完全随机的MAC地址。如果给定的字符是一个使用分号分隔的十六进制偶数,nmap将使用这个MAC地址。
介绍:
NSE中的脚本采用Lua语言编写。使用NSE脚本可以完成许多功能,包括:对各种网络口令强度的审计、对各种服务器安全性配置的审计、对各种服务器漏洞的审计等。
利用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分类中的所有脚本对目标进行检测
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相关的脚本
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 [目标]
如果不仅仅想利用nmap脚本的强大实力,还想进一步了解脚本的原理,例如查看exploit种类中脚本所发送的payload就可以使用这个命令。
nmap --script http-methods --script-trace [目标]
也可以使用-d[1-9]
切换到调试模式,使用-d
意味着进入调试模式,后面的数字是一个从1到9的值,这个数越大,输出就越详细。
使用--packet-trace
选项可以查看所有发送和收到的数据包。
nmap --script http-methods --packet-trace [目标]
信息收集类脚本
http-methods
的使用:
高级主机发现类脚本
broadcast-ping
的使用:
targets-sniffer
的使用:
密码审计类脚本
mysql-brute.NSE
的使用:
smtp-brute.NSE
的使用:
漏洞扫描类脚本
一个完整的NSE包括如下几个部分。
description字段
——这部分内容介绍该NSE的功能,在nmap中考研使用--script-help
选项来阅读其中的内容。categories字段
——这部分内容给出了该NSE所在的分类,nmap中有14个分类。action字段
——脚本执行的具体内容。当脚本通过rule字段
的检查被触发执行时,就会调用action字段
定义的函数。rule字段
——描述脚本执行的规则,也就是确定触发脚本执行的条件。这个规则是一个Lua函数,返回值只有true和false两种。只有当rule字段返回true时,action中的函数才会执行。NSE脚本的执行要与nmap中的扫描相结合,因此两者执行的先后顺序必须做出规定。通常这两者的执行顺序要由设定的规则来决定,目前一共有4种规则。
Prerule()规则
:这个规则的执行要早于nmap的扫描,因此这类脚本不会调用nmap扫描得到的任何结果。执行的顺序是先脚本,后nmap扫描。Hostrule()规则
:这个规则是在nmap已经完成了主机发现之后执行的,根据主机发现的结果来触发该类脚本。执行的顺序是先nmap主机发现,后脚本。Portrule()规则
:这个规则与Hostrule()
相类似,不过是在执行了端口扫描或版本侦测时才会触发的脚本,这个规则的执行与端口的状态联系紧密。执行的顺序是先nmap端口扫描,后脚本。Postrule()规则
:这个规则是在nmap已经完成所有的扫描之后才执行,一般用来处理扫描结果。执行的顺序是当所有的扫描都结束以后才执行脚本。nmap中API的核心功能就是向脚本提供关于主机和端口的信息。nmap中的引擎会向脚本传递如下两个Lua table类型的参数:
接下来分别介绍其中包含的字段内容。
host.os
——该字段中包含了目标的操作系统类型。包括操作系统的供应商、所属系列、具体型号等。ost.ip
——包含了目标的IP地址。host.name
——包含了目标的反向DNS主机名。host.targetname
——包含了目标在命令行中的名字。host.directly_connected
——该字段是一个布尔值,表示目标计算机是否与我们同在一个子网。host.mac_addr
——该字段是目标的MAC地址,注意只有处于同一个子网的设备,这个参数才有效。host.mac_addr_src
——该字段是使用的计算机的MAC地址。host.interface_mtu
——该字段是网络中的MTU值。host.bin_ip
——该字段中的内容是使用4-byte字符串表示的IPv4目标地址以及使用16-byte字符串表示的IPv6目标地址。host.bin_ip_src
——该字段中包含两个地址,一个是使用IPv4格式表示所使用的计算机地址,另一个是用IPv6格式表示所使用的计算机地址。host.times
——该字段中的内容是目标的时序数据。host.traceroute
——该字段中的数据只有在只当--traceroute
时才有用。port.number
——该字段标识了目标端口的编号。port.protocol
——该字段标识了目标端口的类型。port.service
——该字段保存了端口上运行的服务。port.version
——该字段保存了通过服务扫描发现的版本信息。port.state
——该字段保存了端口上运行的状态。nmap中的库文件实现了代码的分离和重构,这有助于对脚本的开发。
NSE库文件的默认存储位置为nmap安装目录下的/NSElib/
的文件。
数据文件的目录:
在Linux中,nmap的数据文件在usr/local/share/Nmap/NSElib/data
和usr/share/Nmap/NSElib/data
中。
数据文件的优先级:
NSE会自动地从指定位置读取数据文件,当多个目录中都存在数据文件时,Nmap选择的优先级如下。
--datadir
所指定的目录