Pyrat
Test your enumeration skills on this boot-to-root machine. - by josemlwdf
Last updated
Test your enumeration skills on this boot-to-root machine. - by josemlwdf
Last updated
The following post by 0xb0b is licensed under CC BY 4.0
We start with an Nmap scan and find two open ports. Port 22 is where we have SSH available and on port 8000 we might have a web server. On closer inspection, this is a simple HTTP server. This reminds of the module SimpleHTTPServer in Python.
When we request the index page, we are only told to use a much simpler connection.
We try the simplest thing we can think of - a simple connection using netcat. We get a connection, but no feedback. Maybe we are not actually facing a web server. We assume that we are probably in a Python environment. Maybe something like a Python shell, but there is nothing to suggest this. Simple calls like 1+1
don't work, and we don't seem to be in a shell. However, we get feedback for our whoami
command that this is not defined. We would have gotten feedback if we used something like print(1+1)
.
Let's try it blind with a Python reverse shell. First we set up a listener with nc -lnvp 4445
. For the reverse shell, we use number 2 from revshells.com
and copy the inner part.
Next, we enter the payload and...
... we receive a connection back. We are www-data
. With the following commands we upgrade our shell. Unfortunately we cannot find the first flag as www-data
.
Interesting, though, we seem not to have access to the current directory. And furthermore, we see that the /root/.bashrc
is loaded. We are in the root directory, and somehow we became www-data
. There might be an interesting escape to get directly to root
.
In the /opt
directory, we notice the /dev
folder. This in turn has a .git
folder. We have a repository here. We check the config and find a password for the username think
.
The password has been reused, we can now switch to the user or access the machine as think
via SSH.
We look at the current git status and see that a file has been deleted. The image below shows how this is done in the SSH session, saving you unnecessary steps. In the following, the repository is first downloaded to the attacker's machine and then viewed.
We set up a Python web server.
Download the entire repository.
And start to analyze it. As mentioned before, a file has been deleted. The pyrat.py.old
.
With git restore
we restore the file.
We see in the script that the switch_case
function processes incoming data and performs actions based on specific conditions. If the data is 'some_endpoint', it calls the get_this_endpoint
function to handle that request. If the data is 'shell', it attempts to spawn an interactive shell on the server, connecting the client's socket to the shell, enabling remote command execution. For any other data input, it runs the exec_python
function, which executes the Python code sent through the socket. It spawns us a shell.
We go back to our necat connection on port 8000 and try shell
. And we get a shell. It seems to be the program.
When we try 'some_endpoint' we get the message that it is not defined. Interesting, this is where we need to fuzz for endpoints with a custom script as mentioned in the room description.
The following shows how to fuzz for the end point. But that could also be guessed, which happened in the first attempt solving the machine. (Looking at the comments)
We chose a rather small wordlist for this since we want to work our way up and use pwntools which slows it a bit down, due to the fact that each attempt gets printed.
https://gist.github.com/yassineaboukir/8e12adefbd505ef704674ad6ad48743d
We have a direct hit with 0
, but this is only a false-positive.
The same applies to special characters or words with special characters.
We remove the numbers, special characters manually and the words with special chars -
and _
from the list using awk.
After that, we run the script again...
... and find the endpoint admin
after a short duration.
We try the admin
endpoint and see that a password is now required. If we enter the wrong password, we receive another prompt for the password Password:
again. This applies three times, then it does not ask for a password again.
We adapt our previous script to fuzz now for passwords using the rockyou.txt
wordlist. We establish a new connection for the password entry every time because it stops after 3 attempts. This was actually the original script that got adapted to fuzz for the endpoints.
We run the script and receive a password that seems valid, since the prompt for a password was not repeated.
We try this in our netcat connection, and are greeted with a welcome message to try out the shell. After entering 'shell', we receive a root
shell and are able to read the flag at /root/root.txt
.