In our previous episode, we covered a series of attacks that bypass firewall/routing rules on multiple SSL VPNs. In this article, we will dive deeper into the vulnerability details and explore how SSL VPN works in general. Lastly, we will provide our open-source tools for deeper investigation into SSL VPN tunneling protocols.
Anatomy of an SSL VPN Connection
We have decided to investigate SSL VPN’s tunneling mechanisms due to the prevalence of high-impact bugs in this technology.
However, most of these bugs were found in the form of HTTP API requests. Our initial investigation shows that an SSL VPN connection should consist of three stages:
- Authentication Stage
- Zero-Configuration Stage
- Tunneling Stage
For readers familiar with IPsec protocol, simply replace the first stage with IKE, and the second stage with pre-setup configuration files.
As you may know, most SSL VPNs are zero-configuration protocols, which have contributed to their adoption rate. Most SSL VPNs only requires the user to authenticate to the server with the corresponding credentials in the first stage. If the credentials are accepted by the server, it will send back connection information, including routing tables, assigned IP addresses and cookies used to authenticate to the third stage (tunneling). The client will then use this information to establish a connection in the third stage, usually by creating a tunnel over the (D)-TLS protocol.
By creating this tunnel, the client and server may exchange IP packets over an insecure network, protected by the encryption and authentication provided by the underlaying TLS/SSL stack.
Moreover, according to our initial investigation, most bugs were found in either the first or second stage of the protocol; there were little to no studies done on the tunneling protocol itself. Before we proceed to the next section, here’s a list of vendors we tested:
Table 1. CVE IDs Tested by Us
Vendor | Advisory | Corresponding C/VE IDs |
Palo Alto Networks | https://www.cisco.com/c/en/us/support/docs/csa/cisco-sa-asa-ssl-vpn-Y88QOm77.html | CVE-2024-3388 |
Cisco | https://security.paloaltonetworks.com/CVE-2024-3388 | CVE-2023-20275 |
SonicWall | https://www.sonicwall.com/support/product-notification/stack-based-buffer-overflow-and-sonicos-ssl-vpn-tunnel-vulnerability/231011145636257/ | CVE-2023-41715 |
Fortinet | https://fortiguard.fortinet.com/psirt/FG-IR-23-225 | CVE-2023-45586 |
Ivanti (Pulse Secure), F5 | Not affected |
Fuzzing SSL VPN Tunneling Protocols
Keen readers may note that we’re testing multiple SSL VPN protocols. We took an unorthodox approach: we implemented the vendor’s tunneling protocol with Scapy and used the mitmproxy project to inject packets into an authenticated connection. Thus, we were able to skip the first and second stage, and only focus on the third stage, which is the tunneling stage. As different vendors have implemented their own encapsulation protocol inside the (D)-TLS layer, we have focused our effort on this surface. We implemented the protocol by referencing openconnect project’s implementation and by observing network behavior made by legitimate clients.
Our initial fuzzing attempt ended in vain, as we focused on said proprietary protocol itself inside the tunnel. We also found such protocols were encapsulating underlaying TCP or UDP packets, which were intended to be sent to the other side of the network by either party, and our fuzzing attempt did not find any bugs that warranted our interest. That is, until we decided to manually test against one field from the underlaying IPv4 header:
Here’s how we found the bug: as the tunneling protocol encapsulates Layer-4 traffic inside the tunnel, most of the vendors did not validate Layer-4 headers after de-encapsulating (D)-TLS and their proprietary protocol. Here’s a representation of how SSL VPN gateways usually process received packets:
VPN Gremlin in Action
The bug we found exposed a lack of validation after de-encapsulation on the receiving end and allowed us to send Layer-4 packets with arbitrary source addresses. Our packet did get forwarded correctly by the receiving end’s SSL VPN appliance, and we were able to bypass IP or policy (user)-based firewall and routing rules as a result.
As this is a spoofing-type bug, we were unable to receive any responses via our forged packets. We have investigated further into available exploit primitives available to VPN Gremlin attacks, and made some conclusions:
- The attack requires one to be authenticated into the tunnel and requires the knowledge of an available source IP address and target IP address.
- It is possible to perform a TCP off-path attack in very limited cases. However, vulnerabilities relying on ICMP and UDP-based protocols may be viable.
This left us with some cases where the VPN Gremlin attack may thrive in a network:
Case 1: Vulnerable Device in a Protected Network
As we mentioned earlier, the attack requires one to have knowledge of the available source IP address. In most cases, this is limited to the IP address of another connected client; we can only spoof as other clients that have already been authenticated into the tunnel.
With this restriction, it is still possible to cause disruption or leverage a VPN Gremlin attack against a network if the network relies on traditional network segmentation and does not rely on a bastion host. Policy-based routing and zero-trust networking may not defend against such cases as the attacker is indeed a legitimated client to the server. Some enterprises will “close off” vulnerable devices in an isolated network environment and restrict access to a limited number of employees, such as when there is a single-point-of-failure network switch/router that is vulnerable but cannot be taken offline to patch its firmware. For the seemingly legitimate client, that is actually the VPN Gremlin attack, this isolated network is still accessible. This also requires one to use vulnerabilities based on stateless protocols, which are rare, but do exist.
Case 2: DNS Spoofing/Hijacking, with DNS server in the tunnel
The second case is related to performing an TCP off-path attack. According to our findings in Yossi Gilad and Amir Herzberg. 2014. Off-Path TCP Injection Attacks. ACM Trans. Inf. Syst. Secur. 16, 4, Article 13 (April 2014), one way to perform TCP off-path attack is through DNS cache poisoning. We devised a network architecture for the VPN Gremlin attack to work with DNS cache poisoning. This architecture requires one to place a DNS server inside the SSL VPN tunnel (i.e., all SSL VPN clients and Intranet clients need to connect to SSL VPNs or its bridge to use DNS).
Conclusions
Since the VPN Gremlin attack is a spoofing-type vulnerability, its exploitation primitive is pretty limited by nature. However, this research did highlight two key points: first, that there has been little to no research on the tunneling attack surface of VPNs; and second, that attacks once considered theoretical are now feasible in real-world scenarios in 2024. We did not implement all the vendors’ protocols in Scapy, as we later found out that the attack could be made with a few commands:
ip addr add <forged IP> dev ppp0 peer <peer IP>
ip r add <target ip> dev ppp0
ping -I <forged IP> <target IP>
Therefore, it is imperative that organizations deploy defense-in-depth measures to protect against new zero-day vulnerabilities. The VPN Gremlin attack, for instance, undermines a fundamental assumption: that routers and firewalls will route and block packets correctly. By implementing network segmentation with bastion hosts (which requires complex TCP connections) or applying zero-trust networking architecture at the very second layer—such as requiring authentication to traverse network segments or access any device on the intranet—organizations can make it highly unlikely for a VPN-based attack to succeed.
Lastly, we have released our Scapy layer implementation under GPL-2 here.
Related Articles: