五、 主机发现

任何网络探测任务的最初几个步骤之一就是把一组 IP 范围(有时该范围是巨大的)缩小为 一列 活动的或者您感兴趣的主机。扫描每个 IP 的每个端口很慢,通常也没必要。 当然,什么样的 主机令您感兴趣主要依赖于扫描的目的。网管也许只对运行特定服务的 主机感兴趣,而从事安 全的人士则可能对一个马桶都感兴趣,只要它有 IP 地址:-)。一个系统管理员 也许仅仅使用 Ping 来定位内网上的主机 而一个外部入侵测试人员则可能绞尽脑汁用各种方法试图 突破防火 墙的封锁。

由于主机发现的需求五花八门,Nmap 提供了一箩筐的选项来定制您的需求。 主机发现有时候也 叫做 ping 扫描,但它远远超越用世人皆知的 ping 工具 发送简单的 ICMP 回声请求报文。用户 完全可以通过使用列表扫描(-sL)或者 通过关闭 ping (-P0)跳过 ping 的步骤,也可以使用多个端口把 TPC SYN/ACK,UDP 和 ICMP 任意组合起来玩一玩。这些探测的目的是获得响应以显示某 个 IP 地址是否是活动的(正在被某 主机或者网络设备使用)。 在许多网络上,在给定的时间, 往往只有小部分的 IP 地址是活动的。 这种情况在基于 RFC1918 的私有地址空间如 10.0.0.0/8 尤其普遍。 那个网络有 16,000,000 个 IP,但我见过一些使用它的公司连 1000 台机器都没有 主机发现能够找到零星分布于 IP 地址海洋上的那些机器。

如果没有给出主机发现的选项,Nmap 就发送一个 TCP ACK 报文到 80 端口和一个 ICMP 回声请求 到每台目标机器。 一个例外是 ARP 扫描用于局域网上的任何目标机器。对于非特权 UNIX shell 用户,使用 connect()系统调用会发送一个 SYN 报文而不是 ACK 这些默认行为和使用-PA -PE 选项的效果相同。 扫描局域网时,这种主机发现一般够用了,但是对于安全审核,建议进行 更 加全面的探测。

-P*选项(用于选择 ping 的类型)可以被结合使用。 您可以通过使用不同的 TCP 端口/标志位和 ICMP 码发送许多探测报文 来增加穿透防守严密的防火墙的机会 另外要注意的是即使您指定了 其它 -P*选项,ARP 发现(-PR)对于局域网上的 目标而言是默认行为,因为它总是更快更有效

下列选项控制主机发现。

-sL (列表扫描)

列表扫描是主机发现的退化形式,它仅仅列出指定网络上的每台主机, 不发送任何报文 到目标主机。默认情况下,Nmap 仍然对主机进行反向域名解析以获取 它们的名字。简单 的主机名能给出的有用信息常常令人惊讶。例如, fw.chi.playboy.com 是花花公子芝加 哥办公室的 防火墙。Nmap 最后还会报告 IP 地址的总数。列表扫描可以很好的确保您拥 有正确的目标 IP。 如果主机的域名出乎您的意料,那么就值得进一步检查以防错误地扫 描其它组织的网络。

既然只是打印目标主机的列表 像其它一些高级功能如端口扫描 操作系统探测或者 Ping 扫描 的选项就没有了。如果您希望关闭 ping 扫描而仍然执行这样的高级功能,请继续 阅读关于 -P0 选项的介绍。

-sP (Ping 扫描)

该选项告诉 Nmap 仅仅 进行 ping 扫描 (主机发现),然后打印出对扫描做出响应的那些 主机。 没有进一步的测试 (如端口扫描或者操作系统探测)。 这比列表扫描更积极,常 常用于 和列表扫描相同的目的。它可以得到些许目标网络的信息而不被特别注意到。 对 于攻击者来说 了解多少主机正在运行比列表扫描提供的一列 IP 和主机名往往更有价值

系统管理员往往也很喜欢这个选项。 它可以很方便地得出 网络上有多少机器正在运行 或者监视服务器是否正常运行。常常有人称它为 地毯式 ping,它比 ping 广播地址更可 靠,因为许多主机对广播请求不响应。

-sP 选项在默认情况下, 发送一个 ICMP 回声请求和一个 TCP 报文到 80 端口。如果非特 权用户执行,就发送一个 SYN 报文 (用 connect()系统调用)到目标机的 80 端口。 当特 权用户扫描局域网上的目标机时,会发送 ARP 请求(-PR), ,除非使用了--send-ip 选项

-sP 选项可以和除-P0)之外的任何发现探测类型-P* 选项结合使用以达到更大的灵活性 一旦使用了任何探测类型和端口选项,默认的探测(ACK 和回应请求)就被覆盖了。 当防 守严密的防火墙位于运行 Nmap 的源主机和目标网络之间时, 推荐使用那些高级选项。 否则,当防火墙捕获并丢弃探测包或者响应包时,一些主机就不能被探测到。

-P0 (无 ping)

该选项完全跳过 Nmap 发现阶段。 通常 Nmap 在进行高强度的扫描时用它确定正在运行的 机器。 默认情况下,Nmap 只对正在运行的主机进行高强度的探测如 端口扫描,版本探 测,或者操作系统探测。用-P0 禁止 主机发现会使 Nmap 对每一个指定的目标 IP 地址 进 行所要求的扫描。所以如果在命令行指定一个 B 类目标地址空间(/16), 所有 65,536 个 IP 地址都会被扫描。 -P0 的第二个字符是数字 0 而不是字母 O。 和列表扫描一样,跳过 正常的主机发现,但不是打印一个目标列表, 而是继续执行所要求的功能,就好像每个 IP 都是活动的。

-PS [portlist] (TCP SYN Ping)

该选项发送一个设置了 SYN 标志位的空 TCP 报文。 默认目的端口为 80 (可以通过改变 nmap.h) 文件中的 DEFAULT_TCP_PROBE_PORT 值进行配置,但不同的端口也可以作为选项 指定。 甚至可以指定一个以逗号分隔的端口列表(如 -PS22,23,25,80,113,1050, 35000), 在这种情况下,每个端口会被并发地扫描。

SYN 标志位告诉对方您正试图建立一个连接。 通常目标端口是关闭的,一个 RST (复位) 包会发回来。 如果碰巧端口是开放的,目标会进行 TCP 三步握手的第二步,回应 一个 SYN/ACK TCP 报文。然后运行 Nmap 的机器则会扼杀这个正在建立的连接, 发送一个 RST 而非 ACK 报文,否则,一个完全的连接将会建立。 RST 报文是运行 Nmap 的机器而不是 Nmap 本身响应的,因为它对收到 的 SYN/ACK 感到很意外。

Nmap 并不关心端口开放还是关闭。 无论 RST 还是 SYN/ACK 响应都告诉 Nmap 该主机正在 运行。

在 UNIX 机器上,通常只有特权用户 root 能否发送和接收 原始的 TCP 报文。因此作为 一个变通的方法,对于非特权用户, Nmap 会为每个目标主机进行系统调用 connect(), 它也会发送一个 SYN 报文来尝试建立连接。如果 connect()迅速返回成功或者一个 ECONNREFUSED 失败,下面的 TCP 堆栈一定已经收到了一个 SYN/ACK 或者 RST,该主机将 被 标志位为在运行。 如果连接超时了,该主机就标志位为 down 掉了。这种方法也用于 IPv6 连接,因为 Nmap 目前还不支持原始的 IPv6 报文。

-PA [portlist] (TCP ACK Ping)

TCP ACK ping 和刚才讨论的 SYN ping 相当类似。 也许您已经猜到了,区别就是设置 TCP 的 ACK 标志位而不是 SYN 标志位。 ACK 报文表示确认一个建立连接的尝试,但该连接尚 未完全建立。 所以远程主机应该总是回应一个 RST 报文, 因为它们并没有发出过连接 请求到运行 Nmap 的机器,如果它们正在运行的话。

-PA 选项使用和 SYN 探测相同的默认端口(80) 也可以 用相同的格式指定目标端口列表 如果非特权用户尝试该功能, 或者指定的是 IPv6 目标,前面说过的 connect()方法将被 使用。 这个方法并不完美,因为它实际上发送的是 SYN 报文,而不是 ACK 报文。

提供 SYN 和 ACK 两种 ping 探测的原因是使通过防火墙的机会尽可能大。 许多管理员会 配置他们的路由器或者其它简单的防火墙来封锁 SYN 报文,除非 连接目标是那些公开的 服务器像公司网站或者邮件服务器。 这可以阻止其它进入组织的连接,同时也允许用户 访问互联网。 这种无状态的方法几乎不占用防火墙/路由器的资源,因而被硬件和软件 过滤器 广泛支持。Linux Netfilter/iptables 防火墙软件提供方便的 --syn 选项来实 现这种无状态的方法。 当这样的无状态防火墙规则存在时,发送到关闭目标端口的 SYN ping 探测 (-PS) 很可能被封锁。这种情况下,ACK 探测格外有闪光点,因为它正好利用 了 这样的规则。

另外一种常用的防火墙用有状态的规则来封锁非预期的报文。 这一特性已开始只存在于 高端防火墙,但是这些年类它越来越普遍了。 Linux Netfilter/iptables 通过 --state 选项支持这一特性,它根据连接状态把报文 进行分类。SYN 探测更有可能用于这样的系 统,由于没头没脑的 ACK 报文 通常会被识别成伪造的而丢弃。解决这个两难的方法是通 过即指定 -PS 又指定-PA 来即发送 SYN 又发送 ACK。

-PU [portlist] (UDP Ping)

还有一个主机发现的选项是 UDP ping,它发送一个空的(除非指定了--data-length UDP 报文到给定的端口。端口列表的格式和前面讨论过的-PS 和-PA 选项还是一样。 如果不 指定端口,默认是 31338。该默认值可以通过在编译时改变 nmap.h 文件中的 DEFAULT_UDP_PROBE_PORT 值进行配置。默认使用这样一个奇怪的端口是因为对开放端口 进行这种扫描一般都不受欢迎。

如果目标机器的端口是关闭的,UDP 探测应该马上得到一个 ICMP 端口无法到达的回应报 文。 这对于 Nmap 意味着该机器正在运行。 许多其它类型的 ICMP 错误,像主机/网络无 法到达或者 TTL 超时则表示 down 掉的或者不可到达的主机。 没有回应也被这样解释。 如果到达一个开放的端口,大部分服务仅仅忽略这个 空报文而不做任何回应。这就是为 什么默认探测端口是 31338 这样一个 极不可能被使用的端口。少数服务如 chargen 会响 应一个空的 UDP 报文, 从而向 Nmap 表明该机器正在运行。

该扫描类型的主要优势是它可以穿越只过滤 TCP 的防火墙和过滤器。 例如。我曾经有过 一个 Linksys BEFW11S4 无线宽带路由器。默认情况下, 该设备对外的网卡过滤所有 TCP 端口,但 UDP 探测仍然会引发一个端口不可到达 的消息,从而暴露了它自己。

-PE; -PP; -PM (ICMP Ping Types)

除了前面讨论的这些不常见的 TCP 和 UDP 主机发现类型 Nmap 也能发送世人皆知的 ping 程序所发送的报文。Nmap 发送一个 ICMP type 8 (回声请求)报文到目标 IP 地址, 期待 从运行的主机得到一个 type 0 (回声响应)报文。 对于网络探索者而言,不幸的是,许 多主机和 防火墙现在封锁这些报文,而不是按期望的那样响应, 参见 RFC 1122。因此

仅仅 ICMP 扫描对于互联网上的目标通常是不够的。 但对于系统管理员监视一个内部网 络,它们可能是实际有效的途径。 使用-PE 选项打开该回声请求功能。

虽然回声请求是标准的 ICMP ping 查询, Nmap 并不止于此。ICMP 标准 (RFC 792)还规 范了时间戳请求,信息请求 request,和地址掩码请求,它们的代码分别是 13,15 和 17 虽然这些查询的表面目的是获取信息如地址掩码和当前时间, 它们也可以很容易地用于 主机发现。 很简单,回应的系统就是在运行的系统。Nmap 目前没有实现信息请求报文 因为它们还没有被广泛支持。RFC 1122 坚持 “主机不应该实现这些消息”。 时间戳和 地址掩码查询可以分别用-PP 和-PM 选项发送。 时间戳响应(ICMP 代码 14)或者地址掩码 响应(代码 18)表示主机在运行。 当管理员特别封锁了回声请求报文而忘了其它 ICMP 查 询可能用于 相同目的时,这两个查询可能很有价值。

-PR (ARP Ping)

最常见的 Nmap 使用场景之一是扫描一个以太局域网。 在大部分局域网上,特别是那些 使用基于 RFC1918 私有地址范围的网络,在一个给定的时间绝大部分 IP 地址都是不使 用的。 当 Nmap 试图发送一个原始 IP 报文如 ICMP 回声请求时, 操作系统必须确定对应 于目标 IP 的硬件 地址(ARP),这样它才能把以太帧送往正确的地址。 这一般比较慢而 且会有些问题,因为操作系统设计者认为一般不会在短时间内 对没有运行的机器作几百 万次的 ARP 请求。

当进行 ARP 扫描时,Nmap 用它优化的算法管理 ARP 请求。 当它收到响应时, Nmap 甚至 不需要担心基于 IP 的 ping 报文,既然它已经知道该主机正在运行了。 这使得 ARP 扫描 比基于 IP 的扫描更快更可靠。 所以默认情况下,如果 Nmap 发现目标主机就在它所在的 局域网上,它会进行 ARP 扫描。 即使指定了不同的 ping 类型(如 -PI 或者 -PS) ,Nmap 也会对任何相同局域网上的目标机使用 ARP。 如果您真的不想要 ARP 扫描,指定 --send-ip

-n (不用域名解析)

告诉 Nmap 永不对它发现的活动 IP 地址进行反向域名解析。 既然 DNS 一般比较慢,这可 以让事情更快些。

-R (为所有目标解析域名)

告诉 Nmap 永远 对目标 IP 地址作反向域名解析。 一般只有当发现机器正在运行时才进 行这项操作。

--system_dns (使用系统域名解析器)

默认情况下,Nmap 通过直接发送查询到您的主机上配置的域名服务器 来解析域名。为了 提高性能,许多请求 (一般几十个 ) 并发执行。如果您希望使用系统自带的解析器,就 指定该选项 (通过 getnameinfo()调用一次解析一个 IP) 除非 Nmap 的 DNS 代码有 bug-- 如果是这样,请联系我们。 一般不使用该选项,因为它慢多了。系统解析器总是用于 IPv6 扫描。