TryHackMe — Vulnversity
Hello guys, what’s going on, this is shellbreak, and today we’re gonna be doing Vulnversity from TryHackMe which is a pretty simple and straightforward machine that involves a File Upload vulnerability to get a shell, and once we get a shell on the box we notice that there’s an unusual SUID binary which we can abuse to get shell as the root user, so enough talking and let’s just jump in.
As always we’re gonna start off with nmap scanning:
nmap -sC -sV -oA nmap/vulnversity $IP
As seen in the above picture, we see that the target server has an FTP server running on port 21, but since we used the -sC
option, and nmap didn’t tell us that anonymous access is allowed, we don’t have much to dig into, so we’re gonna skip this port for now.
Nmap tells us that the ports 139, and 443 are open so let’s see if we can get any information from the smb shares.
Nothing of interest in the smbserver, so let’s keep searching.
From the nmap
scan we saw a kinda weird port open which is 3128
Accessing this port from the web browser (since the banner tells us it’s an http-proxy service) doesn’t give us anything.
But a good piece of information is that the serivce’s version is exposed in the web page, so we can use that information in case nmap
gives us any false positives.
Now to the webserver on port 3333
We see this nicely designed web page, now while manually poking at the web page, we’ll run gobuster in the background to save some time.
gobuster dir -u http://10.10.21.96:3333/ -w /opt/SecLists/Discovery/Web-Content/raft-small-words.txt -t 60
From the gobuster
results, we see an interesting directory internal
Visiting the directory from the browser gives us this simple file upload form
Let’s see what extensions we’re allowed to upload to the web server.
First, we will try uploading a regular image and see what’s what.
We see that uploading images isn’t allowed, so we’re gonna have to fuzz the upload functionality, and we will use burpsuite for that purpose.
Firing up burpsuite and intercepting the upload request gives us the following:
Send the request to the intruder, and we’re gonna highlight only the extension of the file we’re trying to upload.
Now in the payloads
tab, we will add some common extensions we can use to achieve code execution.
In the options
tab, scroll down to the Grep — match
section and add the error message we got from the web application “Extension not allowed”, so burp can detect if any extension causes a different response.
Now hit that “start attack” button and let the fuzz begin ;)
As we can see, burp tells us the the extensions “php,php5,php7,jpeg,jpg, and png” are not allowed, but hey, we have phtml
allowed, which is great as phtml files are nothing but regular php files.
Now let’s grab a reverse shell script and upload it to the web server (Don’t forget to set your IP and PORT in the script, and change the default extension from php to phtml).
I’ll be using php-reverse-shell.php
as it’s my favorite :)
It comes preinstalled on Kali Linux, so you can find it with locate command
locate php-reverse-shell.php
Now let’s upload our shell script to the web server.
And yay!!
We managed to upload our shell script, but wait, where did it get uploaded to?
We need to find the directory in which the uploaded files are stored.
so we will use gobuster
again to find it.
gobuster dir -u http://10.10.21.96:3333/internal/ -w /opt/SecLists/Discovery/Web-Content/common.txt -t 60
We see a subdirectory called uploads
inside internal
directory, let’s go there and see what we got.
We can see our file rev.phtml
here, so clicking on the link should give us the reverse shell.
In my case I used port 9001 to get the shell on, feel free to use whatever port you like (as long as the target server isn’t blocking it).
And, we got our shell, now it’s the time to privesc.
Now let’s do some manual enumeration before using any automated scripts.
For me, when I first land a shell on a box, I run sudo -l
to see if there’s any commands/scripts/binaries I can execute in the context of other users, but it’s not the case on this box. So, my next go-to is checking the SUID binaries.
find / -type f -perm -u=s 2>/dev/null
From the output of the previous command, we notice that systemctl
is a SUID binary, so, easy root for us :)
Go ahead to this great website and check if systemctl
has any available methods to be used for privilege escalation.
And indeed, it has 2 methods, one of which is by exploiting the SUID permissions.
The methodology here, is that we create a malicious service and link it to the systemd system and service manager (which is pretty similar to the task manager on windows machines), then when we enable this service, the user who owns systemctl
binary (in this case it’s the root user), our malicious service will be run in the context of the root user, hence give us a root shell.
Notice that the payload in the above picture isn’t gonna give us any shells, it just executes id
command and redirects the output to a file in the /tmp
directory.
Following the instructions from gtfobins, gives us the following results
which means we executed everything perfectly, and again, from the gtfobins instructions, it’s clear that the malicious service is gonna create a file called output
in the /tmp
directory.
As you can see, the output
file is owned by the user who created it (in this case it’s the root user), and reading the content with cat
shows us the output of the id
command.
Now let’s modify the PoC from gtfobins a little bit and put our reverse shell command.
This is how the payload should look like after the modification.
Following the instructions again with the modified service, we should get a reverse shell with root permissions.
And YAY!!
We got it, and here’s our root flag.
But, that’s not everything.
You know, I’ve been doing CTF for a long time, and it’s cool to pwn boxes and pop shells. However, in real life penetration tests, it’s not everything.
As a penetration tester, you’re expected to provide solutions to the vulnerabilities your exploited to penetrate the server, so on this server we will harden it so it gets hacker-proof, shall we ;).
As you remember, we got our initial shell by exploiting a file upload vulnerability, so, let’s view the vulnerable code and see how we can harden it to prevent any future attacks.
In the directory:
/var/www/html/internal
there’s a php file called index.php
This is where our focus needs to go.
I copied the vulnerable code to my machine so I have syntax highlighting ( and because nano and vi didn’t work well on the target server ).
I’ll break the code down to you so we can understand the logic behind the vulnerability and what we need to fix it.
The code is checking if a parameter called file
is set, if it’s not, the code just throws an error.
After checking the parameter, it breaks down the filename into 3 parts.
file_name, file_type, file_ext
Then it defines a new variable of the type array called extensions
with only one value phtml
Then it compares the variable file_ext
‘s value with the extensions
variable. If the extension of the uploaded file is phtml
,The file gets uploaded and moved to uploads/
directory. And if it’s not phtml
, it prints out the message we saw earlier Extension Not Allowed
.
So we need to change the value from the extension
variable into something not harmful in order to patch the vulnerability. In my case I’ll choose txt
as it’s the most peaceful file extension :)
Now let’s move our newly modified code into the server again (and don’t forget to delete the vulnerable code).
Now let’s test it to see if it’s still vulnerable.
Go back to:
and try uploading a phtml
file, as this extension was the only one allowed before we harden the app.
If you did everything as explained in this write-up, you should not be able to upload phtml
files anymore.
Successfully secured :)
Now even if an attacker uploaded a file, they won’t be able to land a shell on the box.
The next thing to do is, remove the SUID permission from the systemctl
binary.
Removing the SUID permissions will prevent malicious users from being able to get root access on this box, not to forget that we closed their only way in ;)
So, that was the box, I hope you guys enjoyed it, and I’ll see you all in the next write up.