Vulnerability record CVE-2019-14899
The vulnerability record CVE-2019-14899 describes a general flaw in the way how many Linux based operating systems handle inbound network packets. This vulnerability affects all networking activity on those operating systems, including VPNs and it could under some circumstances be exploited to remove some of the protection that VPNs provide.
Hosts maintain a so called "routing table" that keeps track of which address ranges belong to certain network interfaces and which is used to decide where to send outbound packets. In the case of VpnCloud, that table could include the entry associating the range
10.0.0.0/24 with the interface
vpncloud0 which means that packets with a destination address in that range are sent via the VpnCloud interface.
The routing table entries are also used to filter inbound packets and drop those that arrive via an interface that is not associated with their source address. This filtering is called "reverse path filtering" and defined in RFC 3074. The Linux kernel can enforce this filtering using the "rp_filter" configuration value which can work in 3 modes:
- No filtering (value
0): No validation is performed
- Strict mode (value
1): In strict mode, all inbound packets arriving on an interface that is not associated with their source address are dropped.
- Loose mode (value
2): In loose mode, only inbound packets with a source address that is not associated with any interface are dropped.
In the practical example from above that means that only with strict filtering, packets with a source address in the
10.0.0.0/24 range coming from a different interface, like
wlan0, will be filtered out. All other modes will allow an attacker to send such packets via non-VPN interfaces.
The default mode has been strict mode for a long time but a lot of Linux based operating systems moved to loose mode as default to enable support for multipath setups.
The security impact
Without reverse path filtering set to strict mode, an attacker could send packets with addresses associated with the VPN connection via a "normal" interface and they will be processed as if they were received via the VPN. This means that depending on the packet, the attacker could fake a source address and trigger a response being sent out to the real owner of the address via the VPN. An attacker that has access to the base network could exploit this to extract some information about the VPN, active connections and even inject data into connections:
- The attacker can guess VPN addresses and find out whether the victim uses this address. This way he can identify whether a VPN is being used and which IP address the victim uses for it.
- If the attacker can guess the information of an active connection (remote ip, remote port and port on victim), it can verify whether this connection actually exists. By an extensive search over a complete port range, the attacker can potentially scan for active connections.
- If the attacker knows the information of an active TCP connection, it can guess the current sequence number by searching the number space. Using that sequence number, the attacker can inject arbitrary data into an unencrypted connection.
Continuing the practical example from above: An attacker who suspects that the victim might use a VPN could send packets for a range of destination addresses to the victim. Invalid guesses will cause a different reply than an address that is used by the victim. This way, the attacker could find out that the victim uses the address
10.0.0.20 on the VPN. An attacker, who knows that
10.0.0.100 runs a webserver on port
80 could then continue to guess the victims TCP port on an active connection to
10.0.0.100:80 by sending spoofed packets with a fake source of
10.0.0.20:port trying several ports in a brute force manner. Each guess will trigger a reply via the VPN connection, that the attacker might be able to see. Due to the VPN encryption, the attacker can not read the contents of the reply but it can see a difference in packet size when his guess is correct. The same way, that attacker uses to find out the port number, he can also use to find out the current TCP sequence number. Once the attacker found out all this information it can inject data into the connection if it is unencrypted.
Under perfect conditions, an attacker could inject data into an active unencrypted connection. Surely the theoretical security impact of this attack potential should not be underestimated. However, in reality this vulnerability is complicated to exploit: There is a lot of information (remote address, victim port, sequence number) that has to be guessed correctly in order for the attack to work. This means a lot of brute force scanning through big number ranges which takes a lot of time, especially considering every guess is its own network packet. Since a lot of networking traffic, like HTTPS, is protected by end-to-end encryption most of the connections can not be attacked by this vulnerability.
Mitigating the threat
Since this vulnerability results from a common misconfiguration in Linux operating systems and is not located in any VPN software, it can not be fixed directly in a VPN software like VpnCloud. Instead, the configuration of the host needs to be changed to mitigate the threat. This can be done in two ways:
rp_filtersetting can be set to strict mode (value 1). VpnCloud detects this misconfiguration and offers a way to change the setting using the
--fix-rp-filterswitch. Since this fix can potentially break some rare multipath setups, VpnCloud does not apply the fix automatically.
The reverse path filtering can be implemented specifically for the VPN interface and its associated IP space using the
$> iptables -t raw \! -i vpncloud0 -d 10.0.0.0/24 -j DROP $> iptables -t raw \! -i vpncloud0 -s 10.0.0.0/24 -j DROP
10.0.0.0/24 need to be replaced by the VPN interface name and the IP address range that the VPN uses.