Hello guys back again with another walkthrough this time we are going to be tackling Unbaked Pie from TryHackMe. You start off by finding a website vulnerable to insecure pickle deserialization, exploit the vulnerability and land in a docker container as the root user then do some port forwarding of SSH using chisel and using a username that you had obtained from .bash_history file you perform a SSH brute force attack using hydra and get a shell on the main box as the user Ramsey.Next you find a python program that is vulnerable to command injection and leverage that vulnerability to escalate your privilege to a different user then perform python PATH hijacking to get root on the box. The box was rated medium and i think the rating was valid because of the steps you had to take to get root on the box none the less i really loved the box and without much say let’s jump in
As always we are going to start off with a nmap scan of the box to identify ports that are open
Looking at the result of the nmap scan you can see that one port 5003 is open and it seems to be hosting a web server. Navigation to the web server using Mozilla we get a standard web page and the web application seems to be running python instance. The best guesses we can have for now is that the site is either running flask or Django
First i tried to navigate to the different linked and found a login page
I tried obvious credentials on the login page but it didn’t work. Navigating to various link and saw an Django error message that showed that Django was on debug mode. This confirms our suspicion and we can accurately say that the site is running Django
Django being set on debug isn’t a vulnerability as such but it can lead to sensitive information disclosure like passwords and secret_keys if other names other than passwords and secret are used. But as you can see below all our passwords and secret_keys have been masked
So after trying much to find a vulnerability here i hit a dead end and ended up going back to the homepage there were a lot of posts talking about pickle
From penetration tests and CTF’s that I’ve done before i know that some python based web applications are vulnerable to insecure pickle deserialization which leads to remote code execution. By sending the web application a serialized payload it will unpickle the payload and execute the command and give you a shell. And our webpage allows for user input in the search bar. I created a python script that will serialize a payload and give me the base64 encoded payload
I saved the exploit and the executed the script passing it a ping payload as you can see below. If the web application is vulnerable we’ll get a ping back on my box
Next i did set up a tcpdump listener on my box and then performed using that payload
Going back to the listeners you can see that we got 2 pings.
Also intercepting the request with burpsuite we can see that the payload is added to our cookie meaning we can just edit our cookie to add other payloads
Sweet we have now confirmed that by sending the web application serialized payload, it executes the payload and gives us code execution next let’s get a shell on the box
I changed by payload a bit to add a bash reverse shell
Next i did set up a netcat listener
And the edited the cookie to the payload that had been generated by the script and refreshed the page
Going back to the netcat listener we have a shell on the box as a root user. Sweet.
But looking at the root folder it looks like we landed on a docker environment
Now we need to find a way to escape the docker container to perform privilege escalation on the box. I downloaded linpeas to the box and ran the script. Linpeas is an awesome tool that identifies possible privilege escalation vectors and output the information using awesome colors meaning it is easy to identify misconfigurations based on color output.
Looking at the output of linpeas we see that we could read .bash_history file
The history file has an IP Address of another box that we could possibly talk to from the docker container
I tried to ping that IP Address and got a callback
Sweet we can talk to that box. But also linpeas offers options to can be used to scan for active IP Addresses on the subnet so i decided to scan the entire subnet and tried to find if there were other boxes apart from that which we could talk to
But as you can see there were only two IP Address one of which was our IP Address. Since we didn’t know what 172.17.0.1 was, i decided to do a port scan on the IP Address using another feature offered by linpeas
And looking at the results you can see that two ports are open which include SSH. I tried to access SSH from the docker container but i hit a dead end since i didn’t have the necessary software on the docker container to access it
Next i decided to perform port forwarding on that port(SSH) using Chisel so that i can access that port from my local box. I downloaded chisel binary to the box using wget and the from my local box i created a port forwarding server
On the docker container i did set up a port forwarding client
Then tried to access the SSH service from my local box
And voila we have a callback. Sweet but SSH requires valid credentials. And looking back at the linpeas results we didn’t find anything else useful. But we have a ‘somewhat’ valid username we can’t be sure. What if we try and brute force the password for SSH using hydra?
And looking at the screen shot above we found a valid credential from the brute force. Now we can log in to SSH
Sweet we have a shell on the box. Looking at the user’s home directory we have the user flag for the box and we can read it
Now we can submit the user flag to TryHackMe and get the points
Running sudo -l we see that we can execute a python script called vuln.py as the user Oliver without knowing the users password
Looking at the python script. It accepts user input using raw_input function and depending on the choice given by the user the script will execute different function
If option 2 is selected by the user, the script opens up a payload.png image do some magic with its contents and then perform eval() on the results obtained
Eval function is generally a unsafe function if user controlled input is passed to it since it can lead to code execution
But we don’t know what payload.png contains and since we don’t have a GUI interface let’s download payload.png back to our box and see what it contains
I base64 encoded the payload.png file and copied it to my box then decoded the file using base64 and saved it in a file called payload.png
Looking at payload.png
It seems to be performing an addition operation on two numbers meaning if the python script does and eval we should get a result of 4. Lets execute the python script and see what the result will be
Looking at the result above we see it perform an arithmetic operation. But we need to craft an image containing the payload. Browsing through the internet i found a site that does the job perfectly
Since the script uses eval, we could use the OS library to just spawn a shell with the same privileges as the user running the python script which will be Oliver.
But first we need to craft the payload using the site i showed before
The configuration that i used were as follows
Then converted the text to a PNG image and downloaded it to my box
After downloading the image to my box i uploaded it to the server
Then changed the name of the PNG file to payload.png since we didn’t have write access to the vulnerable python script
And then executed the python script again as the user Oliver
Looking at the screenshot above we were able to spawn a shell as the user Oliver. Running sudo -l again we see that the user Oliver can run a script called dockerScript.py as the root user without knowing the root’s password
But we can set our own PATH since we have been provided with the option SETENV as you can see from the screenshot above.
Looking at the python script we only have read and execute permission and not write access
But taking a closer look at the script we can see that it imports a docker module.
And since we can control the path the script uses to import the docker module we can create a malicious module which when executed it will drop us on a root shell
First Let’s create a directory called devel you can name it whatever you want
Next we create a __init__.py file and a docker.py file which will contain the malicious python code
Let’s create a malicious python code in the docker.py file
When the docker.py file will be imported it will spawn a root shell as the user who will be running the python script which in our case will be root.
Now all we have to do is save the script and execute it passing our own python path and we’ll be golden
Executing the command
We get root on the box just like that. Sweet. Navigating to root’s home directory we get the root’s flag
And the box is done just like that. Some rabbit holes that i fell into include there was a SQLite database in the docker’s home directory which contained some Django hashes
I tried cracking them using hashcat but was unsuccessful to crack the hashes in any meaningful time since it has a strong encryption. I thought i could crack those hashes and one of the password would be reused as a SSH password or a root’s password. But the box was good with lots of lessons to be learnt and i hope you enjoyed the walkthrough. If so you can follow me so that you don’t miss any upcoming articles and clap for me down below
Just to get our hand a bit more wet i decided to create a python script that gives you a command prompt where you can type the command you want executed and the python script automatically generates the payload and submits the payload automatically . Below is the python script
Let’s perform a quick demo and see the script working
If you want to learn more on python pickling you can look at one of my earlier articles called Peak Hill which we exploit a similar vulnerability in a detailed form.