Cómo explotar una vulnerabilidad XSS con JavaScript e “imágenes políglotas”
¿Qué es un archivo políglota?
Los políglotas, en un contexto de seguridad, son archivos que tienen una forma válida de múltiples tipos de archivos diferentes. Por ejemplo, un GIFAR es un archivo GIF y JAR. También existen archivos que pueden ser tanto GIF como JS, tanto PPT como JS, etc.
Los archivos políglotas a menudo se usan para evadir la protección según los tipos de archivos. Muchas aplicaciones que permiten a los usuarios cargar archivos solo permiten subir de ciertos tipos, como JPEG, GIF, DOC, para evitar que los usuarios carguen archivos potencialmente peligrosos como archivos JS, archivos PHP o archivos Phar.
Por lo tanto, las aplicaciones realizan comprobaciones de filtrado de extensiones como extensiones dobles (.jpg.php) o el uso de bytes nulos en la extensión (.php% 00.jpg), nombres de archivo (.htaccess, .config, etc.) y si la firma del archivo cargado también coincide con su tipo de contenido.
Las diferentes aplicaciones utilizan métodos diferentes para ello y se pueden usar imágenes políglotas para evadir algunas de estas comprobaciones de validación.
Estructura JPEG
Una imagen JPEG se representa como una secuencia de segmentos donde cada segmento comienza con un encabezado. Cada encabezado comienza con algún byte. El payload seguido por el encabezado es diferente según el tipo de encabezado. Los tipos de marcadores JPEG comunes te los mostramos a continuación:
0xffd8: “Start of Image”, 0xffe0: “Application Default Header”, 0xffdb: “Quantization Table”, 0xffc0: “Start of Frame”, 0xffc4: “Define Huffman Table”, 0xffda: “Start of Scan”, 0xffd9: “End of Image”
Cada archivo binario contiene un par de encabezados. Son muy importantes para un archivo ya que definen información específica de un archivo. La mayoría de los encabezados van seguidos de información sobre la longitud. Esto nos dice qué tan largo es ese segmento en particular.
El inicio del encabezado de la imagen contiene FF D8
. Si no lo vemos, podemos suponer que se trata de otro archivo. Otro marcador importante es FF D9
que indica el final de la imagen.
Para hacer que el payload se vea como un archivo JPEG legítimo, agregaremos la longitud del encabezado, el encabezado del comentario, bytes nulos para rellenar y luego nuestro vector de ataque de JavaScript.
Digamos que el vector de ataque es */=alert(“XSS”)/*
. Al convertirlo en hexadecimal se verá así.
El payload en hexadecimal:
2A 2F 3D 61 6C 65 72 74 28 22 58 53 53 2E 22 29
Podemos usar un editor hexadecimal para inyectar Javascript en los metadatos de la imagen. Esto funciona porque los navegadores interpretan el código cuando procesan la imagen en HTML.
Tengo una imagen test.jpg
y debajo está el registro hexadecimal de test.jpg. Con la ayuda del editor ghex
, vamos a reemplazar algunos caracteres hexadecimales y guardarlos.
Como sabemos, el primero FF D8
es el comienzo de la imagen, los dos bytes siguientes representan los dos bytes siguientes, 00 10
representa la longitud del encabezado JPEG que en equivalente decimal es de 16 bytes.