lunes, 23 de diciembre de 2013

Descifrando la configuración de un troyano PiceBOT 2.0

A diario, en el laboratorio de Hispasec, analizamos una gran cantidad de muestras de diferentes familias. Entre ellas, este año hemos añadido un nuevo integrante a la familia de "Hosts Modifier", concretamente PiceBOT en su versión 2.0. PiceBOT es una familia de troyanos orientados al robo de credenciales bancarias. La versión 1.5 de PiceBOT hizo su aparición a principios de año, concretamente fue Kaspersky quien lo reportó.

Las distintas familias de malware que englobamos dentro de "Hosts Modifier" utilizan una técnica sencilla cuando infectan un sistema, simplemente cambian el archivo host del equipo para redirigir las resoluciones DNS de ciertos dominios hacia un servidor controlado por el atacante. Un envenenamiento de la caché local del equipo.

Adicionalmente, los PiceBOT "zombifican" el sistema añadiéndolo a una botnet y quedando el equipo a la espera de órdenes enviadas desde el centro de control (C&C). Sin embargo, una información de tanto valor como la URL del C&C, no se encuentra en claro en el binario. En este articulo, veremos cómo automatizar su análisis de manera estática, es decir cómo extraer los C&C sin necesidad de ejecutar el PiceBOT. Esto proceso es sumamente importante de cara a automatizar el estudio y análisis de esta familia.

En primer lugar, vamos a ver cómo extraer las cadenas cifradas automáticamente dentro del binario. Una vez extraídas, vamos a diseñar una rutina para descifrarlas. Finalmente veremos cómo automatizar el proceso de descifrado con un script en python para extraer las cadenas sin necesidad de ejecutar el troyano.

Para obtener las cadenas del programa, usaremos el comando "strings -a -e l" que nos permite de extraer todas las cadenas del programa codificadas en formato Unicode. Podemos ver que las cadenas en formato hexadecimal aparecen cifradas, por eso nos interesan especialmente, porque seguramente incluyan información importante para su estudio, como la URL del C&C, entradas del registro, nombres de ficheros, etc.

51934B4E6E534C311AB35512
53914B5D254417730B984A43
53915140274F17730B984A43
539E49572D515C2F55D242432C
61935141055B41220F
66C67A78096D600E72AF7A6D096C77174C8E525A214F
6895455D2F504B2751D27E620C6B701575
6C92524A3255452D4AD6419E095A324F7B224898085B3857
6D95424A164A572851D6
6DB763761F6F6B0264B0796201606C086BB9
708C424E34460E
739555463409
7688495F164A572851
769E4F4A044F486F41904A
798B4F412C4C43320B995E4A
79AF49493454453340A0

Para identificar la rutina que encargada de descifrar estas cadenas, va a ser necesario utilizar técnicas de ingeniería inversa. Concretamente vamos a ayudarnos de la herramienta VB decompiler. Analizando el código desensamblado encontramos el siguiente:

Código que nos permitió localizar la rutina de descifrado

Podemos ver que cada una de las cadenas cifradas en hexadecimal se encuentra seguida por la función llamada Proc_1_0_4074DC que toma como parámetro la cadena a descifrar. Esta fue la pista definitiva para cerciorarnos de que nos encontrábamos ante el código que buscábamos. Una vez dentro de la función encontraremos el siguiente código:

Rutina de descifrado

Para automatizar el descifrado de manera estática, es decir sin ejecutar el binario, hemos decidido traducir el código anterior a Python. A continuación podemos ver el programa equivalente implementado en Python para descifrar las cadenas del troyano:

def decode(ciphered_string, key):
       deciphered_string = ""
       key_length = len(key)

       j = 1
       for i in range(0, len(ciphered_string), 2):
            key_offset = (j -1) % key_length
                     
            #Get the key character corresponding to the character to decipher
            key_character_value = ord(key[key_offset: key_offset + 1])

            #Get the character to decipher
            ciphered_character_value = int("0x%s" % ciphered_string[i:i+2], 16)

            #Decipher the character
            deciphered_character = chr(key_character_value ^ ciphered_character_value)

            #Add the deciphered character to the deciphered string
            deciphered_string = "%s%s" % (deciphered_string, deciphered_character)
            j += 1

            return deciphered_string

def main():
       key = chr(37) + chr(252) + "&/@#$A"
       string_to_decipher = “66C67A78096D600E72AF7A6D096C77174C8E525A214F”
       print(decode(string_to_decipher, key))


Podemos observar que entre las cadenas ocultas de la muestra, se encontraban las direcciones del C&C (C&C1 y C&C2) y varias rutas y nombres de ficheros que nos indican que el troyano comprueba si es  ejecutado en un entorno virtual (Comprueba1, Comprueba2, Comprueba3, Comprueba4, y Comprueba5).

[.exe
open
http://www.americansoftwoodsmexico.com/~izqoder/admin/ (C&C1)
http://www.romney.com.br/~acsegura/Admin/ (C&C2)
toma.php?Os=
vmmreg32.dll (Comprueba1)
vmwogl32.dll (Comprueba2)
vboxmrxnp.dll (Comprueba3)
DownExec*
C:\WINDOWS\BIOSVirtual (Comprueba4)
Microsoft.XMLHTTP
Intervalo
HideVisit*
HKEY_LOCAL_MACHINE
Update*
Visit*
StopVisit
SbieDll.dll (Comprueba5)
\winlogs.exe
\Software\] 

Por último, os dejamos una cadena hexadecimal cifrada para que vosotros mismos probéis a descifrarla:

63994a463a036a205395424e24031e7c0c
  
Más informacion:

SHA-256 del PiceBOT analizado:
064c6fe2c42aa974041c78b049091015d2079392dd048754e75dd07484447391

Kaspersky:


Laurent Delosières


No hay comentarios:

Publicar un comentario en la entrada