前言
非常强大的扫描工具,Kali中有自带的nmap,Windows系统可以在这里下载
在内网渗透时想知道同网段有哪些主机,或者想知道指定主机开了扫描端口,就可以拿nmap扫一扫。实际它的官方文档已经很全了,Kali里面输入man nmap
还有中文的文档。
基本语法
基本语法如下,如果没有加特殊的选项默认使用TCP全连接扫描,而且会先进行主机发现再对在线的主机进行端口扫描
|
|
扫描指定IP
|
|
扫描多个目标
|
|
CIDR
|
|
指定IP范围
|
|
排除特定IP
|
|
主机发现
主机发现是为了解决我们的第一个需求,即想知道同网段有哪些主机,如果没有特殊的需求写个Linux shell脚本ping其他主机也能实现,但在nmap中除了ping还有其他的方式实现主机发现
ping
首先需要了解的是一个参数是-sn
,加上这个参数后nmap会使用ping扫描,不进行端口扫描,如果没有指定特殊选项nmap会发送ICMP协议的数据包,如果IP不在线则会收到一个目的地址不可达的ICMP差错报文。其次nmap还会自动判断目标是否与自己在同一个网段中,如果在同一个网段中nmap默认会使用ARP协议进行主机发现,如果使用ARP协议可以获取到主机的MAC地址,然后还能根据主机的MAC地址获取到主机的一些信息。
|
|
然后需要了解的是-Pn
参数,与-sn
参数正好相反,它是指定nmap只进行端口扫描,不判断目标主机是否在线。
|
|
nmap中还有其他-P*
系列的参数在官方文档中都记录为Ping扫描,例如-PS
参数是在官方文档中记录的是TCP SYN Ping,-P*
系列参数只会指定主机发现时的方式,不会改变端口扫描的方式。其次即是加上了-PS
参数,对于同网段的主机依然会使用ARP协议进行扫描,对于不同网段的主机才会使用SYN Ping进行扫描。默认情况下nmap会先对主机进行ping扫描再对在线的主机进行端口扫描,如果只需要进行主机发现,可以用-sn
参数禁掉端口扫描。
传输层扫描:
nmap中有-PS/PA/PU/PY
这几个参数,这几个参数后面可以加上端口列表,列表可以用逗号分隔开,也可以使用-
指定范围,也可以不加参数,就会扫描0-65535端口
首先看-PS
参数,加上这个参数可以指定nmap进行SYN Ping,对于不同网段的主机nmap会尝试给目标主机的80端口发送一个设置了SYN标志位的TCP报文,如果目标主机在线,则对方会响应一个TCP报文,如果收不到响应则判断目标主机不在线。通常TCP的原始数据是由操作系统发送的,在unix的机器下只有root用户才能原始的TCP报文,如果nmap发送了一个TCP原始报文,操作系统收到对方回复的SYN+ACK报文后不会回复ACK报文进行确认,而会回复一个RST报文断开连接,因为它觉得自己没有请求与目标主机建立连接。而如果是非root用户,是不能发送原始TCP报文的,如果指定了该参数nmap会提示我不是root用户,不能用这种参数。
|
|
-PA
参数和-PS
参数类似,区别在于如果指定了-PA
参数则nmap在扫描时会发送ACK报文,如果对方端口开放则对方会回复SYN+ACK
报文,如果关闭则会回复RST+ACK
报文,由此判断对方端口是否在线
|
|
-PU
参数会使用UDP协议发送空的UDP报文对目标主机进行端口扫描,正常情况下操作系统是不会回复空的UDP报文的,但如果对方在线且端口关闭则会手动对方回复的目的地址不可达的响应
|
|
-PY
参数会使用SCTP协议对目标主机进行扫描,SCTP协议是传输层协议,和TCP类似,它使用了四次握手建立连接,三次握手关闭连接,一旦一端拆除连接,双方都拆除连接。SCTP协议建立连接的过程是:INIT、INIT-ACK、COOKIE-ECHO、COOKIE-ACK。和SYN Ping一样,如果使用了-PY
参数,则nmap会向目标主机发送INIT报文,根据对方是否响应判断对方是否在线。
|
|
网络层扫描
-PE/PP/PM
这几个参数是网络层的扫描,使用ICMP协议,分别是向目标主机发送ICMP的echo、timestamp、netmask的请求进行扫描,如果对方不在线则我们会收到一个目标主机不可达的ICMP响应
|
|
端口扫描
端口扫描是为了解决我们的第二个需求,即想知道指定主机开了扫描端口,用nmap可以快速对目标主机进行扫描。
使用-p
参数可以指定端口,端口可以用逗号分隔开,也可以使用-
指定范围。还能使用--exclude-ports
参数排除某些IP
|
|
端口扫描的时候同样有全连接和半连接扫描,-s*
的参数是用于指定扫描时的选项
首先来看-sS/sT/sA/sW/sM
这几个参数,这几个参数用于指定端口扫描时建立的TCP连接的的选项,使用-sS
指定nmap进行SYN scans,是一种半连接扫描,不会建立完整的TCP连接。使用该参数可以使得nmap向目标主机发送SYN报文,如果对方回复SYN+ACK
报文则判断对方端口开启,如果回复的是RST+ACK
报文则判断对方端口关闭。半连接扫描相对全连接扫描更隐蔽,不会在目标主机上留下痕迹,但需要root权限才能进行扫描。
-sA
参数指定的是ACK扫描,和-sS
参数一样是一种半连接扫描,不会建立完整的TCP连接。
|
|
-sT
是默认是扫描方式,使用-sT
参数时nmap会调用系统的connect()
函数与目标主机建立完整的TCP连接,在用户没有权限发送原始的TCP报文或者扫描Ipv6网络时可以使用这种方式,相对于半连接扫描,这种扫描方式效率较低,而且可能会在目标主机上留下记录。
|
|
-sW
参数是TCP Window scans,是通过检查操作系统返回的窗口大小检测扫描结果。在某些系统上对于开放的端口用正数表示窗口大小而关闭的窗口则窗口大小为0
-sM
参数是使用FIN+ACK
报文扫描端口,根据RFC 793 (TCP),无论端口开放或者关闭,都应该响应这样的RST报文,但在某些系统上开放的端口会直接丢弃FIN+ACK
报文,而关闭的端口会回复RST报文。-sW
和-sM
这俩参数都是利用的TCP的实现细节进行端口扫描,扫端口都不太准确。
|
|
-sN/sF/sX
这三个参数利用了TCP协议的一些标志位进行扫描。根据RFC协议,端口关闭时,对于任何不包含SYN,RST,或者ACK的报文都应该返回一个RST的报文,而对于开放的端口则不响应。所以只要发送不包含SYN,RST,或者ACK的报文都可以用于判断端口是否开放,如果收到RST响应则说明端口关闭,而没有收到响应说明端口开放或者被防火墙过滤了。这种方式的缺点在于无法判断端口是开放状态还是报文被防火墙过滤了。
|
|
除了这三个参数以外还可以使用--scanflags
参数手动设置标志位,只需要设置不包含SYN,RST,或者ACK的报文都可以用于判断端口是否开放,例如设置--scanflags 9
即为PSH+FIN
报文。这个参数还可以使用-sS
或-sF
参数告诉nmap如何对待没有回复的端口,例如SYN scans认为没有回复的端口是被过滤的端口,而FIN scans认为没有回复的端口是开放的端口或者被过滤的端口
|
|
除此之外还可以指定-sY/sZ
参数使用SCTP协议的INIT/COOKIE-ECHO选项进行端口扫描
服务器信息搜集
搜集服务器信息的大概有这三个参数:
-O
参数可用于操作系统指纹识别。原理大概是通过识别不同系统中TCP/IP协议实现的细节,例如IP协议中Initial TTL值和TCP协议的Window Size两个字段在不同系统中有不同的初始值。nmap中有大量的TCP/IP堆栈指纹特征与操作系统的对应关系。
|
|
使用-sV
参数可以搜集服务器信息:
|
|
使用-A
参数是一个比较全面的扫描选项,这个包含了操作系统检测(-O
) 和版本扫描(-sV
)。
源地址欺骗
使用--proxies
参数指定代理,在nmap中支持socks4和http代理,设置这个参数后可以用代理主机的IP进行扫描,有多个代理服务器时可以使用逗号分隔开
|
|
使用-D
参数指定使用诱饵隐蔽扫描,这样后台管理员能看到的就是有好几个IP都在对目标主机进行扫描,里面也混进去了我们的真实IP,不过这种方法应该是只能在局域网使用。下面这条命令敲下去就能看到有好几个IP都对目标主机发了大量的SYN报文
|
|
使用-g/--source-port
参数可以指定源端口号,不过大概没什么用,因为IP还是会暴露
|
|
用nmap -h
还能看到几个有用的参数比如-S
和--spoof-mac
分别可以伪造源IP和源MAC地址,不过我在本地尝试的时候都没扫成功,还有就是使用-b
参数可以利用存在bounce 漏洞的FTP跳板进行扫描,这是个非常古老的漏洞,现在都失效了,所以并没有什么用。