Nmap学习笔记

1 nmap的基本操作

使用nmap最简单的方式就是在命令行中输入nmap和<目标IP地址>,例如:

1
nmap 192.168.10.20

2 扫描范围的确定

2.1 对连续范围内的主机进行扫描

输入如下命令来选择扫描范围为192.168.10.1~192.168.10.254的主机:

1
nmap -sn 192.168.10.1-255

2.2 对整个子网进行扫描

nmap支持使用CIDR(Classless Inter-Domain Routing,无分类域间路由选择)的方式来扫描整个子网。
因此,如果要扫描192.168.10.1~192.168.10.254这个子网范围的主机,还可以使用如下命令:

1
nmap -sn 192.168.10.1/24

2.3 对多个不连续的主机进行扫描

nmap可以一次扫描多个主机,如果这些扫描的目标地址没有任何的关系,那么可以通过将目标地址用空格分隔开的方式来同时对这些主机进行扫描。
如果对192.168.10.10、192.168.10.20、192.168.10.30、192.168.10.40进行扫描,可以使用如下命令:

1
nmap -sn 192.168.10.10 192.168.10.20 192.168.10.30 192.168.10.40 

2.4 在扫描的时候排除指定的目标

在对一些主机进行扫描时,如果需要排除某些指定主机,可以使用--exclude选项。
例如,如果我们希望在扫描192.168.10.0/24子网的时候,并不对192.168.10.20进行扫描,就可以使用如下命令。

1
nmap -sn 192.168.10.0/24 --exclude 192.168.10.20

2.5 对一个文本文件中的地址列表进行扫描

如果需要经常性地对某些地址进行扫描,那么每次都在命令中输入这些地址是相当麻烦的,可以将常用的地址保存在一个记事本文件中,然后用 -iL 把文件名作为选项传给Nmap。

例如List.txt,以后,每次想对这些地址进行扫描,无须重新输入,只需要将这个文本文件设定为目标即可:

1
2
3
4
5
6
vim List.txt
192.168.10.10
192.168.10.20 192.168.10.30
192.168.10.40

nmap -sn -iL List.txt

2.6 随机确定扫描目标

nmap中还提供了一个非常有意思的功能,那就是使用-iR选项指定n个随机目标,然后nmap会对这些目标进行扫描。

下面随机地在互联网上对3个IP地址进行扫描,使用的命令如下:

1
nmap -sn -iR 3

3 活跃主机发现技术

活跃主机: 已经处于运行状态并且网络功能正常的主机

nmap在扫描时,默认会将目标例如端口之类的信息也扫描出来,但是如果只是想要知道目标是否为活跃主机,则并不需要这些信息。
而如果使用-sn参数,则只会显示是否为活跃主机这一条,在nmap中执行如下命令:

1
nmap -sn scanme.nmap.org

3.1 基于ARP协议的活跃主机发现技术

基于ARP协议的活跃主机发现技术的原理是:如果想要知道处在同一网段的IP地址为 *.*.*.* 的主机是否为活跃主机,只需要构造一个ARP请求数据包,并广播出去,如果得到了回应,则说明该主机为活跃主机。
这种发现技术的优点在于准确度高,任何处于同一网段的设备都没有办法防御这种技术,因为如果不遵守ARP,那么将意味着无法通信。缺点在于这种发现技术不能对处于不同网段的目标主机进行扫描

当目标主机与我们处于同一网段的时候,使用ARP协议扫描技术就是最佳的选择。不仅速度最快,扫描结果也是最为精准的。这是因为没有任何安全措施会阻止正常的ARP请求。使用nmap的选项-PR就可以实现ARP协议的主机发现

1
nmap -sn -PR 192.168.10.20

由于Nmap的设计思路,Nmap会首先判断目标主机与Nmap所在主机是否在同一网段,如果相同的话,则继续使用ARP扫描模式,否则使用TCP扫描模式。

3.2 基于ICMP协议的活跃主机发现技术

  • ICMP的报文可以分成两类:差错报告报文和询问报文。
  • nmap的ICMP活跃主机发现技术使用的就是询问报文
  • ICMP协议中包含了很多种方法,但是这些基于ICMP协议的扫描方式往往也是安全机制防御的重点,因此经常得不到准确的结果。
  • 如果不使用root权限,Nmap 将使用一种称为“TCP Pingscan”的替代方法来检查目标主机的在线状态。这种方法利用TCP协议发送一个无效的TCP连接请求,来观察目标主机是否响应。

ICMP中适合使用的询问报文包括如下3类

3.2.1 响应请求和应答

使用nmap的选项-PE就可以实现ICMP协议的响应请求主机发现。这个过程实质上和ping是一样的。

1
sudo nmap -sn -PE scanme.nmap.org

3.2.2 时间戳请求和应答

ping方式已经被很多网络所禁止,因此必须另觅它法。比如时间戳请求和应答。
使用nmap的选项-PP就可以实现ICMP协议的时间戳主机发现

1
sudo nmap -sn -PP scanme.nmap.org

3.2.3 地址掩码请求和应答

虽然这个协议主要使用在无盘系统中,但是也有一些系统在收到这个请求后会发送一个应答。需要注意的是,这种方法在实际中很少使用
使用nmap的选项-PM可以实现ICMP协议的地址掩码主机发现:

1
sudo nmap -PM -sn scanme.nmap.org

3.3 基于TCP协议的活跃主机发现技术

3.3.1 TCP SYN扫描

  1. TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
  2. TCP的特点是使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答TCP的三次握手SYN+ACK,并最终对对方的SYN执行ACK确认。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议。
  3. 如果想知道主机B是否处于活跃状态,就可以向主机B的全部端口(通常并不这样做,而是选择一部分常用的端口)发送连接请求数据包,如果得到回应(注意只要收到了数据包),就可以认为主机B是活跃主机。
  4. TCP扫描是nmap扫描技术中最强大的技术之一,很多服务器的防御机制都会屏蔽掉ICMP echo请求数据包,但是任何的服务器都会响应针对其服务的SYN数据包

nmap中使用-PS选项来向目标主机发送一个设置了SYN标志的数据包,这个数据包的内容部分为空。通常默认的目标端口是80端口,也可以使用参数(可以指定一个以逗号分隔的端口列表,端口与选项之间不能有空格)来改变目标端口:

1
nmap -sn -PS scanme.nmap.org

3.3.2 TCP ACK扫描

  1. 和SYN扫描相当相似,不同之处只在于nmap发送的数据包中使用TCP/ACK标志位,而不是SYN标志位。
  2. nmap直接向目标主机发送一个TCP/ACK数据包,目标主机显然无法清楚这是怎么回事,当然也不可能成功建立TCP连接,因此只能向nmap所在主机发送一个RST标志位的数据包。
  3. 在实际情况中,这种类型的扫描很少能成功,造成这种情况的原因是目标主机上的安全机制或者安全设备将这种莫名其妙的TCP/ACK包直接过滤掉了。
  4. 这种ACK扫描的方式同样以80端口作为默认端口,也可以进行指定。

如果需要对目标主机采用这种扫描方式,可以使用使用nmap的选项-PA

1
nmap -sn -PA scanme.nmap.org

3.4 基于UDP协议的活跃主机发现技术

  1. 由于UDP协议是非面向连接的,对UDP端口的探测也就不可能像TCP端口的探测那样依赖于连接建立过程,这也使得UDP端口扫描的可靠性不高。
  2. 当一个UDP端口收到一个UDP数据包时,如果它是关闭的,就会给源端发回一个ICMP端口不可达数据包(有效判断);如果它是开放的,就会忽略这个数据包,也就是将它丢弃而不返回任何信息(将无法判断数据包是在传输过程中丢失了还是被目的主机丢弃了)。
  3. TCP需要扫描目标主机开放的端口,而UDP需要扫描的是目标主机关闭的端口,在扫描的过程中,需要避开那些常用的UDP协议端口,例如DNS(端口53)、SNMP(161)。因此在扫描的时候,最合适的做法就是选择一个值比较大的端口,例如35462。默认探测端口是40125这样一个极不可能被使用的端口。

使用nmap的选项-PU就可以实现UDP协议的主机发现:

1
sudo nmap -sn -PU scanme.nmap.org

使用UDP Ping(-PU),需要以root权限运行, 因为需要从网络中读取原始响应数据

3.5 基于SCTP协议的活跃主机发现技术

  1. 如果得到的结果和实际不一致,主要原因是目标主机并不支持SCTP协议。目前支持这个协议的主机并不多,因此这种方法只能作为一种备用手段

使用nmap的选项-PY就可以向目标主机发送一个SCTP INIT数据包:

1
sudo nmap -sn -PY scanme.nmap.org

使用SCTP INIT Ping(-PU),需要以root权限运行, 因为需要从网络中读取原始响应数据

3.6 使用IP协议进行主机地址发现

nmap中允许向目标主机发送IP数据包来检测目标主机是否活跃,理论上可以使用的协议多达上百个。这种方式允许指定所要使用的协议,如果不指定的话,nmap默认使用ICMP(IP协议编号1)、IGMP(IP协议编号2)和IP-in-IP(IP协议编号4)三个协议。另外也可以使用选项-PO来指定所要使用协议的编号,例如默认的IP扫描方式:

1
sudo nmap -sP 192.168.10.20

实际上就相当于:

1
sudo nmap -sP -PO1,2,4 192.168.10.20

另外,这种情形发出的数据包内容都是空的,这种数据包很容易被检测出来,可以使用一个--data-length参数来发送添加了随机数据的数据包。例如:

1
sudo nmap -sP --data-length 25 192.168.10.20

4 nmap中的DNS选项

在对一台主机进行扫描的时候,如果它有域名的话,nmap会向域名服务器提出请求,显示该IP所对应的域名(反向域名解析)。但是,在进行扫描时,可能扫描的是一个范围,在这个范围内主机可能有的处于活跃状态,而有的却处于非活跃状态,如果直接进行扫描,nmap只会对处于活跃状态的主机进行DNS转换(会在DNS服务器上留下查询记录),而非活跃状态的主机则不予处理。

如果希望所有的目标IP无论是否是活跃主机, 都将其对应的域名列出来的话,可以使用-R参数:

1
nmap -R 45.33.32.156-160

如果强制将每一个IP都转换为域名,将会耗费大量的时间,有时可能已经知道主机的域名,无须进行任何转换,此时就可以使用-n参数来取消反向域名解析,这一点在对大规模的网络进行扫描时效果极其明显:

1
nmap -n 45.33.32.156-160

如果不想在自己的DNS服务器留下这次查询的记录,可能需要使用指定的DNS服务器来查询目标,这时就可以使用--dns-servers参数:

1
nmap --dns-servers 8.8.8.8 45.33.32.156

5 主机发现技术的分析

  1. nmap中提供了--packet-trace选项,通过它就可以观察nmap发出了哪些数据包,收到了哪些数据包,有了这个研究方法,可以更深入地理解nmap的运行原理。
1
nmap -sn -PY 192.168.10.20 --packet-trace

在对192.168.10.20扫描时,虽然也使用了-PY选项,但是根本没有发送SCTP数据包,而是使用了ARP格式的请求。这其实是由于nmap的设计思路,nmap会首先判断目标主机与nmap所在主机是否在同一网段,如果相同的话,则直接使用ARP扫描模式。

6 端口扫描技术

6.1 端口状态的定义

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

  1. open:如果目标端口的状态为open,这表明在该端口有应用程序接收TCP连接或者UDP报文。

  2. closed:如果目标端口的状态为closed,这里要注意closed并不意味着没有任何反应,状态为closed的端口是可访问的,这种端口可以接收nmap探测报文并做出响应。相比较而言,没有应用程序在open上监听。

  3. filtered:产生这种结果的原因主要是存在目标网络数据包过滤,由于这些设备过滤了探测数据包,导致nmap无法确定该端口是否开放。这种设备可能是路由器、防火墙甚至专门的安全软件。

  4. unfiltered:这种结果很少见,它表明目标端口是可以访问的,但是nmap却无法判断它到底是open还是closed的。通常只有在进行ACK扫描时才会出现这种状态。

  5. open | filtered:无法确定端口是开放的还是被过滤了,开放的端口不响应就是一个例子。

  6. closed|filtered:无法确定端口是关闭的还是被过滤了。只有在使用idle扫描时才会发生这种情况。

6.2 SYN扫描

SYN扫描是最为流行的一种扫描方式,同时它也是nmap所采用的默认扫描方式。这种扫描方式速度极快,可以在一秒钟扫描上千个端口。又因为nmap在收到SYN/ACK后会发送RST包请求断开连接而不是ACK应答。这样,三次握手就没有完成,无法建立正常的TCP连接,本次扫描也就不会被记录到系统日志中,SYN扫描也就不容易被网络中的安全设备所发现

你也可以在扫描的时候输入参数-sS选项。其实只要你是以root或者administrator权限工作的,扫描的形式都是SYN的:

1
sudo nmap -sS scanme.nmap.org

6.3 Connect扫描

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

例如对目标scanme.nmap.org6y扫描,使用-sT选项,命令如下:

1
nmap -sT scanme.nmap.org

6.4 UDP扫描

在扫描过程中可能会产生一些状态为filtered的端口,这些端口的真实状态可能是open,也有可能是closed。要从这些状态为filtered的端口中找到那些其实是open的端口,需要进一步的测试。

要注意UDP扫描的速度是相当慢的,原因是在RFC1812中对ICMP错误报文的生成速度做出了限制

使用Connect扫描端口的选项为-sU:

1
sudo nmap -sU scanme.nmap.org

6.5 TCP FIN扫描

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

使用TCP FIN扫描端口的选项为-sF:

1
sudo nmap -sF scanme.nmap.org

6.6 NULL扫描

TCP NULL扫描方法是向目标端口发送一个不包含任何标志的数据包。按照RFC 793的规定,对于所有关闭的端口,目标系统应该返回RST标志。

使用TCP NULL扫描端口的选项为-sN:

1
sudo nmap -sN scanme.nmap.org

6.7 Xmas Tree扫描

TCP Xmas Tree扫描方法是向目标端口发送一个含有FIN、URG和PUSH标志的数据包。按照RFC 793的规定,对于所有关闭的端口,目标系统应该返回RST标志。

使用TCP Xmas Tree扫描端口的选项为-sX:

1
nmap -sX scanme.nmap.org

6.8 idle扫描

一种更加高级的扫描方式是TCP空闲扫描,这种扫描能让我们冒充网络上另一台主机的ip地址,对目标进行更为隐秘的扫描(这里的空闲主机的意思是该主机在一段特定时间内不向网络发送数据包)。

例如使用-sI选项指定 kiosk.adobe.com 作为第三方主机,然后对http://www.riaa.com 进行扫描:

1
sudo nmap -Pn -p- -sI kiosk.adobe.com www.riaa.com

6.9 指定扫描的端口

  1. 扫描常见的100个端口
1
nmap -F scanme.nmap.org
  1. 指定某一个端口
1
nmap -p80 scanme.nmap.org
  1. 使用名字来指定扫描端口
1
nmap -p ssh,http scanme.nmap.org
  1. 使用协议指定扫描端口
1
nmap -sU -sT -p U:53, T:25 scanme.nmap.org
  1. 扫描所有端口
1
nmap -p * scanme.nmap.org
  1. 扫描常用端口
1
nmap --top-ports 10 scanme.nmap.org

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

在命令行中使用-O选项通过端口扫描来完成对操作系统的扫描。这个命令将会使用Nmap默认的SYN扫描方式来完成端口检测:

1
sudo nmap -O scanme.nmap.org

7.1 操作系统指纹简介

Nmap并不使用被动式的判断目标计算机操作系统的方法。Nmap中的主动式方法采用多达15个探针的操作系统指纹扫描包。操作系统指纹这个名字来源于生物学上的名词指纹。因为人的指纹都是独一无二的,因此可以作为身份验证的一种机制。同样每一种类型的操作系统也都有自己的特征,通过向一台计算机发送特定格式的探针(数据包)来查看目标主机的响应数据,这一过程就是操作系统指纹分析的过程。这些强大的探针利用了TCP、UDP、ICMP等各种协议。这些探针经过巧妙设计,可以发现目标操作系统细微的差别。

7.2 使用Nmap进行服务发现

Nmap提供了更精确的服务及版本检测选项,可通过添加选项-sV进行服务和版本检测:

1
sudo nmap -sV scanme.nmap.org

首先进行端口扫描,默认情况下使用SYN扫描。其次进行服务识别,发送探针报文,得到返回确认值,确认服务。最后进行版本识别,发送探针报文,得到返回的报文信息,分析得出服务的版本。

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

-sV(版本探测):打开版本探测。也可以用-A同时打开操作系统探测和服务发现。

-osscan-guess: 这是Nmap的猜测功能选项,猜测认为最接近目标的匹配操作系统类型。

--allports(不为版本探测排除任何端口):通常,Nmap在进行版本探测时不会对目标的全部端口进行扫描,而是会跳过一些端口,例如端口号为9100的TCP端口。如果对这个端口进行扫描,而目标又恰好是一台打印机的话,这台打印机就有可能会将所有的数据都打印出来。如果确实有必要的话,也可以使用–allports扫描所有的端口。

--version-intensity <intensity>(设置版本扫描强度):当进行版本扫描(-sV)时,Nmap发送一系列探测报文,每个报文都被赋予一个1到9之间的值。这里的强度水平说明了应该使用哪些探测报文。数值越高,服务越有可能被正确识别。然而,高强度扫描花更多时间。强度值必须在0和9之间。默认是7。

--version-light(打开轻量级模式):–version-light其实就相当于–version-intensity 2。这种轻量级模式使版本扫描速度快了许多,不过使用这种模式对服务进行扫描成功的几率也小一些。

--version-all(尝试每个探测):–version-all其实就相当于version-intensity 9,保证对每个端口尝试所有探测报文。

--version-trace(跟踪版本扫描活动)这将会使Nmap打印出关于正在进行的扫描的详细调试信息。它是你用–packet-trace所得到的信息的子集。

-sR(RPC扫描)这种方法和许多端口扫描方法联合使用。它对所有被发现开放的TCP/UDP端口执行SunRPC程序NULL命令,试图确定它们是否RPC端口,如果是,可以确定是什么程序和版本号。

参考书籍:

  1. 诸神之眼, 李华峰