Hack The Box: Delivery


Jump Ahead: EnumUserRoot

TL;DR;

To solve this machine, we begin by enumerating open ports – finding ports 22, 80, and 8065 open. From the main website on port 80, we find a subdomain that reveals a helpdesk. Based on a message we found, we are able to get access to Mattermost, which is hosted on port 8065, after we have a valid @delivery.htb email address. We are able to exploit the helpdesk to obtain a valid email address, which grants access to Mattermost. From Mattermost, we get a set of credentials, which grants us a shell via SSH – giving access to user.txt. Next, we dump the Mattermost database to grab password hashes. Based on a message regarding password templates, we are able to bruteforce root‘s password hash – giving us a shell as root and access to root.txt.

Enumeration

Like all machines, we begin by enumerating open ports using nmap – finding ports 22, 80, and 8065 open.

$ nmap -v -sV -A -p- -oA enum/nmap/tcp-script 10.129.84.144
# Nmap 7.91 scan initiated Sat Jan 16 22:34:02 2021 as: nmap -v -sV -A -p- -oA enum/nmap/tcp-script 10.129.84.144
Nmap scan report for 10.129.84.144
Host is up (0.042s latency).
Not shown: 65532 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| 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    nginx 1.14.2
| http-methods: 
|_  Supported Methods: GET HEAD
|_http-server-header: nginx/1.14.2
|_http-title: Welcome
8065/tcp open  unknown
| fingerprint-strings: 
|   GenericLines, Help, RTSPRequest, SSLSessionReq, TerminalServerCookie: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 200 OK
|     Accept-Ranges: bytes
|     Cache-Control: no-cache, max-age=31556926, public
|     Content-Length: 3108
|     Content-Security-Policy: frame-ancestors 'self'; script-src 'self' cdn.rudderlabs.com
|     Content-Type: text/html; charset=utf-8
|     Last-Modified: Sun, 17 Jan 2021 04:29:27 GMT
|     X-Frame-Options: SAMEORIGIN
|     X-Request-Id: mxsmzirdrpr75qa11zsu16szca
|     X-Version-Id: 5.30.0.5.30.1.57fb31b889bf81d99d8af8176d4bbaaa.false
|     Date: Sun, 17 Jan 2021 04:38:55 GMT
|     <!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"><meta name="robots" content="noindex, nofollow"><meta name="referrer" content="no-referrer"><title>Mattermost</title><meta name="mobile-web-app-capable" content="yes"><meta name="application-name" content="Mattermost"><meta name="format-detection" content="telephone=no"><link re
|   HTTPOptions: 
|     HTTP/1.0 405 Method Not Allowed
|     Date: Sun, 17 Jan 2021 04:38:55 GMT
|_    Content-Length: 0
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.91%I=7%D=1/16%Time=6003BE60%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:\
SF:x20bytes\r\nCache-Control:\x20no-cache,\x20max-age=31556926,\x20public\
SF:r\nContent-Length:\x203108\r\nContent-Security-Policy:\x20frame-ancesto
SF:rs\x20'self';\x20script-src\x20'self'\x20cdn\.rudderlabs\.com\r\nConten
SF:t-Type:\x20text/html;\x20charset=utf-8\r\nLast-Modified:\x20Sun,\x2017\
SF:x20Jan\x202021\x2004:29:27\x20GMT\r\nX-Frame-Options:\x20SAMEORIGIN\r\n
SF:X-Request-Id:\x20mxsmzirdrpr75qa11zsu16szca\r\nX-Version-Id:\x205\.30\.
SF:0\.5\.30\.1\.57fb31b889bf81d99d8af8176d4bbaaa\.false\r\nDate:\x20Sun,\x
SF:2017\x20Jan\x202021\x2004:38:55\x20GMT\r\n\r\n<!doctype\x20html><html\x
SF:20lang=\"en\"><head><meta\x20charset=\"utf-8\"><meta\x20name=\"viewport
SF:\"\x20content=\"width=device-width,initial-scale=1,maximum-scale=1,user
SF:-scalable=0\"><meta\x20name=\"robots\"\x20content=\"noindex,\x20nofollo
SF:w\"><meta\x20name=\"referrer\"\x20content=\"no-referrer\"><title>Matter
SF:most</title><meta\x20name=\"mobile-web-app-capable\"\x20content=\"yes\"
SF:><meta\x20name=\"application-name\"\x20content=\"Mattermost\"><meta\x20
SF:name=\"format-detection\"\x20content=\"telephone=no\"><link\x20re")%r(H
SF:TTPOptions,5B,"HTTP/1\.0\x20405\x20Method\x20Not\x20Allowed\r\nDate:\x2
SF:0Sun,\x2017\x20Jan\x202021\x2004:38:55\x20GMT\r\nContent-Length:\x200\r
SF:\n\r\n")%r(RTSPRequest,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConten
SF:t-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n
SF:400\x20Bad\x20Request")%r(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r
SF:\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close
SF:\r\n\r\n400\x20Bad\x20Request")%r(SSLSessionReq,67,"HTTP/1\.1\x20400\x2
SF:0Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nCon
SF:nection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(TerminalServerCookie
SF:,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;
SF:\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request"
SF:);
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.91%E=4%D=1/16%OT=22%CT=1%CU=31031%PV=Y%DS=2%DC=T%G=Y%TM=6003BEC
OS:B%P=x86_64-pc-linux-gnu)SEQ(SP=103%GCD=1%ISR=10C%TI=Z%CI=Z%TS=A)OPS(O1=M
OS:54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11NW7%
OS:O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%
OS:DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=
OS:0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF
OS:=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=
OS:%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%
OS:IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

Uptime guess: 17.493 days (since Wed Dec 30 10:45:55 2020)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=259 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 993/tcp)
HOP RTT      ADDRESS
1   41.86 ms 10.10.14.1
2   41.93 ms 10.129.84.144

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jan 16 22:36:27 2021 -- 1 IP address (1 host up) scanned in 144.73 seconds

Ports 80 and 8065 are webservers, so we enumerate them using gobuster and nikto, however, we do not receive any notable information. Going to port 8068 in the browser, we see that it is hosting MatterMost – an open-source, self-hostable online chat service. Going to port 80 in the browser, we are presented with a pretty bare website, that tells us to check out the helpdesk for an account.

Getting User

From port 80, by clicking the “Contact Us” button, we are presented with a popup that informs us that unregistered users should use the helpdesk to contact the team. It also states that we will get a @delivery.htb email address, that will allow us access to MatterMost.

When we try to access the HelpDesk from the link, we are forwarded to helpdesk.delivery.htb. Since we do not have this added to /etc/hosts, we are unable to access it. After adding it, we are now able to access the helpdesk. Based on the message we previous read, we can assume that opening a ticket will grant us a @delivery.htb email address, so we open a ticket. After submitting the ticket, we are indeed presented with a valid email.

Using the email address we used to open the ticket, we are able to check the status of the ticket – and receive any responses.

Remembering from the “Contact Us” popup, after we got a valid @delivery.htb email address, we should be able to gain access to MatterMost. Next, we go to MatterMost on port 8065, to try to get it to verify the account was created. Logging in requires a password, and since we did not set it, we can try to create an account using the @delivery.htb email address we received. When the ticket was opened, it stated all communications using that email address would be appended to the ticket.

After refreshing the ticket, we do see our MatterMost account was created, and are able to activate it using the link provided.

After logging into MatterMost with our account, we navigate to the “Internal” team. From there, we select the “Internal” channel. Within it, we find a set of credentials. Additionally, we read a comment from root, that passwords may be some variant of “PleaseSubscribe!”.

Using the credentials, we are able to log into the machine via ssh as the maildeliverer user – giving access to user.txt.

Getting Root

Having gained a shell as the maildeliverer user, we attempt to grab credentials from the ticketing system and MatterMost databases – these may be easy wins for privilege escalation. First, we navigate to /var/www/osticket/upload/include/ and grab the database credentials from ost-config.php.

Unfortunately, this does not provide any advantage. Next, we navigate to /opt/mattermost/config/ and get the MatterMost database credentials from config.json. Logging into the database with the credentials, we find an entry for the root user.

Looking at the password hashes, we observe they are in bcrypt format – denoted by $2a$. Reflecting on root‘s message in the MatterMost channel, we may be able to bruteforce the password using “PleaseSubscribe!” as a template. For this, we can use hashcat along with the “best64” rules.

After successfully cracking root‘s password hash, we attempt to ssh into the machine as root. Since root logon is likely disabled for ssh, we are able to use su from maildeliverer‘s session to log in as root. Having done so, we can now read root.txt.

Thank you for taking the time to read my write-up. I am interested in other ways this machine has been solved. Feel free to reach out to me and we can discuss it. Thanks!