![](/content/images/2019/10/image.png)
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:
![](/content/images/2019/10/image-1.png)
HTTP shows a cool looking site:
![](/content/images/2019/10/image-2.png)
Port 8080 is password protected:
![](/content/images/2019/10/image-3.png)
I clicked around the site on port 80 but didn't find anything interesting so I fired up Gobuster:
![](/content/images/2019/10/image-4.png)
secret.php appears to have some juicy details:
![](/content/images/2019/10/image-6.png)
Troll #1: the user flag does not work.
Running Gobuster again on the /users directory revealed a login.php file:
![](/content/images/2019/10/image-7.png)
I got nowhere with the login.php so I turned my attention to port 8080. I compiled a list of potential users:
![](/content/images/2019/10/image-8.png)
Then I used Hydra:
![](/content/images/2019/10/image-9.png)
Logging on shows page with an upload function:
![](/content/images/2019/10/image-10.png)
There is also an option to upload zip files:
![](/content/images/2019/10/image-11.png)
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:
![](/content/images/2019/10/image-12.png)
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:
![](/content/images/2019/10/image-13.png)
Next I copied it to /var/www/html on my machine and zipped it up using a relative path from the current folder:
![](/content/images/2019/10/image-14.png)
If you take a look at the contents of the newly created zip file, you'll see the directory traversal:
![](/content/images/2019/10/image-72.png)
I uploaded this zip file through the web interface, then hit http://ghoul.htb/rs-small.php to get a reverse shell:
![](/content/images/2019/10/image-15.png)
While enumerating the system, I find /var/www/html/users/login.php that shows credentials in plain text:
![](/content/images/2019/10/image-16.png)
All of these creds work at http://ghoul.htb/users/login.php but they all end up with the same page:
![](/content/images/2019/10/image-17.png)
That was Troll #2.
While enumerating some more, I found /var/backups/backups which had some files in it:
![](/content/images/2019/10/image-18.png)
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:
![](/content/images/2019/10/image-19.png)
The NSA Report was interesting, dealing with spear phishing and election rigging but ultimately useless:
![](/content/images/2019/10/image-20.png)
The 'txt' file was what looked to be obfuscated Powershell malware:
![](/content/images/2019/10/image-21.png)
Ok, time to try those private keys out. They all work:
![](/content/images/2019/10/image-22.png)
![](/content/images/2019/10/image-26.png)
Kaneki's key has a passphrase on it. After some guessing, I figured out it was 'ILoveTouka' from the secret.php:
![](/content/images/2019/10/image-28.png)
The user flag is found in Kaneki's home directory:
![](/content/images/2019/10/image-27.png)
ifconfig
shows that we are not in 10.10.10.101 but likely in a docker container or something:
![](/content/images/2019/10/image-29.png)
Other files in Kaneki's home directory:
![](/content/images/2019/10/image-30.png)
While enumerating, I found /usr/share/tomcat7/conf/tomcat-users.xml which has some creds in plaintext:
![](/content/images/2019/10/image-33.png)
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':
![](/content/images/2019/10/image-31.png)
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 172.20.0.150:
![](/content/images/2019/10/image-32.png)
On a hunch, I tried ssh'ing to 172.20.0.150 as kaneki_pub with Kaneki's id_rsa key. It had a passphrase and he re-used 'ILoveTouka' so I got in:
![](/content/images/2019/10/image-34.png)
There's a to-do.txt file in his home dir:
![](/content/images/2019/10/image-35.png)
I filed away 'AogiriTest' as a potential user somewhere and moved on.
'ifconfig' shows that this is a dual homed machine:
![](/content/images/2019/10/image-36.png)
I transferred 'pspy64' to the machine and ran it. There's an interesting thing being run every so often:
![](/content/images/2019/10/image-39.png)
A peek at /etc/group shows that UID 1001 belongs to kaneki_adm:
![](/content/images/2019/10/image-40.png)
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 172.18.0.0 subnet:
![](/content/images/2019/10/image-37.png)
Let's take a closer look at 172.18.0.2:
![](/content/images/2019/10/image-38.png)
Hmm, a web server of some kind eh? Time to do some tunneling by ssh'ing to my machine from kaneki-pc:
![](/content/images/2019/10/image-41.png)
Now we have GUI access to Gogs:
![](/content/images/2019/10/image-42.png)
Version number:
![](/content/images/2019/10/image-44.png)
The notes I took came in handy here. I logged in with 'aogiritest/test@aogiri123' that I found while enumerating:
![](/content/images/2019/10/image-43.png)
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:
![](/content/images/2019/10/image-46.png)
![](/content/images/2019/10/image-47.png)
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:
![](/content/images/2019/10/image-50.png)
It took a few tries but I finally found a reverse shell that worked:
![](/content/images/2019/10/image-48.png)
![](/content/images/2019/10/image-49.png)
'ps -aux' revealed this:
![](/content/images/2019/10/image-52.png)
Using that breadcrumb, I find /app/gogs/docker/s6/openssh/run:
![](/content/images/2019/10/image-53.png)
That seems pretty ripe for abuse so I created a shell script, made it executable and ran it as root:
![](/content/images/2019/10/image-54.png)
With a netcat listener:
![](/content/images/2019/10/image-55.png)
Alternatively, you can just do this:
![](/content/images/2019/10/image-56.png)
There's a /root/session.sh file with creds:
![](/content/images/2019/10/image-57.png)
There is also an interesting file aogiri-app.7z so I downloaded netcat to the machine and transferred it to mine:
![](/content/images/2019/10/image-58.png)
I extracted the file and looking through it shows some creds:
![](/content/images/2019/10/image-59.png)
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:
![](/content/images/2019/10/image-60.png)
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:
![](/content/images/2019/10/image-61.png)
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:
![](/content/images/2019/10/image-62.png)
With some trial and error, ' 7^Grc%C\7xEQ?tb4' works to become root on kaneki-pc:
![](/content/images/2019/10/image-63.png)
Here we have Troll #3:
![](/content/images/2019/10/image-64.png)
Back to enumerating. I find some interesting commands in kaneki_adm's .bash_history:
![](/content/images/2019/10/image-65.png)
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:
![](/content/images/2019/10/image-66.png)
A bit of googling reveals that these folders contain sockets used by programs to communicate with ssh-agent:
![](/content/images/2019/10/image-67.png)
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:
![](/content/images/2019/10/image-68.png)
I was a bit anxious to try it and got all kinds of annoying errors when I first ran it:
![](/content/images/2019/10/image-69.png)
I ran it again piping errors to /dev/null and after a short while, I got a root shell:
![](/content/images/2019/10/image-70.png)
At long last, the root flag:
![](/content/images/2019/10/image-71.png)