公众号旧文
为什么 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)