Seconda parte della serie sull'XML External Entity (XXE) in cui si esplorano i limiti e le soluzioni alternative

L'XML External Entity (XXE) è una vulnerabilità molto accessibile per poter essere sfruttata da un utente malintenzionato, tuttavia, ci sono casi in cui l'acquisizione di determinati file può essere difficile. Il seguente ne è un esempio:

L' /etc/fstab è un file che contiene alcuni caratteri che sembrano XML (anche se non lo sono). Ciò porterà il parser XML a provare ad analizzare questi elementi, solo per notare che non è un documento XML valido.

Di conseguenza, questo limita l'XML External Entity (XXE) nei seguenti modi:

> L'XXE può essere utilizzato solo per ottenere file o risposte contenenti XML "validi"
> L'XXE non può essere utilizzato per ottenere dei file binari

Soluzioni ai limiti dell'XML External Entities (XXE)

Un aggressore potrebbe essere in grado di aggirare le limitazioni sopra citate utilizzando alcuni intelligenti trucchi. Il problema principale che un aggressore deve affrontare con un attacco XML External Entities (XXE) è che è facile scontrarsi con un muro di mattoni quando si tenta di filtrare i file di testo inopportuni che non sono file XML validi (ad esempio file che contengono caratteri speciali XML come &, >).

La soluzione teorica

L'XML ha già una soluzione per questo problema in quanto esistono casi legittimi in cui è necessario memorizzare i caratteri speciali XML nei file XML. I caratteri XML speciali contenuti nei tag CDATA (dati dei caratteri) vengono ignorati dal parser XML.

Pertanto, in teoria, un utente malintenzionato potrebbe inviare una richiesta simile a quella riportata di seguito:

Tuttavia, risulta che ciò in realtà non funziona perché non è consentito dalla specifica XML includere entità esterne in combinazione con entità interne.

Entità di parametri

Gli aggressori, tuttavia, hanno ancora un asso nella machina che possono giocare - le entità di parametri.

Oltre alle entità generali, cioè quelle di cui abbiamo parlato finora, ci sono anche entità di parametri. Le entità di parametro sono uguali a entità regolari, ma vengono utilizzate solamente nelle DTD (Data Type Definitions). Per ulteriori informazioni riguardo le DTD, fate riferimento all'articolo precedente di questa serie.

Di seguito è descritto come si presenta un'entità del parametro. È lo stesso concetto di un'entità generale, salvo che esiste solamente all'interno delle DTD e inizia con un % come prefisso per far riconoscere al parser XML che essa è un'entità di parametro (non un'entità generale). Nell'esempio seguente, viene utilizzata un'entità di parametro per definire un'entità generale, che viene poi chiamata all'interno del documento XML.

Grazie all'esempio sopra riportato, un aggressore può prendere l'esempio teorico CDATA sopra e trasformarlo in un attacco funzionante creando una DTD maligna ospitata su attacker.com/evil.dtd.

Quando un attaccante invia la richiesta sopra citata, il parser XML cercherà inizialmente di elaborare l'entità di parametro % dtd facendo una richiesta a http://attacker.com/evil.dtd.

Una volta scaricata la DTD dell'attaccante, il parser XML caricherà l'entità di parametro del file % (da evil.dtd), che in questo caso è /etc /fstab. Quindi includerà il contenuto del file nei tag <! [CDATA []]> usando rispettivamente le entità del parametro %start e %end e le memorizzerà in un'altra entità di parametro denominata %all.

Il cuore del trucco è che %all crea un'entità generale denominata &fileContents;, che può essere inclusa come parte della risposta all'attaccante.

Nota: è da tenere presente che un utente malintenzionato può utilizzare solo entità di parametro all'interno del DTD e non all'interno del documento XML.

Il risultato è una risposta all'attaccante con il contenuto del file (/etc/fstab) contenuto in un tag CDATA.

Wrapper del protocollo PHP

Nei casi in cui l'applicazione web vulnerabile all'XML External Entity (XXE) sia un'applicazione PHP, alcuni nuovi vettori si aprono in termini di che cosa può fare un aggressore, grazie ai wrapper del protocollo PHP. I wrapper del protocollo PHP sono flussi di I/O che consentono l'accesso ai flussi di input e output del PHP.

Un utente malintenzionato può utilizzare il wrapper del protocollo php://filter a Base64 per codificare il contenuto di un file. Poiché il Base64 sarà sempre trattato come un XML "valido", un utente malintenzionato può semplicemente codificare i file sul server e quindi decodificarlo alla fine della ricezione. Inoltre, questo metodo ha anche l'ulteriore vantaggio di consentire a un aggressore di rubare i file binari.