1 基本操作

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

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

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

在对一台主机进行扫描的时候,如果它有域名的话,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
  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.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

在命令行中使用-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. 诸神之眼, 李华峰