9 min read
October 5, 2019

HackTheBox Writeup: Ghoul

Ghoul was a hard rated box and man did it deserve that rating! It was a devious machine with lots of layers, false leads and trolling. Despite it being very frustrating at times, I found it to be extremely rewarding and I learned a ton from it. Zip slip, a vulnerability in Gogs, git histories, ssh-agent - there's not much that Ghoul didn't have! Let's dig in.

Nmap scan:

HTTP shows a cool looking site:

Port 8080 is password protected:

I clicked around the site on port 80 but didn't find anything interesting so I fired up Gobuster:

secret.php appears to have some juicy details:

Troll #1: the user flag does not work.

Running Gobuster again on the /users directory revealed a login.php file:

I got nowhere with the login.php so I turned my attention to port 8080. I compiled a list of potential users:

Then I used Hydra:

I really should have tried admin/admin before anything

Logging on shows page with an upload function:

There is also an option to upload zip files:

With the hint in secret.php about RCE somewhere on the site, I tried uploading a PHP reverse shell with a jpg extension first. That failed as the site inspects the contents of the file:

That only leaves a zip file. A bit of googling around and I found this article talking about the zip slip vulnerability - it's basically taking advantage of directory traversal with zip files. First I created a small php reverse shell:

Next I copied it to /var/www/html on my machine and zipped it up using a relative path from the current folder:

If you take a look at the contents of the newly created zip file, you'll see the directory traversal:

I uploaded this zip file through the web interface, then hit http://ghoul.htb/rs-small.php to get a reverse shell:

While enumerating the system, I find /var/www/html/users/login.php that shows credentials in plain text:

All of these creds work at http://ghoul.htb/users/login.php but they all end up with the same page:

That was Troll #2.

While enumerating some more, I found /var/backups/backups which had some files in it:

In the 'keys' folder, there were what appeared to be private RSA keys for each user so I saved those. Continuing to enumerate, I found some interesting files in /var/tmp including my php/zip files:

The NSA Report was interesting, dealing with spear phishing and election rigging but ultimately useless:

The 'txt' file was what looked to be obfuscated Powershell malware:

FYI, the pastebin link doesn't work

Ok, time to try those private keys out. They all work:

Kaneki's key has a passphrase on it. After some guessing, I figured out it was 'ILoveTouka' from the secret.php:

The user flag is found in Kaneki's home directory:

ifconfig shows that we are not in but likely in a docker container or something:

Other files in Kaneki's home directory:

While enumerating, I found /usr/share/tomcat7/conf/tomcat-users.xml which has some creds in plaintext:

I couldn't do anything with those creds so filed them away for the time being and continued to enumerate. A look at Kaneki's 'authorized_keys' file reveals another one of his usernames 'kaneki_pub':

It stands to reason that if we are currently in a container, there may be another container that is reachable. I used a simple for loop to run a ping sweep and found

On a hunch, I tried ssh'ing to as kaneki_pub with Kaneki's id_rsa key. It had a passphrase and he re-used 'ILoveTouka' so I got in:

There's a to-do.txt file in his home dir:

I filed away 'AogiriTest' as a potential user somewhere and moved on.

'ifconfig' shows that this is a dual homed machine:

I transferred 'pspy64' to the machine and ran it. There's an interesting thing being run every so often:

A peek at /etc/group shows that UID 1001 belongs to kaneki_adm:

I couldn't do anything with that yet so just filed it in my notes. Time to enumerate more then. I transferred nmap to the machine and ran a ping scan on the newly accessible subnet:

I meant to type but it's the same result

Let's take a closer look at

Hmm, a web server of some kind eh? Time to do some tunneling by ssh'ing to my machine from kaneki-pc:

Now we have GUI access to Gogs:

Version number:

The notes I took came in handy here. I logged in with 'aogiritest/test@aogiri123' that I found while enumerating:

Some googling around lead me to a RCE vulnerability which took me quite a while to get working. First I figured out that you need to comment out the below lines:

That let the script complete but I still had issues getting a reverse shell. It was somewhere during this process that I discovered that the RCE stops working after every run unless you change the repo name. That is done at this line in the script:

It took a few tries but I finally found a reverse shell that worked:

'ps -aux' revealed this:

Using that breadcrumb, I find /app/gogs/docker/s6/openssh/run:

That seems pretty ripe for abuse so I created a shell script, made it executable and ran it as root:

With a netcat listener:

Alternatively, you can just do this:

There's a /root/session.sh file with creds:

There is also an interesting file aogiri-app.7z so I downloaded netcat to the machine and transferred it to mine:

I extracted the file and looking through it shows some creds:

Unfortunately these creds did not work anywhere. I was stuck here for a while until I learned a bit more about how to use 'git'. git log shows a list of commits:

I wrote these commit numbers to a text file with: git log | grep commit | cut -d " " -f2 > commits.txt then tried another simple for loop: for i in $(cat commits.txt); do git show $i ; done but couldn't find a password in that.

After poking around some more, .git/logs/HEAD had more commits so I used that instead:

I was only interested in the first block of numbers and wrote them to head.txt with cat HEAD | cut -d " " -f1 > ../../head.txt

Next another for loop:

With some trial and error, ' 7^Grc%C\7xEQ?tb4' works to become root on kaneki-pc:

Here we have Troll #3:

Le sigh.

Back to enumerating. I find some interesting commands in kaneki_adm's .bash_history:

I try these commands as root and kaneki_adm but struck out. I got stuck here for quite a while. After a break to clear my head, I started the enumeration process again and noticed funny looking folders in /tmp that I had skimmed past before:

A bit of googling reveals that these folders contain sockets used by programs to communicate with ssh-agent:

In short order I find this article explaining how to hijack that. Basically, a file will appear in one of those /tmp/ssh-* directories as part of some script/cron. When it does, we need to set the environment variable SSH_AUTH_SOCK to that file. This happens pretty quickly so scripting is the way to go. I created the below script:

I was a bit anxious to try it and got all kinds of annoying errors when I first ran it:

I ran it again piping errors to /dev/null and after a short while, I got a root shell:

At long last, the root flag: