如果有问题的NAT设备重写出站ICMP数据包,ICMP NAT遍历应如何工作?
=========================================================================================
| CLIENT | <---> | NAT-C | <---> { internet } <---> | NAT-S | <---> | SERVER |
=========================================================================================
19.19.19.19 (external addresses) 72.72.72.72
192.168.0.2 192.168.0.1 (internal addresses) 172.16.0.1 172.16.0.2
SERVER
将ICMP Echo Request数据包(ping)发送到其他主机(例如3.3.3.3
)以在NAT-S
中打开一个漏洞。当CLIENT
想要连接时,它会向NAT-S
发送一个ICMP Time Exceeded数据包,该数据包应该被路由到SERVER
。为了使所述路由起作用,CLIENT
通过在其中嵌入预期3.3.3.3
首先发送的相同数据包(ICMP Echo to SERVER
)来构建ICMP Time Exceeded数据包。 / p>
如果CLIENT
需要在其ICMP Time Exceeded回复中嵌入与NAT-S
相同的(ICMP Echo Request)数据包,则必须知道数据包的查询ID。 但它如何知道此查询ID?
根据RFC 3022 Section 2.2,当NAT-S
遇到出站ICMP Echo请求时,它会将数据包的查询ID字段重写为唯一的外部查询ID,以便它可以将具有相同查询ID的未来ICMP Echo回复路由到SERVER
。
鉴于上述问题,似乎pwnat
和ICMP打孔背后的前提是无效的,它永远不会起作用。我在这里错过了什么吗?
提前致谢:)
答案 0 :(得分:3)
您对查询ID是正确的。
pwnat
现在很少有用。几年前我碰巧知道这件令人讨厌的事情,并对这个想法感兴趣。我已经阅读了pwnat的源代码,并在Go中自己重新实现了它。只有简单地址转换的基本NAT设备(rfc 1631描述)才能使用它,任何具有强大NAPT实现功能的NAPT设备都无法做到。
除了标识符问题,(顺便说一下,pwnat的source code使用0作为原始请求的标识符)pwnat没有给出原始ip头的正确校验和,这可能导致NAT-S丢弃TTL超出消息(如果数据包可以到达那里) 根据{{3}},
更严重当NAT设备从私有领域接收到ICMP错误数据包时,NAT设备使用嵌入在ICMP错误消息中的数据包(即,从客户端到服务器的IP数据包)来查找NAT会话嵌入式数据包属于。如果NAT设备没有嵌入数据包的活动映射,NAT应该静默地丢弃ICMP错误数据包。
这意味着来自客户端的ICMP Time Exceeded数据包不会通过NAT-C。 rfc 5508确实提到了这种情况并推荐了其他解决方案。