domingo, 11 de febrero de 2018

XML eXternal Entity (you can call me XXE)



Hola a todos, como siempre me pierdo por un largo tiempo entre post y post. Por suerte me encontré devuelta (jeje) y con un tiempito para dedicar una entrada a uno de los nuevos puntos del OWASP Top Ten: XML External Entity

De que se trata esta vulnerabilidad?

Para hablar de XXE, es necesario realizar una breve introducción a XML y al uso de entidades externas.

eXtensible Markup Language o XML es un metalenguaje, es decir, un lenguaje para describir otros lenguajes (un minuto cerebrito). A diferencia de HTML, este metalenguaje, es utilizado para definir como debe ser estructurada la información.

XML utiliza etiquetas como HTML, pero estas etiquetas no son predefinidas. La persona que crea el documento XML define sus propias etiquetas. Por ejemplo:

<?xml version="1.0" encoding="UTF-8"?>
<pagos>
   <pago>
      <titulo>Pagar multa</titulo>
      <monto>10000</monto>
      <responsabilidad optional="1">pagar</responsibilidad>
   </pago>
</pagos>

A diferencia de HTML, todas las etiquetas o tags deben tener su correspondiente tag de cierre

<pagos></pagos>

Como los tags, a diferencia de HTML, se pueden definir, como podemos saber si un documento XML es válido?

El famoso DTD

Un documento XML es válido cuando sigue las reglas generales de XML y concuerda (matchea) con su DTD. El DTD o Document Type Definition es un documento en el cual se definen los tags a utilizar y es desarrollado por el diseñador de XML.

Un DTD para nuestro docunento de arriba luce de la siguiente manera:

<!ELEMENT Pagos (Pago)*>
<!ELEMENT Pago (Titulo, Monto, Responsabilidad)>
<!ELEMENT Titulo (#PCDATA)>
<!ELEMENT Monto (#PCDATA)>
<!ELEMENT Responsabilidad (#PCDATA)>
<!ATTLIST Responsabilidad optional CDATA "0">

Entre los tags utilizados para armar un DTD existen dos que son muy importantes y que están involucrados en esta vulnerabilidad. Ellos son !DOCTYPE y !ENTITY

El tag !DOCTYPE nos sirve para definir un DTD dentro o fuera del documento XML

Si queremos incluir el DTD en nuestro documento, el mismo quedaría de la siguiente manera:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Pagos [
<!ELEMENT Pagos (Pago)*>
<!ELEMENT Pago (Titulo, Monto, Responsabilidad)>
<!ELEMENT Titulo (#PCDATA)>
<!ELEMENT Monto (#PCDATA)>
<!ELEMENT Responsabilidad (#PCDATA)>
<!ATTLIST Responsabilidad optional CDATA "0">
]>
<pagos>
   <pago>
      <titulo>Pagar multa</titulo>
      <monto>10000</monto>
      <responsabilidad optional="1">pagar</responsibilidad>
   </pago>
</pagos>

Esto sería un Internal DTD Declaration

Si quisieramos incluir las definiciones en un DTD externo utilizariamos:

<!DOCTYPE Pagos SYSTEM "pagos.dtd">

Bueno bueno, pero que pasa con el tag ENTITY que es tan peligroso?

El tag ENTITY nos permite crear "atajos". 

Pensemos lo siguiente:

Que pasaría si quisiera incluir, por ejemplo, una URL donde realizar el pago de la multa (asi de una vez por todas el deudor paga) en distintos documentos XML. Habría que escribir la misma cada vez que quiera hacerlo. Ahi es donde entra en juego el tag !ENTITY el cual hace que el parser obtenga el contenido de ahi y lo inserte en el documento.

Un ejemplo de como funciona el tag !ENTITY lo podemos ver en:

https://www.w3schools.com/xml/xml_dtd_entities.asp


Una entidad, como podemos ver en w3 schools, puede ser declarada internamente o estar en un archivo externo. Para indicarle que busque la definición en un archivo externo lo hacemos de la siguiente manera:

<!ENTITY entity-name SYSTEM "URI/URL">

Y acá empieza el problema...Ahi donde vemos URI/URL podemos elegir entre varios schemas para indicar a la entidad a que archivo recurrir. 

Podemos por ejemplo, definir lo siguiente:

<!ENTITY xxe SYSTEM "file:///etc/passwd">

Ahhhh, ahora veo adonde vamos con todo esto.

Si no se encuentra configurado correctamente, el paser XML irá a buscar el archivo especificado y devolverá la información en él contenida. Esto lo podremos lograr siempre y cuando la aplicación esté diseñada para mostrar información en el response. Pero hay otra forma de obtener esa información si no es mostrada en la respuesta. Mas abajo veremos como.

Con este tipo de ataques podemos obtener información sensible del servidor, realizar denegaciones de servicio y, en algunas ocasiones, hasta un RCE.

Pasemos ahora a un ejemplo de explotación de XXE.

Para realizar esta desmotración, utilicé la VM vulnerable de Pentester Labs, la cual pueden descargar desde:

https://pentesterlab.com/exercises/play_xxe/iso

En este ataque se levanta un servidor web en el equipo del atacante. En este servidor malicioso tendremos un dtd que contendrá instrucciones para que el parser xml del equipo víctima acceda al archivo passwd y nos envíe la información a otro puerto que tendremos a la escucha.

El esquema queda de la siguiente forma:

Pueden probar todo esto paso a paso siguiendo el turorial, para la VM mencionada, de aquí:

https://pentesterlab.com/exercises/play_xxe/course

Por último, les dejo un video en el que recreo el ataque:




Saludos y..

Happy XXE Hacking!