8 minutes
OffSec Proving Grounds: Hetemit - Walkthrough
This post contains rough notes explaining my process for exploiting the Hetemit Proving Grounds box while preparing for the OSCP certification.
My Process
Firstly I ran a port scan with nmap:
Then I tried to enumerate SMB shares using null authentication.
The null authentication was successful and when listing the shares other than the standard SMB shares there was an additional share called Cmeeks.
So I tried to connect to this share using smbclient.
Unfortunately we have no read or write permissions.
I then connected to FTP using anonymous authentication. Again, I could authenticate anonymously but had no read or write permissions.
So the next interesting port to focus on was port 50000 which nmap identified as a Werkzeug (flask) HTTP server.
I connected to the port in my browser and was returned the potential endpoints /verify and /generate:

The verify endpoint returned a response indicating that it accepted a parameter called code.
So I tried to add a HTTP GET parameter called code:

This still returned the same response.
The next step was to try sending the code parameter as an HTTP post parameter.
To do that I used burp and changed the HTTP request method to a post request:

The server then returned a 500 error, so maybe the code triggered an exception.
I then tried to insert some Python code since Werkzeug runs on Python:

This returns None which indicates that the server is executing the code parameter and displaying what the function returns since the print() function returns None.
I confirmed this by trying to execute some code that would return True (None==None):

True is returned confirming we have code execution.
Next I inserted some python code to execute System commands using the os module. I attempted to execute the wget command and reach back to my own HTTP server so that I could observe if the command was executed successfully:

I received a connection back to my webserver which showed I had command execution:
At this point I used the command execution to get a bash reverse shell:

And I received the shell as the user cmeeks:
I ran sudo -l and saw that I had privileges to reboot the machine, which I noted as being intersting. If there was a overwritable service then having this privilege would allow me to reboot the system and when the system reboots the service would execute my command.
I looked into the local services running:
I was curious about the local service running on port 18000 so I started an ssh remote port forward with my kali machine:
This then allowed me to connect to the service through my browser:

This was intersting but since the web service on port 18000 was being run from the user cmeeks, exploiting this service didnt seem like it would offer a path to escalate privileges to root.
So I then focused on finding an overwritable system service that I could use to trigger a command with my reboot privilege.
I used find to recursively search for writable files in the /etc directory. This revealed that the pythonapp.service was writable. Inspecting this service file showed that it was currently executing the flask command as the user cmeeks. So if I changed this to execute a reverse shell command as the root user then it would be executed when the server got rebooted.
I created a script that had a reverse shell payload in it and saved it to as /home/cmeeks/revshell.sh.
I then gave the script execute permissions:
Then I used echo to write the updated service file to the /etc/systemd/system/pythonapp.service file. I changed the ExecStart and User values to execute the reverse shell script as the root user.
Then I rebooted the machine using my sudo access:
On my kali machine I listened for the reverse shell. When I received the reverse shell I had a shell as the root user: