(Ver partes I, II y III de esta serie)
En el anterior post conseguimos obtener el SWF original, pero descubrimos que el exploit se encuentra incrustado en un ByteArray. ¿Conseguiremos extraerlo?
Primeramente necesitamos extraer el contenido almacenado por el ByteArray. Para ello, necesitamos un decompilador Flash de escritorio; Adobe SWF Investigator (It’s free!). Una vez instalado abrimos el último fichero obtenido: uncompressed_exploit.swf. Vamos a la ficha “Tag Viewer” y de todos los tags mostrados, seleccionamos “DefineBinaryData” y lo guardamos pulsando en “Dump to file” nombrado como “dump_exploit.bin”, por ejemplo.

Miramos el fichero “dump_exploit.bin” hexadecimalmente y nos fijamos en los tres primeros bytes, ya que si es un fichero Flash estos han de ser 5a 57 53 (ZWS) o 43 57 53 (CWS) o 46 57 53 (FWS) según lo que hemos estado viendo anteriormente.
$ hexdump dump_exploit.bin -n 3 -C 00000000 0e 03 07 |...| 00000003
Pero como sabemos, a estos bytes se les ha aplicado XOR para complicar su análisis. Según se ve en el código ActionScript, han usado el carácter “T” para realizar el cifrado XOR a cada byte. Por lo tanto, probamos a realizar la operación desde una consola Python con estos primeros bytes:
>>> ord("T") # Valor decimal en ASCII.
84
>>> chr(int('0x0e',16)^84) # 0x0e XOR 84
'Z'
>>> chr(int('0x03',16)^84) # 0x03 XOR 84
'W'
>>> chr(int('0x07',16)^84) # 0x07 XOT 84
'S'
‘Z’, ‘W’, ‘S’… ¿De qué nos suena? ¡Es un fichero SWF comprimido con LZMA como en la tercera parte de esta serie!
Rápidamente, desarrollamos un script que aplique XOR a todos los bytes del fichero binario.
#!/usr/bin/python
# -*- coding: utf-8 -*-
key = "T"
data_in = "dump_exploit.bin"
data_out = "out.bin"
file_in = open(data_in, "rb")
file_out = open(data_out, "wb")
while 1:
byte = file_in.read(1) # Lectura byte a byte.
if not byte: break
xor = chr(int(hex(ord(byte)), 16) ^ ord(key)) # Aplica operación XOR.
file_out.write(xor) # Guarda en un fichero el resultado de la operación.
file_in.close()
file_out.close()
Una vez ejecutado, obtenemos un fichero binario llamado “out.bin”.
$ file out.bin out.bin: data $ hexdump out.bin -n 128 -C 00000000 5a 57 53 17 f9 4d 00 00 f0 1b 00 00 5d 00 00 20 |ZWS..M......].. | 00000010 00 00 3b ff fc 8e 19 fa df e7 66 08 a0 3d 3e 85 |..;.......f..=>.| 00000020 f5 75 6f d0 7e 61 35 1b 1a 8b 16 4d df 05 32 fe |.uo.~a5....M..2.| 00000030 a4 4c 46 49 b7 7b 6b 75 f9 2b 5c 37 29 0b 91 37 |.LFI.{ku.+\7)..7| 00000040 01 37 0e e9 f2 e1 fc 9e 64 da 6c 11 21 33 ed a0 |.7......d.l.!3..| 00000050 0e 76 70 a0 cd 98 2e 76 80 f0 e0 59 56 06 08 e9 |.vp....v...YV...| 00000060 ca eb a2 c6 db 5a 86 7b 47 de 99 5d 68 76 38 16 |.....Z.{G..]hv8.| 00000070 bd 93 3c d3 d0 9e d3 55 63 5a da b0 db 27 e6 7c |..<....UcZ...'.|| 0000008
Al tratarse de un caso similar al original (ver la tercera parte), se procede de la misma manera:
$ python swfzip.py out.bin exploit.swf
info : Input file: out.bin
info : Output file: exploit.swf
info : Reading out.bin
info : lzma compressed swf detected.
info : Filesize in signature: 19961
info : Filesize decompressed: 19961
info : Generating uncompressed data
info : Compressing with zlib
info : Packing zlib header
info : Generating compressed data
File compressed with zlib, size decreased: -21%
Notice: Recompressing may cause filesize increased
$ file exploit.swf
exploit.swf: Macromedia Flash data (compressed), version 23
$ ./uncompress.sh exploit.swf
uncompressing to ./uncompressed_exploit.swf
$ file uncompressed_exploit.swf
uncompressed_exploit.swf : Macromedia Flash data, version 23
$ hexdump uncompressed_exploit.swf -n 128 -C
00000000 46 57 53 17 f9 4d 00 00 78 00 04 e2 00 00 0e a6 |FWS..M..x.......|
00000010 00 00 18 01 00 44 11 19 00 00 00 7f 13 76 01 00 |.....D.......v..|
00000020 00 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 |...
¡Tachán! ¡Ya tenemos el exploit! Vamos a decompilarlo usando de nuevo http://www.showmycode.com/ obteniendo el siguiente código ActionScript.
Le echamos un ojo y... ¡WOW! ¡Es una **** locura!
Investigando sobre el código, pueden observarse que hay varios métodos utilizados para comprobar la versión de Flash:

Normalmente, la comprobación de la versión de Flash se hace mediante funciones Javascript pero en este caso, al estar ejecutando este Flash directamente desde memoria, evades que un antivirus detecte dichos Javascripts durante la navegación.
Asimismo, vemos que lee los parámetros FlashVars y recoge la variable “exec”:

Ésta es procesada por diferentes métodos hasta llegar a uno usando como nombre de parámetro “url”. ¿Entonces la variable “exec” contiene la URL para la descarga del binario que realmente hace la infección del equipo?

Es una teoría, pero puede probarse fácilmente lanzando el exploit en un entorno vulnerable y modificando esta parte del payload desde HTML, viendo la solicitud que realiza.
Sin modificar el payload...

...se procede a ejecutar el exploit y éste realiza correctamente la petición de descarga a lo que es el bicho malo-malísimo (5) BV4NBkQDAQ9SHwMfBh1SDFcCDwBRBVcHHVUOSwABAE0FUBlQUg0ZBkVnFHwARhgzRFc

Pero ahora, si se modifica el payload cambiando unos cuantos bytes por otros...

...la solicitud cambia...

...quedando demostrada la teoría anterior.
Si se sigue tirando del hilo sobre el código, se llega a la parte más importante donde se observa que el exploit utilizado es el referente al CVE-2015-0311 el cual se explica detalladamente aquí.
Pueden verse el string “uncompress” y como genera el string “compress”...
![]()
...que son utilizados en las partes más críticas del exploit:


Y que como pueden verse, son muy similares al ejemplo enlazado más arriba. Finalmente, se puede subir alguno de los ficheros Flash a Virustotal y confirmar que el exploit utilizado es el correspondiente al CVE-2015-0311.

¡Saludos!

Gran serie de posts.
Muchas Gracias Adrián muy interesante
Gracias a ti J. J.
Saludos!!