公众号旧文

为什么 IP 能 ping 通,但设备却并不存在?

作者:胖子阅读 —

相信很多人都和之前的我一样,认为:

只要能 ping 通,就说明 IP 对应的网络设备在线。

但实际上,这件事不一定成立。

有时,那台网络设备甚至根本就不存在。

今天,让我们一起来做一个离谱的实验。

这个实验,会彻底颠覆很多人对能 ping 通和网络设备在线的理解。

一、ping 在验证什么?

能 ping 通,就意味着对面的网络设备在线,这已经是共识。

但严格来说,ping 只能证明有 ICMP Echo Reply 返回了。

也就是说,你发出了一个 ICMP Echo Request(回显请求)。

随后,有人给你回了一个 Echo Reply(回显响应)。

仅此而已。

但问题在于,你并不能确定这个 Reply,一定是目标机器自己发出来的。

二、一台不存在的网络设备

实验非常简单,一台 Windows,和运行在 Windows 上的 WSL。

WSL(Windows Subsystem for Linux)是微软推出的一个功能,允许在 Windows 10/11 上原生运行 Linux 二进制可执行文件,无需虚拟机或双启动。

我先在 WSL 里写了一个 Python 脚本。

作用是监听网络中的 ICMP 请求。

只要通过 WSL 去 ping 某些 IP,脚本就伪造一个 Echo Reply 发回去。

核心逻辑如下:

  • 收到 Echo Request
  • 读取源 IP 和目标 IP
  • 构造假的 Echo Reply
  • 把 Reply 发回去

于是,即使目标 IP 根本不存在。

Windows 也会认为对面的网络设备在线。

三、Windows上的对应设置

Windows 默认不会把数据发给 WSL。

于是我又增加了一条静态路由:

route add 192.168.50.0 mask 255.255.255.0 172.31.170.208

这条命令的意思是,凡是从 Windows 发往:

192.168.50.0/24

的数据。

全部交给:

172.31.170.208

也就是 WSL 来转发(172.31.170.208 是 WSL 的 IP)。

从这时起,Windows 会认为整个 192.168.50.0/24,都在 WSL 后面。

四、见证奇迹的时刻

在 Windows 上 ping 一个根本不存在的 IP:

ping 192.168.50.0

结果:

C:\Users\Desktop> ping 192.168.50.0

正在 Ping 192.168.50.0 具有 32 字节的数据:
来自 192.168.50.0 的回复: 字节=32 时间=50ms TTL=64
来自 192.168.50.0 的回复: 字节=32 时间=25ms TTL=64
来自 192.168.50.0 的回复: 字节=32 时间=25ms TTL=64
来自 192.168.50.0 的回复: 字节=32 时间=13ms TTL=64

192.168.50.0 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 13ms,最长 = 50ms,平均 = 28ms

居然真的通了。

而且 TTL、延迟、返回值,看起来完全正常。

甚至还可以批量 ping 整个 /24 网段。

结果是:

C:\Users\Desktop\pp.ps1
ping 192.168.50.0   stabled   ttl=64,64,64,64      time=70,25,32,25
ping 192.168.50.1   stabled   ttl=64,64,64,64      time=29,24,25,24
ping 192.168.50.2   stabled   ttl=64,64,64,64      time=24,32,25,20
ping 192.168.50.3   stabled   ttl=64,64,64,64      time=41,29,29,42
ping 192.168.50.4   stabled   ttl=64,64,64,64      time=32,24,37,38
...
ping 192.168.50.251 stabled   ttl=64,64,64,64      time=25,24,25,26
ping 192.168.50.252 stabled   ttl=64,64,64,64      time=23,18,27,13
ping 192.168.50.253 stabled   ttl=64,64,64,64      time=22,27,35,14
ping 192.168.50.254 stabled   ttl=64,64,64,64      time=36,35,34,25
ping 192.168.50.255 stabled   ttl=64,64,64,64      time=24,19,32,12

看上去整个 /24 都在线。

但实际上,这 256 个 IP 后面根本就没有机器。

真正回应这些 ping 的,是 WSL 里的那个 Python 脚本。

五、用 ping 来做在线检测

大部分人,在做网络探测时,都会习惯性地 ping 一下。

看到通了,就认为目标 IP 对应的设备在线。

但今天的实验说明,ICMP 是可以被代答的。

只要能控制路由,能截获 ICMP,就能伪造 Reply

六、互联网里,在线是一种幻觉

事实上,在网络世界里,有很多东西都只是看起来存在。

比如:

  • 能建立 TCP,不一定真有业务
  • 能打开网页,不一定是真实源站
  • traceroute 看到的路径,也未必是真实路径
  • ping 通,也不一定真有机器

互联网很多时候并不真实。

最后分享一下 Python 脚本,感兴趣的读者可以自行尝试:

from scapy.all import *

def handle(pkt):
    if IP in pkt and ICMP in pkt:
        if pkt[ICMP].type == 8:  # Echo Request
            src = pkt[IP].src
            dst = pkt[IP].dst

            print(f"[+] Ping {dst} from {src}")

            reply = IP(src=dst, dst=src) / ICMP(
                type=0,
                id=pkt[ICMP].id,
                seq=pkt[ICMP].seq
            )

            if Raw in pkt:
                reply = reply / pkt[Raw].load

            send(reply, verbose=0)

sniff(filter="icmp", prn=handle)