I began with a simple scan, to check the ports of the machine.

$ rustscan -a 

I went to the website that is being hosted on port 80, and I saw that there is some sort of PGP stuff. Furthermore, I noticed the following URLs:

https://ssa.htb/pgp # the site's public key
https://ssa.htb/guide # some sort of playground for PGP

In the /guide endpoint there is some sort of playground for PGP, and while I was playing with it, I have noticed that when I am using the verify signature there is output that looked like pulled from the console.

I’ve enumerated the technologies and versions that the website is using, I found that it used Flask as the main server application and (possibly Flask for the frontend/templating engine).


When I saw Flask I thought that the application could be using Jinja, so I immediately thought that this could be a potential SSTI. I had only a single entry point that could give me output which was through Verify Signature in the /guide endpoint.

Crafting the exploit

The injection point is the name of the PGP key, so I’ve generated a key called syl.

$ gpg --gen-key

The exploit is described/explained here.

After that, we need to export the public key using this command:

$ gpg -a -o public_key.key --export syl

then we should craft an arbitrary message:

$ echo 'test' | gpg --clear-sign

Common Issues

While crafting this, I’ve experienced serious hassles such as:

  • wrongfully crafting the message
  • using different key to encrypt the message

I fixed those issues when I started clean and using only 1 key, and whenever asked for anything “passphrase/name” I just typed “syl”.

To check the current keys that you have:

$ gpg --list-keys

Another useful website is this one: https://www.sobyte.net/post/2021-12/modify-gpg-uid-name/ I’ve used the article to modify the name of the key, and then to export the public key again.

Upon crafting the message, paste the message and the public key and click to verify the signature, this would get you a reverse shell to the machine.

Atlas (firejailed)

The user that we got atlas is actually is firejailed, commands such as wget/curl are not available in the environment. The pivot point is in the httpie directory in the $HOME folder. There you can find the admin.json file where the SSH credentials for the user silentobserver are.


I ran linpeas.sh to check where would my next pivoting point would be, I stumbled fairly fast on these files that I could write:


I noticed the application located in the /opt directory /opt/tipnet/ I’ve examined the source code, and it is some sort of rust application, I already got a hint to those writable directories and whenever I saw the source code:

extern crate logger;
logger::log(username, keywords.as_str().trim(), justification.as_str()); // Invoking it later on.

I knew that I could modify the crate that could be executed by the application.

But what is this application? And where is it running?

Tipnet Application

This application is running like that:

/bin/sh -c cd /opt/tipnet && bin/echo "e" | /bin/sudo -u atlas /usr/bin/cargo run --offline sleep 10

We can see the user atlas(not firejailed) is running it, so this could be our next attack vector.

I’ve crafted a rust reverse shell: https://doc.rust-lang.org/std/process/struct.Command.html and added it into the logger/src/lib.rs file then I build the crate using cargo build.

After some seconds, your listener should be getting a connection from the server, that would be the atlas user.

Atlas user to root

Fairly simple and straightforward, this is a CVE-2022-31214 vulnerability. You can use the already crafted exploits for that:

There are issues with that exploit, I believe it is in the wait mechanism. To make sure that it is working correctly add a breakpoint() in the beginning of the script then you can follow the execution by pressing “n”.