Infección con TLS CALLBACK Funtions
Introducción - Infección mediante TLS
Hoy vengo a mostrarles un ejemplo de infección de ejecutables mediante TLS (thread local storage) Callbacks functions, el cual nos permite ejecutar funciones en hilos distintos en el orden en que se encuentran las funciones, se ejecutan antes del punto de entrada del programa, muy utilizado en malware pero muy poco documentado.
El TLS es un directorio del IMAGE_DATA_DIRECTORY, que se encuentra en la cabecera de los archivos ejecutables, su uso es opcional. Según el PECOFF el TLS almacena estáticamente hilos, que posteriormente ejecutará justo antes del punto de entrada del programa (Entry Point), su ventaja en malware es su manera de ejecutar (muy disimulada).
Explicaré su estructura y su fácil implementación manual.
Referencias:
PECoff (Documentación oficial de Microsoft sobre el formato PE)
http://msdn.microsoft.com/es-es/windows/hardware/gg463125
Estructura TLS Directory
typedef struct TLS
{
DWORD RawDataStartVA;
DWORD RawDataEndVA;
DWORD AddressOfIndex;
DWORD AddressOfCallbacks;
DWORD SizeOfZeroFill;
DWORD Characteristics;
} TLS_DIRECTORY, *PTLS_DIRECTORY;
La estructura está compuesta por 6 valores enteros (DWORD), por lo tanto su tamaño sería de 0x18h. De todos estos campos destacaré y explicaré solo 2:
- AddressOfIndex
- AddressOfCallbacks
AddressOfIndex
Es el puntero a la zona donde el loader de Windows asignará el índice TLS. Esta zona por lo general debe encontrarse en una sección de datos, he de suponer que por los permisos de lectura y escritura.
AddressOfCallbacks
Es el puntero a una matriz de funciones, donde se encuentran una serie de direcciones virtuales seguidas que apuntan a cada función individualmente, el final estará marcado por un DWORD nulo.
Hay que tener en cuenta que los 2 valores anteriores contienen direcciones virtuales es decir: [ImageBase + RVA]:
Análisis e inicio de la infección
Bueno los valores de la estructura que mencioné anteriormente son pieza fundamental en las funciones TLS Callbacks. Como miramos la que más nos interesa es AddressOfCallbacks, que tendrá una lista de punteros a las funciones a ejecutar, y el AddressOfIndex que apuntará a un espacio el cual recibirá el TLS Index por parte del loader de Windows.
Añadiendo directorio TLS
Principalmente debemos añadir soporte a este directorio, y lo aremos con LordPE que nos facilitará mucho las cosas, lo primero será escoger una zona vacía del ejecutable y sacar su RVA (Relative Virtual Address), creo que quien lo lea debe tener más que claro lo anterior así que no me extenderé.
Una vez tengamos la zona editamos el TLS TABLE con LordPE que se encuentra en Directory y colocamos el valor virtual y el tamaño de la estructura que como recordamos es 0x18h.
Una vez realizado esto ya tenemos nuestro TLS Directory y podremos agregar la estructura, que solo aplicaremos los 2 valores anteriormente mencionados, los otros tendrán el valor de 0.
Preparando la función a ejecutar:
Decidí trabajar con un ejecutable simple ensamblado en MASM que muestre un simple mensaje, y escogí como rutina ese mismo mensaje para no liarnos, claro ustedes ya cambiarán la rutina ;)
Shellcode:
x6A\x00\x68\x00\x30\x40\x00\x68\x05\x30\x40\x00\x6A\x00\xE8\xAD\xFF\xFF\xFF\xC3
Este Shellcode es un simple paso de parámetros y llamada a MessageBoxA previamente establecida por las importaciones.
Como se darán cuenta hay para tener en cuenta 2 detalles, si me están siguiendo al pie de la letra creo que tendrán que ubicar esta Shellcode en el offset 0x460 para que concuerde con la parte de la llamada de la API, y el otro detalle es que tenemos que colocar en AddressOfCallbacks la dirección virtual en nuestro caso 00401060.
Ahora nos ya que tenemos lista nuestra rutina debemos agregar la dirección de la función a AddressOfCallbacks, entonces buscamos un espacio vacío de mínimos 8 bytes (incluyendo el DWORD nulo), para colocar aquí la dirección de la función a ejecutar, yo escogí el offset: 0x498 y como necesitamos en dirección virtual entonces sería: 00401098 y la agregamos al campo AddressOfCallbacks con LordPE:
CallBackTableVA: 00401098
Ahora si recordamos el AddressOfCallbacks apuntaba a una matriz (array) de punteros a las funciones entonces, en ese espacio necesitaremos escribir el puntero a nuestra función que es 00401060:
Y recuerden que después de la dirección de la función el final de la lista se debe identificar con 4 bytes nulos (DWORD). Ahora nos queda solamente cambiar el puntero del AddressOfIndex y terminamos.
IndexVariableVA: 00403072
Correspondiente al offset 0x872, que es el espacio donde el loader cargará el Index:
Guardamos el ejecutable y al ejecutarlo deberemos tener 2 mensajes en vez de 1, claro uno a la vez:
Ejecución antes del Punto de Entrada Original (OEP)
Para comprobar que se ejecuta un mensaje antes del punto de entrada probamos abriendo el ejecutable con Olly, y pasará que siquiera antes de cargar las rutinas ya se abra ejecutado el mensaje: Win Asembly is Great
Una vez aceptemos tendremos las rutinas normalmente y como vemos en la rutina inicial no hay saltos ni ningún tipo de engaño:
Con esto creo que hemos terminado, pasemos a la despedida ;)
Despedida
Bueno me agrado escribir este pequeño artículo, y pueda que me haiga quedado corto en algunos conceptos o tenga algunas fallas de procedimiento XD. Quiero agradecer a Shaddy, [Zero], Psymera, Thor, Karcrack, karmany, Steve10120, Lelouch; ustedes son personas que admiro mucho y creo que jamás pondrán un pero para ayudar. A la lista de CracksLatinos, que a diario los leo y sé las personas tan talentosas y valerosas que hay ahí, a H-SEC la comunidad de mi amigo Zero, que de a poco progresa lento pero seguro, el-hacker y los amantes del malware.
Creo que será hasta la próxima, cualquier duda crítica o sugerencia:
@MSN: Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.
@GTalk: Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.
The Swash
Descarga:
MD5: 164332434f31243750f62761f5a5e7fa
Un saludo y que tengas un buen día!!!!