Vulnerability that allows wedging into TCP connections made through VPN tunnels

Published attack technique (CVE-2019-14899) that allows you to replace, change or substitute packets in TCP connections forwarded through VPN tunnels. The issue affects Linux, FreeBSD, OpenBSD, Android, macOS, iOS, and other Unix-like systems. Linux supports the rp_filter (reverse path filtering) mechanism for IPv4, setting it to "Strict" mode neutralizes this problem.

The method allows packet substitution at the level of TCP connections passing inside an encrypted tunnel, but does not allow wedging into connections that use additional layers of encryption (for example, TLS, HTTPS, SSH). The encryption algorithms used in the VPN are irrelevant because the spoofed packets come from the outside interface and are treated by the kernel as packets from the VPN interface. The most likely target of the attack is to interfere with unencrypted HTTP connections, but not excluded and using an attack to manipulate DNS responses.

Successful packet spoofing has been demonstrated for tunnels created using OpenVPN, WireGuard and IKEv2/IPSec. Tor is not affected by the problem, as it uses SOCKS to forward traffic and bind to the loopback interface. For IPv4, an attack is possible if rp_filter is set to "Loose" mode (sysctl net.ipv4.conf.all.rp_filter = 2). Initially, most systems used the "Strict" mode, but starting from systemd 240, released last December, the default mode of operation was changed to "Loose" and this change is reflected in the default settings of many Linux distributions.

rp_filter mechanism applies to additionally check packet paths to prevent source address spoofing. When set to 0, source address verification is not performed and any packet can be forwarded between network interfaces without restrictions. Mode 1 "Strict" includes checking each incoming packet against the routing table, and if the network interface through which the packet was received is not associated with the optimal response delivery route, then the packet is discarded. Mode 2 "Loose" softens the check to allow operation when using load balancers or asymmetric routing, in which
the response path may not go through the same network interface through which the incoming packet arrived.

In Loose mode, an incoming packet is checked against the routing table, but considered valid if the source address is reachable through any available network interface. The proposed attack is based on the fact that an attacker can send a packet with a spoofed source address corresponding to the VPN interface, and despite the fact that this packet enters the system through an external network interface, and not through the VPN, in the rp_filter "Loose" mode, such a packet will not be dropped.

To carry out an attack, an attacker must control the gateway through which the user accesses the network (for example, through the MITM organization, when the victim connects to an attacker-controlled wireless access point, or through router hack). By controlling the gateway through which the user is connected to the network, the attacker can send dummy packets that will be understood in the context of the VPN network interface, but the responses will be sent through the tunnel.

By generating a stream of dummy packets in which the IP address of the VPN interface is substituted, attempts are made to influence the connection established by the client, but the effect of these packets can only be observed through passive analysis of the encrypted traffic flow associated with the operation of the tunnel. To carry out an attack, it is necessary to find out the IP address of the network interface of the tunnel assigned by the VPN server, and also to determine that a connection to a specific host is currently active through the tunnel.

To determine the IP of the VPN virtual network interface, sending SYN-ACK packets to the victim system is used, sequentially sorting through the entire range of virtual addresses (first of all, the addresses used in VPN by default are sorted out, for example, OpenVPN uses the 10.8.0.0/24 subnet). The existence of the address can be judged based on the receipt of a response with the RST flag.

Similarly, the presence of a connection to a specific site and the port number on the client side are determined - sorting through the port numbers, a SYN packet is sent to the user as the source address, in which the site IP is substituted, and the destination address is the VPN virtual IP. The server port can be predicted (80 for HTTP), and the port number on the client side can be brute-forced, analyzing for different numbers the change in the intensity of ACK responses in combination with the absence of a packet with the RST flag.

At this stage, the attacker knows all four elements of the connection (the source IP address/port and the destination IP address/port), but in order to generate a dummy packet that the victim's system will accept, the attacker must determine the sequence and acknowledgment numbers (seq and ack) of the TCP connection. To determine these parameters, the attacker continuously sends fake RST packets, trying out different sequence numbers, until it captures an ACK response packet, the arrival of which indicates that the number falls within the TCP window.

Next, the attacker clarifies the correctness of the determination by sending packets with the same number and observing the arrival of ACK responses, after which he selects the exact number of the current sequence. The task is complicated by the fact that responses are sent inside an encrypted tunnel and their presence in the intercepted traffic flow can only be analyzed by indirect methods. Whether a client sent an ACK packet addressed to the VPN server is determined based on the size and latency of the encrypted responses, which correlate with the sending of spoofed packets. For example, for OpenVPN, an encrypted packet with a size of 79 allows you to accurately judge that an ACK acknowledgment is contained inside.

Before attack protection is added to the kernel of the operating system, as a temporary method of blocking the problem recommended using a packet filter in the "preroute" chain, block the passage of packets in which the virtual IP address of the tunnel is specified as the destination address.

iptables -t raw -I PREROUTING ! -i wg0 -d 10.182.12.8 -m addrtype ! --src-type LOCAL -j DROP

or for nftables

nft add table ip raw
nft add chain ip raw prerouting '{ type filter hook prerouting priority 0; }'
nft add rule ip raw prerouting 'iifname != "wg0" ip daddr 10.182.12.8 fib saddr type != local drop'

For protection when using tunnels with IPv4 addresses, it is enough to set rp_filter to "Strict" mode ("sysctl net.ipv4.conf.all.rp_filter = 1"). From the VPN side, the method of determining the sequence number can be blocked by adding extra padding to the encrypted packets, making the size of all packets the same.

Source: opennet.ru

Add a comment