An attack technique (CVE-2019-14899) allows for the substitution, modification, or insertion of packets in TCP connections routed through VPN tunnels. This issue affects Linux, FreeBSD, OpenBSD, Android, macOS, iOS, and other Unix-like systems. Linux supports the rp_filter (reverse path filtering) mechanism for IPv4, enabling its "Strict" mode neutralizes this problem.
The method allows for packet substitution at the level of TCP connections passing through an encrypted tunnel, but does not allow for interference in connections that utilize additional encryption layers (e.g., TLS, HTTPS, SSH). The encryption algorithms used in the VPN do not matter, as forged packets arrive from the external interface and are processed by the kernel as packets from the VPN interface. The most likely target of the attack is intervention in unencrypted HTTP connections, but the use of the attack to manipulate DNS responses.
Successful packet substitution has been demonstrated for tunnels created using OpenVPN, WireGuard, and IKEv2/IPSec. Tor is not susceptible to this issue, as it uses SOCKS for traffic forwarding and binds to the loopback interface. For IPv4, the attack is possible if rp_filter is switched to "Loose" mode (sysctl net.ipv4.conf.all.rp_filter = 2). Initially, the "Strict" mode was used in most systems, but starting with , released in December last year, the default operation mode was changed to "Loose", and this change has been reflected in the default settings of many Linux distributions.
The rp_filter mechanism provides additional path checking for packets to prevent source address spoofing. When set to 0, source address checking is not performed, and any packet can be freely redirected between network interfaces. Mode 1 "Strict" enables checking of each incoming packet from outside against the routing table, and if the network interface through which the packet was received is not associated with the optimal response delivery route, the packet is dropped. Mode 2 "Loose" relaxes the check to allow operation with load balancers or asymmetric routing, where
the response route may not go through the same network interface from which the incoming packet arrived.
In 'Loose' mode, incoming packets are checked against the routing table but are considered valid if the source address is reachable through any available network interface. The proposed attack is based on the assumption that the attacker can send a packet with a spoofed source address matching the VPN interface, and despite the fact that this packet will enter the system through the external network interface rather than through the VPN, in 'Loose' rp_filter mode, such a packet will not be dropped.
To carry out the attack, the attacker must control the gateway through which the user accesses the network (for example, through a MITM attack, connecting the victim to a wireless access point controlled by the attacker or through ). By controlling the gateway used by the user to connect to the network, the attacker can send bogus packets that will be perceived in the context of the VPN network interface, but responses will be directed through the tunnel.
By generating a stream of bogus packets with the VPN interface's IP address, 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 associated with the tunnel operation. To conduct the attack, it is necessary to know the IP address assigned by the VPN server to the tunnel's network interface and to determine that there is currently an active connection through the tunnel to a specific host.
To determine the IP of the virtual VPN network interface, SYN-ACK packets are sent to the victim's system, systematically scanning the entire range of virtual addresses (first, the addresses used by default in VPNs, for example, OpenVPN uses the subnet 10.8.0.0/24). The existence of an address can be inferred based on the receipt of a response with the RST flag.
Similarly, the connection to a specific site and the port number on the client side is determined — by iterating through port numbers towards the user, a SYN packet is sent with the site's IP as the source address and the virtual IP of the VPN as the destination address. The server port can be predicted (80 for HTTP), while the port number on the client side can be calculated by enumeration, analyzing the changes in the intensity of ACK responses in conjunction with the absence of a packet with the RST flag.
At this stage, the attacker knows all four elements of the connection (source IP address/port and destination IP address/port), but in order to generate a spoofed packet that the victim's system will perceive, the attacker must determine the sequence and acknowledgment numbers (seq and ack) of the TCP connection. To identify these parameters, the attacker continuously sends fake RST packets, iterating through different sequence numbers until an ACK packet response is recorded, indicating that the number falls within the TCP window.
Next, the attacker verifies the correctness by sending packets with the same number and observing the incoming ACK responses, after which the exact current sequence number is determined. The task is complicated by the fact that responses are sent within an encrypted tunnel, and their presence in the intercepted traffic stream can only be analyzed indirectly. The fact that an ACK packet addressed to the VPN server is sent by the client is determined based on the size and delay of the encrypted responses, which correlate with the sending of spoofed packets. For example, for OpenVPN, an encrypted packet of size 79 reliably indicates that it contains an ACK acknowledgment.
Before attack protection is added to the operating system kernel, as a temporary method to block the problem, using a packet filter in the 'preroute' chain to block the passage of packets where the destination address is specified as the virtual IP address of the tunnel.
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'
To protect when using tunnels with IPv4 addresses, it is sufficient to set rp_filter to 'Strict' ('sysctl net.ipv4.conf.all.rp_filter = 1'). From the VPN side, the method of determining the sequence number can be blocked by adding padding to the encrypted packets, making the size of all packets the same.
Source: opennet.ru
