This is a write-up for the recently retired Aragog machine on the Hack The Box platform. If you don’t already know, Hack The Box is a website where you can further your cyber security knowledge by hacking into a range of different machines.

TL;DR: RCE through XXE. | For me, this box was great because unlike some others there wasn’t much to guess, and instead it was simply logical.

As per usual, we begin by scanning the machine:

The ports for FTP, SSH and HTTP seem to be open.

We can immediately see that they offer an anonymous FTP service, which seems very strange.

We can connect to the FTP service and then look for some files like so:

There is only one file: ‘test.txt’

The file downloaded contained simply:

<details> <subnet_mask>255.255.255.192</subnet_mask> <test></test> </details>

Which, without context, we can’t really do anything with.

The next noticeable port was port 80, but visiting that in the browser displayed the default Apache2 welcome page.

With little else to go on, I fired up dirb to try and enumerate further.

A regular dirb attempt with the large bruteforce found nothing, and so I swapped over to dirbuster to use its (far simpler) fuzzing toolset, which quickly revealed a file called hosts.php:

This page showed only one line of text.

I then tried some more enumeration to see if there was anything else to help progress, but it seemed that we have been given all possible information.

A quick Google search revealed that 4294967294 is the maximum number of IPs that can be assigned to a computer running IPv4, and the file seems to be performing some form of calculation to work this out.

Since we were given a template earlier on through FTP, I tried posting it to the file in Burp:

Sending the blank template from earlier through a POST request.

From this, we can assume that the hosts.php script takes the value in the subnet_mask tags and performs a calculation with it.

Seeing as there don’t seem to be many possible exploits here, I tried a standard XXE attack using a template from OWASP like so:

We’re shown the contents of /etc/passwd!

As shown, there seem to be 2 interesting entries to the password file: cliff and florian.

One of these must be the desired user, so we can test them both and look for the user flag.

To make this process easier, I wrote a short Python script to retrieve the contents of a directory slightly faster:

Soon enough, we can find the user flag:

(The flag has been blurred).

From here, getting a proper shell isn’t too hard, since the SSH private key was completely unencrypted:

The old script name was ‘xxeDirSearch.py’.

An interesting article that I used to help me through that stage can be found here, as it outlines useful files to look for when you can read system files.

The RSA Private key for the florian user.

I saved this into a separate file, and then used it to SSH into the server:

We now have the user shell.

I tried navigating to the cliff directory, but it was restricted.

I then ran LinEnum.sh and browsed through some key directories, but still couldn’t find anything of interest, and gave up on the box for a couple of days.

When I came back to it, I decided to try pspy to see if any cron jobs were running. If you don’t already know, pspy is used to intercept all commands/processes on the machine in real-time.

After leaving it running for a while, a few unusual events kept on occurring. The main ones were as follows:

2018/06/12 06:55:01 CMD: UID=0 PID=1858 | /usr/sbin/CRON -f 2018/06/12 06:55:01 CMD: UID=0 PID=1857 | /bin/sh -c /bin/bash /root/restore.sh 2018/06/12 06:55:01 CMD: UID=1001 PID=1861 | /usr/bin/python /home/cliff/wp-login.py 2018/06/12 06:55:01 CMD: UID=0 PID=1860 | rm -rf /var/www/html/dev_wiki/ 2018/06/12 06:55:01 CMD: UID=0 PID=1862 | cp -R /var/www/html/zz_backup/ 2018/06/12 06:55:02 CMD: UID=0 PID=1867 | chown -R cliff:cliff /var/www/html/dev_wiki/ 2018/06/12 06:55:02 CMD: UID=0 PID=1868 | chmod -R 777 /var/www/html/dev_wiki/

It looks like they have a backup wordpress folder that they periodically sync to their main one.

We can assume that the wp-login.py script is logging in to the wp-login.php page in the /dev_wiki/ directory, and so we simply need to capture the data being sent to this page.

So, in simpler terms, the wp-login.py script probably sends its login details to a file called wp-login (which we can control).

As such, I deleted the wp-login.php page, and then replaced it with a script that simply logs the data, which can be found here.

We can then continuously check the folder for the dumprequest.txt (which is created by the aforementioned github script) file with watch -n1 ls, which soon appears with the following contents:

The most interesting part here is the pwd parameter, which reads “%21KRgYs%28JFO%21%26MTr%29lf”. When URL decoded, we get the string “!KRgYs(JFO!&MTr)lf”.

Using this password, we can log into the root account, and obtain the root flag!