ICMP 重定向攻击实验
完成条件
由于网络环境经常变化,路由器需要不断交换信息以确保其路由表中的信息是最新的。主机并不参与路由协议,那么如果它们的路由信息变得过时了会发生什么?让我们看看下图中的情况。

图中的两个路由器 R1 和 R2 在同一个网络上。主机 H 需要向目标 T 发送一个数据包。根据 H 的路由表,该数据包应该发送给 R1。然而R1刚刚更新了其路由表,现在最佳路径是通过 R2 到达 T 。因此,R1 将把数据包转发给 R2。但是由于 H 和 R2 在同一网络上,H 可以直接将数据包发给 R2,而不是绕路经过 R1,这是由于主机上的路由信息过时导致的。为了节约网络带宽,R1 有责任告诉H其路由条目已经过时,并需要更新。这会通过 ICMP 重定向消息来实现。
ICMP 重定向是路由器向发送IP数据包的主机发送的错误消息。当路由器认为数据包被错误地路由时,它会通知发送方应该使用另外的路由器。
ICMP 重定向的实际应用:我们回到实验设置中的机器 10.9.0.5(参见下图)。在该机器上,默认路由器是 10.9.0.1。因此,如果我们发送一个数据包到 1.1.1.1,它将被发送给默认路由器。我们可以使用以下方法将默认路由器改为 10.9.0.11:

// 在 10.9.0.5
# ip route change default via 10.9.0.11
# ip route
default via 10.9.0.11 dev eth0
10.9.0.0/24 dev eth0 proto kernel scope link src 10.9.0.5
192.168.60.0/24 via 10.9.0.11 dev eth0
在 10.9.0.11 上,发往 1.1.1.1 的数据包也将使用默认路由条目,也是 10.9.0.1。请参见以下内容:
// 在 10.9.0.11
# ip route
default via 10.9.0.1 dev eth0
10.9.0.0/24 dev eth0 proto kernel scope link src 10.9.0.11
192.168.60.0/24 dev eth1 proto kernel scope link src 192.168.60.11
我们从 10.9.0.5 向 1.1.1.1 发送一个 ping 消息。我们可以看到,该数据包被发送到路由器 10.9.0.11。该路由器立即意识到问题,此数据包的下一站路由是 10.9.0.1,但发送方与那个路由器其实是直接相连的,因此这是绕道,需要纠正发送方。因此,该路由器向发送方发送了几条 ICMP 重定向消息,通知它更新路由信息。
// 在 10.9.0.5 上
# ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
From 10.9.0.11: icmp_seq=2 Redirect Host(New nexthop: 10.9.0.1)
From 10.9.0.11: icmp_seq=3 Redirect Host(New nexthop: 10.9.0.1)
从下面的结果中我们可以看到,发送方确实更改了路由信息,但不是在路由表上。只有两个缓存条目被添加。在这些缓存条目过期之前,如果我们再向 1.1.1.1 发送一个 ping 消息,这次该数据包直接到达 10.9.0.1。
// 在 10.9.0.5 上
# ip route
default via 10.9.0.11 dev eth0
10.9.0.0/24 dev eth0 proto kernel scope link src 10.9.0.5
192.168.60.0/24 via 10.9.0.11 dev eth0
# ip route show cache
1.1.1.1 via 10.9.0.1 dev eth0
cache <redirected> expires 263sec
1.1.1.1 via 10.9.0.1 dev eth0
cache <redirected> expires 263sec
# ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=54 time=24.6 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=54 time=28.2 ms
如果我们想重复这个实验,可以等待缓存超时或使用 "ip route flush cache" 清除缓存。
注意事项:需要注意的是,在 Ubuntu 20.04 中,默认情况下,主机不会接受 ICMP 重定向消息,因为 ICMP 重定向可用于攻击(我们将在下文讨论此攻击)。此行为由系统变量决定(见下文)。默认情况下,它设置为 0,即不接受 ICMP 重定向消息。在我们的容器设置中,我们已经将 10.9.0.5 的参数设置为 1:
# sysctl net.ipv4.conf.all.accept_redirects
net.ipv4.conf.all.accept_redirects = 0
最后修改: 2025年09月8日 星期一 15:58