我发现了windows的tracert命令的一个bug---ICMP重定向包详尽分析

hi朋友,如果你的好奇心没有因繁杂的生活而被消磨,如果你喜欢对计算机进行追根究底的研究,那么欢迎与我一起,进行一趟说走就走的ICMP协议底层之旅。

先把ICMP包结构贴在这里:

我们研究的是差错报告报文的类型5,也就是ICMP"重定向"报文,它有2个作用:对网络重定向,对主机重定向。

要理解这个报文的作用,先画出一张拓扑图:

实验是PC1 ping PC3,由于PC1的默认网关是路由器R1的f0/0口,所以数据包的流向是:PC1→R1→R6→PC3。

但很明显,R1的转发多此一举,PC1把数据包直接发给路由器R6的f0/0口即可。

所以R1会给PC1发出一个ICMP错误报文,本例是type=5,code=0,意为网络重定向,即告诉PC1:去往192.168.7.0/24这个网络(路由器有路由表),网关应该是192.168.0.4,wireshark抓包如下:

PC1收到后会更新路由表,下一跳指向192.168.0.4的MAC地址,数据包转由R6转发。

那么接下来就做实验。先运行wf.msc关闭防火墙,因为防火墙会禁用ICMP重定向包以防止中间人攻击风险。

用tracert命令跟踪数据包的路径,这是2次运行tracert命令的结果:

tracert命令的原理是,发出ICMP的ping包(type=8,code=0),但初始ttl=1,之后每次累加1,直到目的地。这样一来,途径的每个路由器将TTL-1,如果为0,就会向PC1发回"TTL过期"错误包(type=5,code=0),这样tracert命令就探测出了途径的所有路由器和主机。

分析上图。用wiershark抓包可以发现,第一次运行tracert命令,R1会向PC1返回ICMP重定向包(type=5,code=0),但随后仍然会继续转发此包,也就是说第一次ping能够到达目的地,但并非最优路径。

第二次运行tracert命令,由于之前收到了ICMP重定向包,所以修改了路由表,ping包的第一跳就是R6,随后到达目的地。

但我们只关注第一次运行tracert命令的结果。你发现了没有,路径是不对的,正确的应该是R2(192.168.0.1)→R6(192.168.0.4)→PC3(192.168.7.2)才对,可显示的结果缺失了中间的R6(192.168.0.4)。

一开始我也是百思不得其解,但仔细观察wireshark的抓包结果之后,终于知道了问题根源所在。

原来,tracert命令发出的第一个ping包的TTL=1,那么第二个ping包就应该是TTL=2,第三个ping包应该是TTL=3。。。

可这种累加策略却忽略了ICMP重定向包造成的"干扰",所以当第二个ping包的下一跳转向R6时,携带的TTL=2。

当数据包到达R6,会将TTL-1=1,由于并非为0,所以R6不会向PC1返回TTL过期的ICMP错误包,tracert命令也就探测不到R6的存在了。

这。。。算是tracert命令的一个bug吧。正确的方法是当路由表被ICMP重定向包修改,发出的第一个ping包的TTL应该被置为1。

对此,GNS3的VPCS虚拟设备就做得很好,清楚地显示了路径的修改过程:

另外,被ICMP重定向包修改的路由表是看不到的,因为Windows 在处理 ICMP Redirect 时,不会在永久或显示的路由表中增加一条可见路由项。被重定向的路由是**内核临时缓存(transient route)**中的一部分,只在内存中生效,不会显示在 route print 或 netstat -r 里。这个缓存属于 TCP/IP 协议栈内部(Route Cache 或 Neighbor Cache),更新仅在该目标主机或子网通信时生效,不会写入持久路由表。

但也有显示的方法------显示缓存表:

netsh interface ipv4 show destinationcache

还有资料提到另一种写法,记录于此:

netsh interface ipv4 show global

相关推荐
0白露6 小时前
关闭搜狗输入法右下角广告,可以适用于大多数应用系统通知的广告
windows·bug
一只自律的鸡19 小时前
【Linux驱动】bug处理 ens33找不到IP
linux·运维·bug
Lichenpar2 天前
Springboot采用FastJson2作为MessageConverter时,配置的全局日期类型序列化转换BUG
java·开发语言·bug
Irene19913 天前
AI 找 bug 的局限性 和 Deepseek 优势明显
bug
癫狂的兔子3 天前
【bug】【Python】pandas中的DataFrame.to_excel()和ExcelWriter的区别
python·bug
癫狂的兔子4 天前
【BUG】【Python】【Spider】Compound class names are not allowed.
开发语言·python·bug
netkiller-BG7NYT4 天前
阿里云语音合成CosyVoice重大BUG被我发现了
bug
马猴烧酒.5 天前
【Mybatis出现bug】应为 <statement> 或 DELIMITER,得到 ‘id‘
java·bug·mybatis
请叫我大虾5 天前
发现一个jdk中ArrayList的小BUG
android·java·bug
离离茶5 天前
【笔记1-10】Qt bug记录:dockwidget通过raise在最前面显示,toolbar的拓展菜单失效
笔记·qt·bug