Hack The Box: Bolt

Jump Ahead: EnumGetting a FootholdUserRootResources


To solve this machine, we begin by enumerating open ports using nmap – finding ports 22, 80, and 443 open. From the nmap ssl-cert script, we find the subdomain passbolt.bolt.htb, and it add it and the root domain to our /etc/hosts file. Next, we enumerate vhosts, and find 2 additional subdomains to add – demo and mail. From the webserver on port 80, we find a downloadable docker image. While analyzing it, we find login and database credentials, as well as the source code for a couple of the vhosts. Using a secret we find in the source code, we are able to create an account on http://demo.bolt.htb. After creating an account, we learn that it also creates us an email account for http://mail.bolt.htb. Through source code analysis and fuzzing, we learn that http://demo.bolt.htb is vulnerable to Server-Side Template Injection (SSTI). Exploiting this, we get a reverse shell on the machine as www-data. Looking around the machine, we find a set of database credentials, and attempt to use the password with system users. Doing this gives us a shell as eddie – allowing access to user.txt. While enumerating the machine, we find a file that references passbolt (same service used on port 443). Looking into it, we find information that leads us to look further into passbolt. Eventually, we are able recover eddie’s passbolt account, and get credentials for root. Using them, we get a shell as root, and read root.txt.


Like all machines, we begin by enumerating open ports using nmap. From our scans, we find ports 22, 80, and 443 open.

$ sudo nmap -v -p- --min-rate 3000 $RHOST
$ sudo -p 22,80,443 -sV -A -oA enum/nmap/tcp-scripts $RHOST
# Nmap 7.91 scan initiated Sun Sep 26 10:07:00 2021 as: nmap -p 22,80,443 -sV -A -oA enum/nmap/tcp-scripts
Nmap scan report for
Host is up (0.065s latency).

22/tcp  open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 4d:20:8a:b2:c2:8c:f5:3e:be:d2:e8:18:16:28:6e:8e (RSA)
|   256 7b:0e:c7:5f:5a:4c:7a:11:7f:dd:58:5a:17:2f:cd:ea (ECDSA)
|_  256 a7:22:4e:45:19:8e:7d:3c:bc:df:6e:1d:6c:4f:41:56 (ED25519)
80/tcp  open  http     nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title:     Starter Website -  About 
443/tcp open  ssl/http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-title: Passbolt | Open source password manager for teams
|_Requested resource was /auth/login?redirect=%2F
| ssl-cert: Subject: commonName=passbolt.bolt.htb/organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=AU
| Not valid before: 2021-02-24T19:11:23
|_Not valid after:  2022-02-24T19:11:23
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Linux 5.0 - 5.3 (94%), Linux 5.3 - 5.4 (94%), Linux 2.6.32 (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.4 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 443/tcp)
1   66.54 ms
2   66.69 ms

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Sep 26 10:07:21 2021 -- 1 IP address (1 host up) scanned in 21.41 seconds

From our nmap script results, we immediately learn port 443 has the subdomain passbolt.bolt.htb in its TLS certificate. For now, we add it, and the root domain bolt.htb to our /etc/hosts file. Next, we enumerate the webservers on ports 80 and 443 with tools like gobuster and nikto, however, we do not see any particularly interesting results. Since we found a subdomain on port 443, we decided to check for other vhosts on both webservers. For this, we use gobuster vhost, and subdomains-top1million-5000.txt wordlist from seclists. From our results, we find 2 new vhosts on port 80demo.bolt.htb and mail.bolt.htb. For the time being, we add them to our /etc/hosts file.

Lastly, we check out the vhosts we have found so far, and verify they are all different. http://bolt.htb shows a basic website, https://passbolt.bolt.htb shows an input field for passbolt (an open-source password manager), http://demo.bolt.htb redirects to a generic login for a platform, and http://mail.bolt.htb gives a login form for roundcube email client.

Getting User

Going to the download page on the main site, we learn there is a downloadable docker image that contains a basic web package.

Next, we download the docker image and import it into docker, so we may analyze the source code. We, however, have issues getting the image to run.

Alternatively, since the docker image is a tar archive, we extract the contents and find there are nested archives in each folder. We also extract those, so that we may look for interesting information that may be contained within the docker image.

In the a4ea7da8de7bfbf327b56b0cb794aed9a8487d31e588b75029f6b527af2976f2/layer/ folder, we find an SQLite database. Dumping the contents of it, we find there is a table that contains credentials. Connecting to the database, we are able to extract the password hash for the admin user.

Next, we use hashcat to crack the hash. For now, we save them in case we need them later.

Continuing our analysis of the docker image, we find a couple web apps in the 41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/layer/app/ directory. From 41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/layer/app/base/routes.py, we find an invite code check in the “/register” route. Using this information, we deduce this code (/app/base/) is for http://demo.bolt.htb as it requires and invite code to register, whereas http://bolt.htb/register does not.

Through further analysis, this code base appears to be for everything pre-login (login/registration). Since we have the invite code for http://demo.bolt.htb, we proceed to create an account, which might also create a “@bolt.htb” email address for us as well. Once created, we are presented with an admin view.

Next, we head over to http://mail.bolt.htb to check if we were indeed granted an email account. After our attempt to login, we are given access to Roundcube.

Going to the “Settings” page, we are told we will need email verification in order to update our personal information.

When we update our information, we check our inbox and are given a link to click that verifies the changes. After the changes are verified, we get another email that serves as a confirmation that the changes have been made. Notably, we see that whatever name we chose is reflected in the email.

Next, we want to look at the code for the email component for profile changes. Looking at 41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/layer/app/home/routes.py, we see that code that appears to be for post-login on http://demo.bolt.htb – mainly profile settings and the email components. Within the “/confirm/changes/<token>” route, we see that the name we supplied, is directly put into the template used for the email. This suggests that the email template is vulnerable to Server-Side Template Injection (SSTI).

Since we know jinja2 is the template engine used for this web app, we can quickly POC the vulnerability to confirm that vulnerability does exist. For this, we refer to PayloadsAllTheThings for a quick payload. After we supply the payload, and confirm the changes, we see that 7777777 is indeed reflected in our email – meaning the email generator is definitely vulnerable to SSTI.

To exploit this, we refer back to the cheatsheet and get a payload that uses popen() to execute commands. Using it, we confirm netcat is installed on the machine using which nc. Once confirmed, we start a netcat listener, and place our reverse shell payload in the name field of the profile settings form. Next, we submit the form, and wait for the email. After we click the confirmation link in the email, we get a reverse shell on the machine as the www-data user.

Getting User

Now that we have a connection on the machine as the www-data user, we begin our local enumeration. Looking around the machine, we find /var/www/demo/config.py which contains database credentials for the boltmail database. Using them to connect to the database, we do not find anything of particular interest. Trying the password against system users, we are unsuccessful with getting additional access.

Next, to speed up our enumeration, we run linpeas to automate enumeration. From its results, we find database credentials for both roundcube (http://mail.bolt.htb) and passbolt (https://passbolt.bolt.htb).

Taking a look at the databases, we see that passbolt’s database contains a lot of information that we may be able to leverage. Attempting to use the database password against system users, we get a shell as eddie using the su command. We are now able to read user.txt.

Getting Root

Now that we have a shell as eddie, we start enumerating for a path to privilege escalate.We run linpeas, and see a few interesting items for “private SSH keys”.

One of these seems particularly interesting as it’s a log file under an Extensions folder for Google Chrome. Taking a look at /home/eddie/.config/google-chrome/Default/Local Extension Settings/didegimhafipceonhjepacocaffmoppf/000003.log, we find references to passbolt, see a username of eddie@bolt.htb, and see there is a GPG private key.

Since the log file we found includes the link https://passbolt.bolt.htb in it, we decide to go back to the passbolt webpage. We are prompted for an email address, which we supply eddie@bolt.htb as we found in the log file. When we click the “Next” button, we are told to check our mailbox.

When we try to login into eddie‘s email account using the password we have, we find the password does not match. Next, we Google “passbolt account recovery no email” to see if we can recover the account without the email verification. In our research, we find this community post that states we can recover the token if we have database access. Following the instructions, we were able to get the token. Additionally, we got eddie‘s userid, since we will need it.

Going to https://passbolt.bolt.htb/setup/recover/<user_id>/<authentication_token.token> like the article states, we are told that we need to install an extension.

After we install the extension, we are prompted for the private key. Since we previously found a GPG private it, we format it, and paste it in the box. After we click “Next”, we are prompted to supply the passphrase.

To get the passphrase, we use gpg2john to get a crackable hash of the GPG private key, then use john to crack the hash.

After we supply the passphrase, we are chose to pick 3 characters and a color as our security token.

Once we select the security token, we are given access to eddie‘s pass vault. In it, we find credentials for root. Using the credentials to login as root, we are given a shell, and can 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!