tom@home.htb:~$

Blog o HTB

11 November 2020

XXE a XML workflow

Úvod a kontext

XXE se často vysvětluje jako chyba XML parseru, který dovolí načítat externí entity. To je technicky správně, ale pro praxi trochu málo. V běžném provozu totiž XML málokdy vstupuje do systému jako “libovolný XML dokument”. Obvykle je schované ve formuláři, trackeru, importu, dokumentovém workflow nebo převodníku, který vývojář nepovažuje za exponovanou attack surface.

Právě proto dává smysl mluvit o XML workflow, ne jen o parseru. Útočník totiž obvykle neútočí na XML jako takové. Útočí na podnikový nebo aplikační proces, který XML přijímá, rozbaluje, převádí nebo jinak zpracovává s větší důvěrou, než si zaslouží.

Proč je XML pořád relevantní

Mnoho týmů má pocit, že XXE patří spíš do starších technologií. Jenže XML se stále objevuje v celé řadě míst:

To znamená jednoduchou věc: i když veřejné API působí moderně, uvnitř může pořád běžet parser, který umí:

Kde se XXE v praxi schovává

XXE nevzniká jen tam, kde aplikace explicitně přijme application/xml. Často se objeví ve workflow, která na první pohled nevypadají jako XML:

Právě to je důležité i pro audit. Nestačí se ptát, jestli aplikace “má XML endpoint”. Je potřeba se ptát, kde všude nějaká komponenta XML nakonec opravdu parsuje.

Co XXE ve skutečnosti dovolí

XXE se vyplatí chápat podle dopadu, ne podle syntaxe payloadu.

1. File read

Nejběžnější dopad je čtení lokálních souborů. To je stále nejpraktičtější varianta, protože vede ke:

Typický didaktický příklad vypadá takto:

<?xml version="1.0"?>
<!DOCTYPE bugreport [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<bugreport>
  <title>test</title>
  <reward>&xxe;</reward>
</bugreport>

Samotné /etc/passwd ale nebývá cílem. Je to jen potvrzení, že parser čte lokální soubory a že dává smysl sáhnout po db.php, .env nebo jiném provozním artefaktu.

2. SSRF do dalších služeb

Pokud parser dovolí externí entity přes http://, nevzniká jen file read, ale i SSRF. To bývá důležité hlavně ve chvíli, kdy:

XXE tak nemusí končit u jednoho souboru. Může se stát síťovým pivotem.

3. Potvrzení chování dokumentového backendu

V některých řetězcích XXE sama nevydá finální shell, ale potvrdí, že převodník nebo importní backend skutečně:

To je cenné hlavně u složitějších workflow, kde je XXE první důkaz, že dokumentová pipeline stojí na slabých předpokladech a zaslouží si hlubší test.

Jak tenhle vzorec vypadal v konkrétních případech

V jednom případě šlo o tracker endpoint, který přijímal base64-encoded XML a přes DOMDocument ho načítal s povolenými entitami. Praktický dopad nebyl v tom, že by parser “vrátil /etc/passwd”. Rozhodující bylo až čtení lokálního db.php, z něhož vypadlo heslo použitelné pro SSH účet development. XXE tedy nevedla přímo k RCE, ale otevřela nejkratší cestu k tajemství, které už shell zajistilo.

Jiný případ stál na dokumentovém převodníku a veřejně dostupných artefaktech, z nichž šlo odvodit, že backend pracuje s kancelářským dokumentem jako se ZIP strukturou obsahující XML. Škodlivý docx s externí entitou tam posloužil jako potvrzení, že převodník opravdu expanduje entity a že dokumentové workflow stojí na nebezpečném parseru. Samotný shell pak přišel jinou cestou nad stejným převodníkem, ale XXE byla klíčová pro správné čtení architektury celé funkce.

Co při analýze hledat

Při review nebo testu se vyplatí projít několik konkrétních otázek.

Kde se XML do systému dostává

Jaký parser a jaké volby se používají

Jaká práva má proces, který XML čte

Co parser dělá s výsledkem

Proč “zakázat externí entity” není celý příběh

Tohle doporučení je správné, ale samo o sobě nestačí jako mentální model.

První problém je, že XML bývá ukryté ve workflow, které si tým jako XML ani nepojmenuje.
Druhý problém je, že i správně opravený parser nemusí vyřešit celou dokumentovou pipeline, pokud:

Jinými slovy: XXE je často první symptom, že hranice kolem dokumentového nebo importního workflow je navržená příliš volně.

Obrana a bezpečnější návrh

1. Zakázat externí entity a DTD tam, kde nejsou nezbytné

To je základ. Parser nemá číst externí entity jen proto, že to “umí”. Pokud aplikace nepotřebuje DTD, nemá být zapnuté.

2. XML parser chápat jako bezpečnostní hranici

Proces, který zpracovává XML nebo dokumenty obsahující XML, nemá běžet s přístupem k citlivému filesystemu a k interní síti. I když dojde k chybě parseru, dopad má zůstat omezený.

3. Auditovat i skrytá XML workflow

Bezpečnostní review musí zahrnout:

4. Nevracet parser output slepě do odpovědi

Pokud aplikace přímo vypisuje zpracovaný XML obsah do response nebo do dalšího kroku workflow, stává se z parseru mnohem pohodlnější file-read kanál.

5. Tajemství uložená vedle aplikace považovat za okamžitě ohrožená

Jakmile je možný XML-based file read, jsou .env, db.php, config.yml a podobné soubory prakticky první cíle. Obrana musí počítat s tím, že parser bug rychle eskaluje na credential leak.

Shrnutí klíčových poznatků

Co si odnést do praxe

tags: xxe - xml - web - parser