Imagery
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 crackstation
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 crackstation 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