cubeImagery

Linux Medium Box from HackTheBox Season 9 (2/13)

Recon

As always, we start off by performing a TCP port scan using nmap

We see that TCP Port 22 | SSH and TCP Port 800 | HTTP-ALT are open, this one running on Werkzeug 3.1.3 which is a web application that runs on python

let's check what's inside the website running on TCP Port 8000

We see that we can register as well, after the registration we see a new dashboard where we can upload images

But nothing appears to be injectable for now here

From here, after applying some lateral thinking we notice a weird endpoint at the bottom of the webpage:

Here we see a report form, and if we send it:

As we can see, the Admin is going to review our form that we sent, this gives us a clear hint on what we need to do next.

Stored / Persistent XSS on Report Bug Form

We need to send a malicious XSS payload that retrieves the admin's cookies to our local server after he loads the payload, hence showing us the cookies explicitly.

We're going to use the following payload:

And in our Python HTTP Server we see the following output

Which outputs the session cookie of the Admin User, so we hijack the cookies using Firefox

But after trying to access the admin panel the website crashes by redirecting us to the

This happens because we're getting the reflected XSS to fix this we're going to use burp-suite's intercept so we control which requests are forwarded or not

And now we're able to see the admin panel properly

LFI in get_system_log

After inspecting a bit, we see that when we try to use the Download Log function it tries to retrieve a file from the system, hence giving us hint on what we should do, in this case, performing an LFI (Local File Inclusion) so we send this request to burp's repeater with Ctrl + R and try to look for arbitrary files on the system (e.g ../../../../etc/passwd)

And voilah, we succeeded at the LFI

After enumerating some more we don't see any SSH Key( id_rsa) that we can enumerate, so as we know this is running on Werkzeug and the system has a web user

Web Backend Enumeration

Let's try to enumerate his current directory with the use of /proc/self/cwd/ which is a symbolic link of the CWD (current working directory) of the user running the web, in this case: web

Let's try to look for the app.py file as it's in most of the web servers running on Werkzeug

This helps us understand how everything is working at a better glance, it's importing stuff content config which means that a config.py file is available, same goes for utils.py

Let's try to enumerate the config.py file and see what it contains

We see that data is stored at a file called db.json and after enumerating that file with the same process we get the following output:

So we got a md5 hash for the testuser and the admin user!! let's crack them with crackstationarrow-up-right

Backend code review

We've got access to the testuser so login through the web to it:

And after uploading an image and accessing to the Gallery dashboard, we see that we've got some options that are not blanked anymore

Remember that we got full access to the web backend? Let's try to enumerate from these functions from app.py as we did earlier but with the focus to to audit the code and potentially find attack vectors

We see that it's importing the os library which gives us a hint: It's executing system commands, we also see both api_manage and api_edit which could be related to the options we saw earlier in the Gallery dashboard

After carefully inspecting the code, we don't seem to find anything in api_manage.py

In the other hand, api_edit.py crop function seems vulnerable to command injection

constructs a shell command using untrusted input and executes it with shell=True This allows us to take control of the interpolated values e.g x, y, width, height to inject shell commands and execute arbitrary commands as the web process user.

Foothold: Command Injection

So let's intercept the crop function on the web with burp and send it to repeater

As we can see the code is reflecting, showing us web as the user with the command whoami,

now let's execute a Bash TCP Reverse shell with the following payload

And set up our listener with netcat so we receive the reverse shell

AES Decrypt Script Development

After a lot of enumeration we see a AES Encrypted file on the /var/backup directory

So let's transfer it to our local host and try to crack it

The AES encryption method needs a passphrase to crack it, so we're going to develop a python script that brute-forces this passpharse with the use of the rockyou.txt wordlist and then decrypts the file itself with the pyAesCrypt module:

So first off we activate the python venv and install the pyAesCrypt library

And finally we execute

We successfully cracked the AES file and the passphrase is: bestfriends so we unzip the file

And we see that it's a web backup and after enumerating a bit we notice that the db.json file now also contains the mark user password hash

So we crack it with crackstationarrow-up-right as we did with testuser earlier:

Privilege Escalation: Abusing Charcol

We see that the credential successfully worked so it's time to escalate to the root user

And after some enumeration we see this

We try execute it

So we try to check the help manual using --help

As we see, we can reset the password to it's default using the -R parameter, so let's try to do it

Now we got access to the charcol shell and after typing help a help manual appears on the output

Something catches our attention instantly

You can summon a cron job that spawns a shell command, and this is executed as root

Let's try to change the /bin/bash permissions so we can access a privleged bash

And if we do

We get a shell as the root user!

Thank you for reading this writeup, I hope it helped a lot and see you next time!

Last updated