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: