tom@home.htb:~$

Blog o HTB

25 November 2020

Fatty

Úvod a kontext

Fatty je stroj, kde hlavní vstup neleží ve webu, ale v distribuovaném Java klientu. Ten je veřejně dostupný přes anonymní FTP, spoléhá na starý Java 8/TLS stack a po dekompilaci rychle ukáže, že aplikace není navržená bezpečně ani na klientské, ani na serverové straně.

Řetězec stojí na třech navazujících vrstvách. Nejdřív je potřeba klient vůbec rozchodit a porozumět jeho protokolu. Pak z interních poznámek a MITM logů vyplyne SQL injection v přihlašování. A teprve po přihlášení dává smysl stáhnout serverovou část a zneužít nebezpečnou Java deserializaci. Root část už pak není o Java exploitu, ale o klasické wildcard injection do tar v root cron jobu.

Počáteční průzkum

FTP s klientem a interními poznámkami

První nmap hned ukáže, že nejzajímavější službou není SSH, ale anonymní FTP s klientem fatty-client.jar a třemi textovými poznámkami. Současně jsou otevřené tři TLS porty 13371339, takže je zřejmé, že aplikace komunikuje mimo běžný webový protokol.

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
21/tcp   open  ftp                vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed
| -rw-r--r--    1 ftp ftp 15426727 Oct 30 12:10 fatty-client.jar
| -rw-r--r--    1 ftp ftp      526 Oct 30 12:10 note.txt
| -rw-r--r--    1 ftp ftp      426 Oct 30 12:10 note2.txt
| -rw-r--r--    1 ftp ftp      194 Oct 30 12:10 note3.txt
22/tcp   open  ssh                OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
1337/tcp open  ssl/waste?
1338/tcp open  ssl/wmc-log-svc?
1339/tcp open  ssl/kjtsiteserver?

Poznámky samy o sobě prozradí tři důležité věci: server byl přesunut z 8000 na 1337, klient pořád vyžaduje Java 8 a dočasné přihlašovací údaje jsou qtc / clarabibi.

Rozchození klienta a TLS proxy

Klient po stažení nejde jen spustit. Je potřeba mu upravit cílový port, použít Java 8 a přizpůsobit se starému TLS nastavení. sslscan ukáže jen TLSv1.0 a cipher AES128-SHA, takže běžné moderní proxy selhávají, pokud se výslovně nepřepnou do kompatibilního režimu.

update-alternatives --config java
sslscan 10.10.10.174:1337
=> Accepted TLSv1.0 128 bits AES128-SHA

Po dekompilaci klienta navíc vyjde najevo, že TrustedFatty.java pracuje s klientským certifikátem fatty.p12 chráněným heslem secureclarabibi123. To dovolí certifikát rozbalit a postavit MITM přes sslsplit, takže je možné číst vlastní aplikační protokol.

openssl pkcs12 -in fatty.p12 -nocerts -out fatty.key
openssl pkcs12 -in fatty.p12 -clcerts -nokeys -out fatty.crt
sslsplit -k fatty.key -c fatty.crt -Z -D -P -L con.log -r tls10 -s AES128-SHA ssl 127.0.0.1 8000 10.10.10.174 1339

Analýza zjištění

Co prozradí MITM log

MITM zde není samoúčelné. Log ukáže nejen úspěšné přihlášení qtc, ale i strukturu interního úložiště notes a mail. V security.txt je zmínka o proběhlém penetračním testu a v dave.txt ještě důležitější informace: administrátorské účty byly kvůli bezpečnostním problémům odstraněné a proti loginu přibyl timeout, aby se zhoršily time-based SQL injection útoky.

To je silná indicie, že chyba v autentizaci stále existuje, jen už nejde zneužít nejjednodušším způsobem. Přesně proto dává smysl testovat klasické login bypass payloady místo slepého fuzzingu celého protokolu.

Login bypass a server-side deserializace

Payload qtc' or '1'='1' or ''=' v logu vede k úspěšnému přihlášení, takže SQL injection ve vstupu pro login je potvrzená. Tím se otevře přístup do klienta a k serverovým artefaktům. Jakmile je k dispozici serverová část aplikace, je vidět i druhá zásadní chyba: funkce changePw deserializuje objekt ClientCredential bez bezpečnostních omezení.

To mění způsob práce. Místo dalšího lámání SQLi už dává smysl připravit serializovaný payload přes ysoserial a poslat ho přes rutinu pro změnu hesla. Po úpravě objektu tak, aby se tvářil jako požadavek skupiny admins, server payload zpracuje a spustí příkaz pro reverzní shell.

Získání přístupu

Shell jako qtc

Po doručení serializovaného payloadu do changePw vznikne shell jako qtc. Důležitější než samotný shell je tady to, proč fungoval: SQL injection jen otevřela dveře do aplikace, ale skutečnou RCE přinesla až deserializace neověřeného objektu na serveru.

Eskalace oprávnění

Wildcard injection do root záloh

Lokální eskalace už nemá s Javou nic společného. Root cron job pravidelně vytváří zálohy přes tar nad obsahem, který může qtc ovlivnit. To je klasický scénář pro wildcard injection: pokud se v archivovaném adresáři objeví soubory pojmenované jako parametry tar, root je při dalším běhu interpretuje jako volby.

V praxi stačí připravit shell skript a k němu soubory, které zneužijí checkpoint mechaniku tar. Při dalším běhu cron se shell skript spustí s root právy a otevře finální shell.

Shrnutí klíčových poznatků

Co si odnést do praxe

tags: linux - sql-injection - ssh - java - exploit - enumeration