HackTheBox Writeup: Bashed

As a career blue teamer I feel it's important to understand the tools, techniques, and thought processes of an attacker. The best way to learn is by doing, and one of my favorite ways to practice is HackTheBox.

The machine named Bashed was recently retired so walkthroughs for it have been popping up everywhere. This one is mine.

Recon

As usual with a HackTheBox target system, all you have at the onset is a name and IP address. My starting point is usually an nmap scan against the target machine's IP.

The /dev directory contains a couple of scripts. Visiting http://10.10.10.68/dev/phpbash.php in a browser presented me with a web shell (!). I'm able to navigate the file structure and read the contents of /home. Getting user.txt is a simple exercise at this point.

user = owned

Gaining a Foothold

I need to get a "real" shell on the box to go any further. I choose one of my favorite reverse shell one-liners and see if it will work from the PHP web shell.

First, I'll need a listener on my local attacker machine:

nc -v -n -l -p 4444

Now I drop this python script directly in the web shell. The ampersand (&) at the end just backgrounds the process.

Note that the field "my HTB IP address" would be the 10.10.x.x IP assigned to the VPN interface on my machine (usually tap0 on Kali Linux) when I'm connected to the HTB environment, and the port number (4444) is the same one I used to start the netcat listener in the previous step.

Now I have a reverse shell on the target system, but it's still limited. I try using python again to escape to a bash shell.

python -c 'import pty; pty.spawn("/bin/bash")'

Great, now I'm at a more typical shell as user www-data. Time to enumerate.

Enumeration

I checked many many things, but looking at sudo capabilities turned up some useful information.

-i [command]
The -i (simulate initial login) option runs the shell specified by the password database entry of the target user as a login shell. This means that login-specific resource files such as .profile or .login will be read by the shell. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is specified, an interactive shell is executed. sudo attempts to change to that user's home directory before running the shell. The security policy shall initialize the environment to a minimal set of variables, similar to what is present when a user logs in. The Command Environment section in the sudoers(5) manual documents how the -i option affects the environment in which a command is run when the sudoers policy is in use.

Examining these two files leads me to believe that test.txt containts output from the test.py script. However,test.txt is owned by root while the directory it resides in and the test.py script that generates it are owned by scriptmanager.

This implies that root is executing the script as itself, so the output is written with root ownership. If I can replace test.py with my own malicious version I can do something on the target machine with root privileges. Reverse shell time!

Here I moved/renamed the existing test.py and created my own with the reverse shell code. This isn't necessary, you could just add the reverse shell bits to the end of the existing file.

Again note the "my HTB IP address field" and port number. I want a second reverse shell that's separate from the one I'm currently working in, so I selected a new port (5555).

I'm not exactly sure how or when root executes the test.py script. Given the autonomous nature of these HTB systems I assume it's just a cron job. I start a netcat listener on this new port on my local attacker machine and wait.

After a few minutes...

root = owned

Conclusion

Looking back Bashed was a pretty simple machine, but there were two primary lessons I learned from it:

Look at the simple or obvious things first. Don't assume every target is going to require some elaborate, complicated method to exploit.

Enumerate (a lot) and review the details carefully. It took me way too long to notice the permissions on test.txt and test.py

Did you conquer Bashed using some other method? Feel free to reach out to me on Twitter, I'd love to talk about it.