tom@home.htb:~$

Blog o HTB

6 November 2020

Zápis do prostoru, který se pak vykoná nebo použije pro autentizaci

Úvod a kontext

Jedna z nejčastějších analytických chyb po footholdu vypadá nevinně:

V mnoha prostředích je to naopak téměř hotový kompromis. Jakmile útočník dokáže zapsat do prostoru, který se později:

nejde už o „jen write“. Jde o přímou nebo téměř přímou cestu k dalšímu přístupu.

Právě tenhle pattern spojuje na první pohled různé případy:

O čem tenhle článek je a o čem není

Tenhle text se schválně překrývá s několika jinými tématy jen částečně.

Není to článek o nebezpečných upload funkcích. Tam je hlavní otázka, jak upload projde validační logikou a kdo ho interpretuje.

Není to ani článek o repozitáři a deployment trustu. Tam jde o to, že Git nebo historie konfigurace řídí důvěryhodný provozní proces.

Tady je hlavní abstrakce jiná:

Proč je „jen write“ tak podceňované

Důvod je jednoduchý. Lidé intuitivně hodnotí zápis jako slabší oprávnění než spuštění. Jenže to platí jen u inertních dat. Jakmile zapisovaný soubor později čte jiný proces s jinou logikou nebo jinými právy, write se mění na:

Prakticky je užitečné ptát se ne:

ale:

Varianta 1: write -> execute přes webroot

Devel je nejčistší ukázka. Anonymous FTP samo o sobě není shell. Rozhodující je až to, že FTP míří do prostoru, který servíruje IIS:

ftp-anon: Anonymous FTP login allowed
iisstart.htm

Jakmile lze do stejného prostoru zapsat ASPX soubor, další krok už není kreativní. Webserver soubor vykoná. Tady se write oprávnění okamžitě mění v execute.

To je důležitá lekce: write do webrootu není „souborový přístup“. Je to nepřímé RCE.

Varianta 2: write -> execute přes oficiální deploy kanál

Jerry stojí na trochu jiné verzi téhož principu. Tomcat Manager sice funguje jako legitimní administrativní rozhraní, ale z bezpečnostního pohledu je to pořád write do prostoru, který se pak vykoná.

Nahraný WAR není statický soubor. Je to artefakt, který aplikační server:

To je přesně ten důvod, proč veřejně přístupný Manager se slabým heslem znamená prakticky okamžité převzetí hostu. Write do deployment prostoru je už execute.

Varianta 3: write -> authenticate přes authorized_keys

Zetta ukazuje jinou, velmi praktickou variantu. Rsync export domácího adresáře roy dovolil nejen čtení, ale i zápis. Tím bylo možné podstrčit:

/home/roy/.ssh/authorized_keys

To je přesný příklad patternu write -> authenticate. Útočník nepotřebuje shell v době zápisu. Potřebuje jen zapsat do místa, které SSH později přijme jako důvěryhodný autentizační materiál.

Stejný princip se opakuje i jinde:

Varianta 4: write -> execute přes aplikaci nebo repo

Bitlab dobře ukazuje, že write nemusí směřovat jen do webrootu nebo deployment rozhraní. Jakmile kompromitovaný uživatel může změnit soubor:

profile/index.php

a běžící aplikace tuto změnu převezme, write se znovu mění v execute.

To už je blízké deployment trustu, ale důležitý je stejný sjednocující bod: útok nevyžaduje zranitelnost interpretru. Stačí změnit to, co interpret důvěryhodně načte a spustí.

Varianta 5: write -> privileged execute přes pomocný skript

Nibbles přidává ještě jednu vrstvu. Uživatel nibbler mohl přes sudo spustit:

/home/nibbler/personal/stuff/monitor.sh

Jestliže je tento soubor současně zapisovatelný, nejde už o „omezené sudo na konkrétní skript“. Jde o write do prostoru, který se později vykoná s vyššími právy.

To je velmi důležitý pattern při lokální analýze:

často znamená totéž jako přímé spuštění kódu pod cizí identitou, jen s malým zpožděním.

Jak tenhle pattern poznat systematicky

Když někde najdeš write přístup, má smysl projít tyto otázky:

1. Kdo ten soubor nebo adresář později čte

2. Jde o data, nebo o řídicí vstup

Bezpečnostně je nejrizikovější vše, co určuje:

3. Jak krátká je cesta od write k dopadu

Někdy je dopad okamžitý:

Jindy je odložený:

4. Je write lokální, síťový nebo přes aplikaci

Tohle je důležité pro obranu. Pattern je stejný, ale vstup se liší:

Co podobné případy spojuje

Na první pohled jde o různé technologie, ale všechny stojí na stejné důvěře:

Právě proto write často přeskakuje mezikrok, který by jinak byl potřeba:

Stačí dodat obsah na správné místo.

Obrana a hardening

1. Oddělit write prostor od execute a authenticate prostoru

Nejzákladnější pravidlo zní: uživatel nesmí zapisovat tam, odkud se později spouští kód nebo odkud se bere autentizační materiál.

2. Nepoužívat writable uživatelské cesty pro privilegované workflow

sudo skript, cron job nebo deployment krok nesmí číst z cesty, kterou může měnit neprivilegovaný účet.

3. Chránit deploy a auth soubory jako řídicí rovinu

authorized_keys, plugin adresáře, webrooty, hooky, playbooky a deployment artefakty nejsou obyčejná data. Jsou to řídicí vstupy bezpečnostního modelu.

4. Auditovat write oprávnění stejně pečlivě jako execute oprávnění

V řadě případů má write do citlivého místa téměř stejný dopad jako přímé execute. Kontrola oprávnění proto nesmí končit u toho, kdo smí spustit binárku.

5. Monitorovat změny v citlivých cestách

Zvlášť důležité je hlídat:

Shrnutí klíčových poznatků

Co si odnést do praxe

tags: file-write - execution - authentication - webroot - ssh - deployment