Destripando Nuclear EK (IV)

(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.

imagen_6

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:

imagen_7

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”:

imagen_8

É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?

imagen_9

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...

imagen_10

...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

imagen_11

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

imagen_12

...la solicitud cambia...

imagen_13

...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”...

imagen_14

...que son utilizados en las partes más críticas del exploit:

imagen_15

imagen_16

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.

imagen_17

¡Saludos!

Ver también en:

Comments

  1. Gran serie de posts.
    Muchas Gracias Adrián muy interesante

  2. Adrián Macías says

    Gracias a ti J. J.
    Saludos!!