TwoMillion is a Linux machine hosting a web application with an API that has a command injection vulnerability. This vulnerability can be exploited to obtain a shell on the system as www-data. Enumeration can lead to the discovery of a configuration file that contains credentials for the admin user, allowing for SSH login. An email in the /var/mail directory provides a hint indicating that the Linux kernel version on the machine is outdated and might be vulnerable to certain CVEs; this leads to the identification of CVE-2023-0386, a local privilege escalation vulnerability that can be exploited to gain root access on the system.
nmap scan:
Open ports:
- 22 (SSH)
- 80 (HTTP)
Browsing to the IP redirected to 2million.htb, so I added that to /etc/hosts and then visited the webpage which was an older version of the Hack The Box home page:
There was an invite code form which needs to be hacked in order to obtain a code:
After inspecting the code, I found an interesting script: /js/inviteapi.min.js:
The page contained obfuscated javascript code:
I used js-beautify to deobfuscate the code:
The code above contains two functions, verifyInviteCode() makes a POST request to /api/v1/invite/verify and makeInviteCode() makes a POST request to /api/v1/invite/how/to/generate.
In Burp Suite, I sent a POST request to /api/v1/invite/how/to/generate which responded with data that was encrypted using ROT13:
The decrypted message said In order to generate the invite code, make a POST request to /api/v1/invite/generate:
After visiting that endpoint, a new code was generated encoded in base64:
Once it was decoded, a valid invite code was provided:
I went to the invite code form and used the code to sign up:
This brought me to a registration page, so I registered a new user:
Then, I logged in which redirected to the dashboard page:
I looked around the webpage but didn't find anything too useful, so next, I tried visiting the /api/v1 endpoint, which responded with a list of API endpoints:
/api/v1/user/auth checks if a user is authenticated. This endpoint responded with my current user and also showed that the is_admin parameter was set to 0 meaning that I wasn't an admin user:
But there's another endpoint: /api/v1/admin/settings/update, which can update the admin settings for a user. This can be done with a PUT request that provides the email and is_admin parameters, and the Content-Type should be set to application/json:
The above PUT request responded with "is_admin":1, showing that my user was now an admin user. I verified this by sending a GET request to /api/v1/admin/auth:
/api/v1/admin/vpn/generate will generate a certificate to connect to the VPN. I sent a POST request to this endpoint and provided a username parameter:
I tested for command injection within the username parameter to the /api/v1/admin/vpn/generate route:
{
"username":"mike;whoami;"
}The server responded with www-data, showing successful command execution.
Next, I started a Netcat listener and then sent the following command for a reverse shell:
nc caught a shell as www-data:
Enumeration of the system led to the discovery of a username and password in ~/html/.env:
I viewed /etc/passwd to see what users were on the system:
There was an admin user, so I attempted to log in over SSH using the username admin and password SuperDuperPass123:
Upon logging in, there was a message saying that the user had mail:
So I went to /var/mail and found the following email:
The message mentions that there have already been a few serious Linux kernel CVEs this year, noting the one in OverlayFS/FUSE specifically. A web search led to this article from Datadog, which provides more details on the OverlayFS vulnerability (CVE-2023-0386).
The article states:
Checking the current OS info on the machine with uname -a showed that the current Linux kernel was 5.15.70:
The Datadog article contains a proof of concept exploit here.
So, I cloned the repo and used tar to compress it:
Started up a python web server:
From the target machine, I used wget to download the archive and used tar to extract it:
As stated on the PoC GitHub page, the exploit takes three steps. First, the make command to compile the code:
Next, I ran ./fuse ./ovlcap/lower ./gc from one terminal:
Then, I opened another terminal on the target machine and ran ./exp:
After doing so, a root shell was spawned: