Introducción
En este laboratorio, aprenderás sobre la inyección de Entidades Externas XML (XXE), una vulnerabilidad de seguridad web que permite a un atacante interferir en el procesamiento de datos XML de una aplicación.
El XXE se basa fundamentalmente en el comportamiento del analizador (parser). La aplicación cree que está procesando datos, pero el analizador XML también está procesando instrucciones adicionales incrustadas en ese formato de datos.
Cuando una aplicación web analiza una entrada XML sin deshabilitar correctamente la resolución de entidades externas, los atacantes pueden definir entidades personalizadas que apunten a archivos locales en el servidor. Al inyectar estas entidades maliciosas en la carga útil (payload) XML, el atacante puede obligar al servidor a leer archivos confidenciales (como /etc/passwd) y devolver su contenido en la respuesta HTTP. Te pondrás en la piel de un evaluador de seguridad para identificar un punto final (endpoint) XML, crear una carga útil maliciosa y extraer con éxito archivos del sistema.
Identificar el procesamiento de datos XML
En este paso, interactuaremos con una aplicación web local que ha sido configurada para este laboratorio. La aplicación se ejecuta en 127.0.0.1 en el puerto 5000 y tiene un punto final en /process que acepta datos XML.
XML (eXtensible Markup Language) es un formato popular utilizado para estructurar y transportar datos entre un cliente y un servidor. Antes de poder explotar una vulnerabilidad XXE, primero debemos confirmar que la aplicación realmente procesa la entrada XML y nos devuelve los datos analizados.
Esa primera confirmación es importante porque el XXE solo es posible cuando realmente ocurre un análisis XML. Muchos puntos finales aceptan texto, pero no todos tratan el cuerpo como XML.
Utilizaremos la herramienta de línea de comandos curl para enviar una solicitud HTTP POST al servidor. Una solicitud POST envía datos a la aplicación, y el encabezado Content-Type: application/xml le indica al servidor que interprete esos datos como XML en lugar de texto plano o JSON.
Ejecuta el siguiente comando en tu terminal para enviar una carga útil XML básica:
curl -X POST -H "Content-Type: application/xml" -d '<root><name>LabEx User</name></root>' http://127.0.0.1:5000/process
Deberías ver una salida similar a esta:
Hello, LabEx User!
Esta salida confirma dos cosas importantes. Primero, la aplicación analizó con éxito nuestros datos XML. Segundo, la aplicación extrajo el texto dentro de la etiqueta <name> y nos lo devolvió en la respuesta. Esta reflexión es crucial porque nos da una forma de ver los resultados de nuestras entidades inyectadas más adelante.
Interceptar la solicitud XML
En las pruebas de penetración del mundo real, los investigadores de seguridad a menudo utilizan herramientas de proxy como Burp Suite para interceptar y modificar solicitudes web. Dado que estamos trabajando completamente en la terminal, simularemos este proceso guardando nuestra carga útil XML en un archivo local. Esto hace que sea mucho más fácil editar e inyectar estructuras XML complejas de varias líneas sin lidiar con el complicado escape de caracteres en la línea de comandos.
Mover la carga útil a un archivo no es solo una conveniencia. Facilita el razonamiento y la revisión de entradas estructuradas complejas, lo cual es importante cuando la sintaxis misma afecta la explotación.
Creemos un archivo llamado payload.xml en nuestro directorio actual (~/project). Usaremos el editor de texto nano para crear y editar este archivo. Si no has usado nano antes, es un editor de texto simple basado en terminal que es muy adecuado para archivos pequeños como esta carga útil.
Abre el editor ejecutando:
nano payload.xml
Escribe o pega la siguiente estructura XML estándar en el archivo:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>Security Tester</name>
</root>
Guarda el archivo y sal del editor (en nano, presiona Ctrl+O, luego Enter para guardar, y Ctrl+X para salir).
Ahora, enviemos este archivo al servidor usando curl. El símbolo @ le indica a curl que lea los datos del archivo especificado en lugar de tratar la cadena literalmente.
Ejecuta el siguiente comando:
curl -X POST -H "Content-Type: application/xml" -d @payload.xml http://127.0.0.1:5000/process
Deberías ver la siguiente salida:
Hello, Security Tester!
Al mover nuestra carga útil a un archivo, hemos preparado un espacio de trabajo limpio para comenzar a crear nuestra inyección XXE en los siguientes pasos.
Definir una entidad externa (DOCTYPE)
Ahora que tenemos un archivo XML funcional, podemos comenzar a manipular su estructura. XML permite a los desarrolladores definir variables personalizadas llamadas "Entidades" dentro de una Definición de Tipo de Documento (DOCTYPE). Un DOCTYPE es una sección adicional cerca de la parte superior de un documento XML que describe reglas o valores reutilizables para el analizador.
Una entidad actúa como un atajo. Si defines una entidad llamada test con el valor Injected Data, cada vez que escribas &test; en tu documento XML, el analizador XML lo reemplazará con Injected Data. Si el analizador es vulnerable, procesará estas entidades personalizadas sin ninguna verificación de seguridad.
Este ejemplo inofensivo es importante porque demuestra que la expansión de entidades está habilitada antes de pasar a las entidades externas basadas en archivos.
Modifiquemos nuestro archivo payload.xml para incluir una declaración DOCTYPE y una entidad personalizada.
Abre el archivo nuevamente:
nano payload.xml
Actualiza el contenido del archivo para que coincida con el siguiente código:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY test "Injected Entity Data">
]>
<root>
<name>&test;</name>
</root>
Guarda el archivo y sal de nano (Ctrl+O, Enter, Ctrl+X).
En esta carga útil, definimos una entidad llamada test. Dentro de la etiqueta <name>, hicimos referencia a esta entidad usando &test;. Enviemos esta carga útil actualizada al servidor para ver si resuelve nuestra entidad personalizada.
Ejecuta el comando curl nuevamente:
curl -X POST -H "Content-Type: application/xml" -d @payload.xml http://127.0.0.1:5000/process
Deberías ver la siguiente salida:
Hello, Injected Entity Data!
El servidor reemplazó con éxito &test; con nuestra cadena personalizada. Esto demuestra que el analizador XML está resolviendo entidades activamente, lo que significa que es muy probable que sea vulnerable a la inyección de Entidades Externas XML (XXE).
Extraer archivos locales (/etc/passwd)
En el paso anterior, definimos una entidad interna. El verdadero peligro del XXE surge cuando definimos una entidad externa. Al usar la palabra clave SYSTEM, podemos instruir al analizador XML para que obtenga el valor de la entidad de una fuente externa, como una URL o una ruta de archivo local.
Si el analizador XML del servidor web está mal configurado, leerá el contenido del archivo que especifiquemos y lo incrustará en el documento XML. Dado que la aplicación refleja la etiqueta <name> hacia nosotros, podremos ver el contenido del archivo en la respuesta HTTP. Es por esto que la reflexión es tan valiosa para un atacante: convierte una lectura de archivos del lado del servidor invisible en una salida visible en el navegador o la terminal.
Intentaremos leer /etc/passwd, un archivo estándar de Linux que contiene información de cuentas de usuario. Este archivo es legible por todos los usuarios del sistema, lo que lo convierte en un objetivo común para probar vulnerabilidades de lectura de archivos.
Abre tu archivo de carga útil una última vez:
nano payload.xml
Modifica la definición de la entidad para usar la palabra clave SYSTEM y apunta al archivo local usando el protocolo file://:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
<name>&xxe;</name>
</root>
Guarda el archivo y sal de nano (Ctrl+O, Enter, Ctrl+X).
Ahora, envía la carga útil maliciosa al servidor:
curl -X POST -H "Content-Type: application/xml" -d @payload.xml http://127.0.0.1:5000/process
Si la explotación es exitosa, el servidor leerá el archivo /etc/passwd y devolverá su contenido en la respuesta. Deberías ver un gran bloque de texto similar a este:
Hello, root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
labex:x:1000:1000::/home/labex:/bin/zsh
!
¡Felicidades! Has explotado con éxito una vulnerabilidad de Entidad Externa XML para extraer archivos locales confidenciales del servidor web.
Resumen
En este laboratorio, aprendiste cómo identificar y explotar vulnerabilidades de Entidades Externas XML (XXE). Comenzaste verificando que una aplicación web procesa y refleja datos XML. Luego aprendiste cómo definir entidades XML personalizadas usando una declaración DOCTYPE. Finalmente, escalaste el ataque usando la palabra clave SYSTEM para crear una entidad externa, obligando al analizador XML del servidor a leer el archivo local /etc/passwd y devolver su contenido.
Para prevenir vulnerabilidades XXE, los desarrolladores deben asegurarse de que sus analizadores XML estén configurados para deshabilitar por completo la resolución de entidades externas y DTDs (Definiciones de Tipo de Documento).



