Jump Ahead: Enum – Getting a Foothold – User – Root – Resources
To solve this machine, we begin by enumerating open ports using
nmap – finding ports
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 –
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
Like all machines, we begin by enumerating open ports using
nmap. From our scans, we find ports
$ 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 10.129.224.80 Nmap scan report for 10.129.224.80 Host is up (0.065s latency). PORT STATE SERVICE VERSION 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) HOP RTT ADDRESS 1 66.54 ms 10.10.14.1 2 66.69 ms 10.129.224.80 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
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
443 with tools like
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
mail.bolt.htb. For the time being, we add them to our
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.
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.
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
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
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 (
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
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
email@example.com, 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
firstname.lastname@example.org 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.
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
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!