Linux 内核的 XFRM 框架负责 IPsec 变换,其中 ESP 的 BEET(Bound End-to-End Tunnel)模式在解密 IPsec 包后,会重构内部 IP 头。然而,在某些内核路径中,用于构造新 IP 头的 skb 区域未被完全初始化为零,导致内核堆中残留的指针或数据碎片被嵌入数据包并返回给远端用户。攻击者可从互联网发送特制的空载荷 ESP 包,在解密后的响应中泄露堆上的内核基址、堆地址甚至密钥材料,从而彻底击溃 KASLR 并为后续内核利用铺路。
BEET 模式
IPsec ESP 隧道
IPsec ESP 支持两种经典模式:传输模式仅加密传输层以上内容,保留原始 IP 头;隧道模式则加密整个原始 IP 数据包,并添加新的外部 IP 头。BEET 模式是两者的混合:它使用外部 IP 头进行路由,但内部 IP 头在解密后被重新计算,并以最小开销嵌入外部 IP 头之后。这种模式常用于移动 IPv6 和端到端加密场景。
其核心特性对比可以参考以下表:
维度
传输模式
隧道模式
BEET 模式
IP 标头数量
1 个(原始 IP)
2 个(新 IP + 旧 IP)
1 个(映射后的新 IP)
数据额外开销 (Overhead)
极小(无额外 IP 头)
较大(多出 20/40 字节新 IP 头)
极小(等同于传输模式)
主要应用场景
主机到主机(Host-to-Host)
网关到网关(Site-to-Site VPN)
端到端移动性、NAT 优化
隐藏内网 IP
否(暴露原始 IP 标头)
是(加密原始 IP 标头)
是(通过地址绑定隐藏真实端点)
在 Linux 内核中,BEET 的处理由 net/xfrm/xfrm_input.c 和协议相关的 ESP 处理函数完成。当收到一个 BEET 模式的 ESP 包时,解密后内核需要构造一个新的内部 IP 头,其源和目标地址来自 SA(安全关联)的模板,而非原始数据包。这一重建过程对 skb 的操作非常精细,容易出现未初始化内存问题。