允许通过 VPN 隧道建立的 TCP 连接被劫持的漏洞

已发表 一种攻击技术 (CVE-2019-14899),允许在通过 VPN 隧道转发的 TCP 连接中欺骗、修改或替换数据包。 该问题影响 Linux、FreeBSD、OpenBSD、Android、macOS、iOS 和其他类 Unix 系统。 Linux 支持 IPv4 的 rp_filter(反向路径过滤)机制,在“严格”模式下打开它可以解决这个问题。

该方法允许在加密隧道内传递的 TCP 连接级别进行数据包替换,但不允许插入使用其他加密层(例如 TLS、HTTPS、SSH)的连接。 VPN 中使用的加密算法并不重要,因为欺骗数据包来自外部接口,并由内核作为来自 VPN 接口的数据包进行处理。 最有可能的攻击目标是干扰未加密的 HTTP 连接,但是 不排除 并使用攻击来操纵 DNS 响应。

使用 OpenVPN、WireGuard 和 IKEv2/IPSec 创建的隧道已证明成功的数据包欺骗。Tor 不易受到该问题的影响,因为它使用 SOCKS 转发流量并绑定到环回接口。 对于 IPv4,如果 rp_filter 设置为“宽松”模式 (sysctl net.ipv4.conf.all.rp_filter = 2),则可能会发生攻击。 最初,大多数系统都使用“严格”模式,但从 systemd 240去年XNUMX月发布的版本中,默认操作模式更改为“Loose”,这一变化反映在许多Linux发行版的默认设置中。

rp_filter机制 申请 用于对数据包路径进行额外验证,以防止源地址欺骗。 当设置为 0 时,不执行源地址检查,任何数据包都可以在网络接口之间转发,不受限制。 模式1“严格”包括检查来自外部的每个数据包是否符合路由表,如果接收数据包的网络接口与最佳响应传递路由不相关,则丢弃该数据包。 模式 2“宽松”放宽了检查,以允许负载均衡器或非对称路由在以下情况下工作:
响应路由可能会经过与传入数据包到达所经过的网络接口不同的网络接口。

在松散模式下,将根据路由表检查传入数据包,但如果可以通过任何可用网络接口访问源地址,则认为该数据包有效。 所提出的攻击基于以下事实:攻击者可以发送具有与 VPN 接口相对应的欺骗源地址的数据包,尽管该数据包将通过外部网络接口而不是通过 VPN 进入系统,但在rp_filter “宽松”模式这样的数据包不会被丢弃。

要进行攻击,攻击者必须控制用户访问网络的网关(例如,通过 MITM 组织,当受害者连接到攻击者控制的无线接入点时,或者通过 路由器黑客攻击)。 通过控制用户连接到网络的网关,攻击者可以发送伪造的数据包,这些数据包将在 VPN 网络接口的上下文中被感知,但响应将通过隧道进行路由。

通过生成虚拟数据包流(其中替换 VPN 接口的 IP 地址),尝试影响客户端建立的连接,但这些数据包的影响只能通过对关联的加密流量进行被动分析来观察随着隧道的运营。 要进行攻击,您需要找出 VPN 服务器分配的隧道网络接口的 IP 地址,并确定当前通过隧道与特定主机的连接处于活动状态。

为了确定VPN虚拟网络接口的IP,SYN-ACK数据包被发送到受害系统,依次枚举整个虚拟地址范围(首先默认枚举VPN中使用的地址,例如OpenVPN使用 10.8.0.0/24 子网)。 可以根据收到带有RST标志的响应来判断地址的存在。

类似地,确定是否存在与某个站点的连接以及客户端的端口号 - 通过对端口号进行排序,向用户发送 SYN 数据包,作为源地址,其中该站点的IP被替换,目的地址是虚拟IP VPN。 可以预测服务器端口(HTTP 为 80),并且可以通过暴力计算客户端的端口号,结合不同端口号结合 RST 数据包的缺失来分析 ACK 响应强度的变化旗帜。

在此阶段,攻击者知道连接的所有四个元素(源 IP 地址/端口和目标 IP 地址/端口),但为了生成受害者系统将接受的虚构数据包,攻击者必须确定 TCP 序列和确认号(seq 和 ack)- 连接。 为了确定这些参数,攻击者不断发送伪造的 RST 数据包,尝试不同的序列号,直到检测到 ACK 响应数据包,该响应数据包的到来表明该数字落在 TCP 窗口内。

接下来,攻击者通过发送相同编号的数据包并观察 ACK 响应的到达来澄清定义的正确性,然后选择当前序列的确切编号。 由于响应是在加密隧道内发送的,并且它们在截获的流量流中的存在只能使用间接方法进行分析,因此该任务变得复杂。 客户端是否发送寻址到 VPN 服务器的 ACK 数据包是根据加密响应的大小和延迟来确定的,这与欺骗数据包的发送相关。 例如,对于OpenVPN,加密数据包大小为79,可以准确判断其中包含ACK。

直到将攻击防护添加到操作系统内核中作为阻止问题的临时方法 建议 在“预路由”链中使用数据包过滤器,阻止将隧道的虚拟 IP 地址指定为目标地址的数据包通过。

iptables -t raw -I 预路由! -i wg0 -d 10.182.12.8 -m 地址类型! --src-类型本地-j 删除

或者对于 nftables

nft 添加表 ip raw
nft add chain ip raw prerouting '{ type filter hook 预路由优先级 0; }'
nft 添加规则 ip raw 预路由 'iifname != "wg0" ip baddr 10.182.12.8 fib Saddr type != local drop'

为了在使用带有 IPv4 地址的隧道时保护自己,只需将 rp_filter 设置为“严格”模式(“sysctl net.ipv4.conf.all.rp_filter = 1”)。 在VPN端,可以通过在加密数据包中添加额外的填充来阻止序列号检测方法,使所有数据包大小相同。

来源: opennet.ru

添加评论