Los investigadores de ESET reciben y analizan miles de muestras nuevas de malware por día. A principios de este año, una de ellas nos llamó la atención porque no se trataba de un archivo ejecutable común, sino que era un archivo de preferencias específico de un programa. Un análisis más detallado reveló rápidamente que de hecho era un malware que aprovechaba una vulnerabilidad del software para ejecutar código malicioso.
El presente artículo analiza en profundidad el funcionamiento del exploit y luego describe brevemente el payload final.
Información general sobre el exploit
El exploit aprovecha una vulnerabilidad de desbordamiento de búfer (buffer overflow) en la versión de demostración de un programa llamado Uploader!. Este último, desarrollado por ksoft, le permite al usuario subir archivos a Internet a través del protocolo FTP. Las preferencias (como el nombre del host FTP y el nombre de usuario) se guardan en un archivo llamado uploadpref.dat.
Los investigadores de ESET analizaron un archivo de preferencias que se usaba para infectar el sistema cuando se iniciaba el programa Uploader!. Hay un exploit de prueba de concepto disponible online desde marzo de 2014.
La vulnerabilidad explotada
El archivo de preferencias de Uploader! está compuesto por una serie de cadenas separadas por líneas, que identifican, por ejemplo, el nombre de usuario y el nombre de host del servidor al cual se subirán los archivos. La aplicación utiliza la secuencia de entrada estándar de C++ (std::ifstream) para leer el archivo uploadpref.dat desde el disco.
Mientras lee las cadenas del archivo, verifica que todos los campos tengan un tamaño adecuado; para ello usa in_stream.get(buffer, sizeof(buffer), '\n'). Sin embargo, el último campo que contiene las contraseñas cifradas usan la siguiente línea de código: in_stream >> buffer, donde el búfer se encuentra en la pila de ejecución. Si no se especifica in_stream.width(…), entonces in_stream >> buffer copiará el contenido del archivo a la pila de ejecución hasta llegar a un un espacio en blanco o al Fin del archivo.
Cuando ESET le advirtió a Ksoft sobre este problema, la empresa lanzó una nueva versión de Uploader! (3.6) dentro de las 24 horas de haber recibido la notificación.
Cómo se ejecuta el código
En el caso del exploit que analizamos, el contenido del archivo se copia a la pila de ejecución, excediendo la variable del búfer, que tiene un tamaño fijo de 80 bytes. Sobrescribe el mecanismo de Structured Exception Handler (SEH, del inglés, Controlador de Excepciones Estructurado) y copia el primer shellcode.
La copia se detiene cuando se produce una excepción al alcanzar el final de la pila de ejecución, lo que genera un error de página, ya que intenta escribir en una dirección no válida. Luego llama al controlador de excepciones manejado por el atacante. El gadget de instrucciones en el espacio de la dirección de Uploader! es pop ecx; pop ecx; ret. Por último, el gadget permitirá la ejecución del primer shellcode de la pila.
Los exploits basados en mecanismos de SEH no son nuevos. Si te interesa conocer los detalles, Corelan Team tiene un muy buen artículo sobre este tema en su sitio web. La protección Structured Exception Handling Overwrite Protection (SEHOP) evita que se ejecute este tipo de exploits, pero no está habilitada en la aplicación Uploader! y solo está habilitada para todo el sistema en Windows Server. Se puede cambiar esta configuración en la interfaz del usuario de EMET.
Es probable que el exploit esté basado en el de prueba de concepto mencionado arriba, dado que, aunque hay 178 gadgets pop; pop; ret en el código, este usa exactamente el mismo encontrado en 0x0040bf38. Las otras partes, como el shellcode y las etapas subsiguientes, fueron agregadas por el autor del malware.
Etapas
El exploit pasa por varias etapas antes de ejecutar el payload final. Esta sección describe brevemente cada una de ellas.
Etapa 0
Como ya mencionamos, el controlador SEH apunta a un gadget pop ecx; pop ecx; ret que pasará el flujo del control a nuestro primer shellcode.
Estas primeras instrucciones desempaquetan la siguiente etapa, a la que llamamos shell_code_1. Calcula un valor de un byte a partir de una palabra de dos bytes y lo escribe en la misma ubicación de memoria. Este método permite cifrar la Etapa 1 en el archivo utilizando solamente letras en mayúscula.
Etapa 1
Cuando termina esta etapa, todo el contenido del archivo uploadpref.dat se lee en memoria. Al principio no es obvio, porque el código busca funciones para la API de Windows en la estructura de datos PEB utilizando los hashes de los nombres y las funciones DLL. Calcula la suma de cada representación hexadecimal individual de los caracteres en minúsculas que forman el nombre de la función y la multiplica por dos.
A continuación mostramos la versión en Python del algoritmo de hash:
def hash_name(name): result = 0 for c in name: result = 2 * (result + (ord(c) | 0x60)) return result
Curiosamente, este algoritmo de hash es el mismo que se utiliza como ejemplo en un libro de Chris Anley y John Heasman titulado "The Shellcoder’s Handbook: Discovering and Exploiting Security Holes" (El Manual del programador de shellcode: Cómo descubrir y aprovechar fallas de seguridad). La implementación de C se explica en la página 145 de la Segunda Edición.
Tras resolver las llamadas a las funciones API, shell_code_1 asigna dos búfers del mismo tamaño que el archivo uploadpref.dat. El contenido completo del archivo se copia en el primer búfer, mientras que el segundo se deja intacto. Luego pasa al primer bloque del offset 0x10, donde se encuentra la siguiente etapa. Éste es un resumen en pseudo C:
HANDLE f = CreateFileA("uploadpref.dat", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);DWORD uploadpref_size = GetFileSize(f, 0);char * memblock1 = VirtualAlloc(NULL, uploadpref_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);char * memblock2 = VirtualAlloc(NULL, uploadpref_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);ReadFile(f, memblock1, uploadpref_size);stage_2 = &memblock1[0x10];stage_2(&memblock1[0x650], memblock2);// también se hace referencia a memblock2 de modo que, al volver de la Etapa 2 (stage_2), vaya al offset 0 de memblock2
Etapa 2
La función descomprime un búfer en 0x650 en el búfer memblock2 asignado anteriormente con un algoritmo un poco ineficiente. Este búfer puede llegar a tener una longitud de 3.632 bytes. A continuación, el flujo del control se redirige al comienzo de memblock2, que ahora contiene la Etapa 3.
Etapa 3
Esta etapa vuelve a abrir uploadpref.dat. Desde allí descomprime un archivo PE, comenzando en el offset 0x1600, y lo coloca en el nuevo búfer asignado. El algoritmo de descompresión es el mismo que se usó en la Etapa 2.
Luego crea un nuevo proceso en modo suspendido, e inyecta y ejecuta el nuevo archivo ejecutable.
El archivo PE extraído de uploadpref.dat tiene una longitud de 56.832 bytes, y su función es descargar y ejecutar una herramienta maliciosa de acceso remoto.
Información general sobre el archivo malicioso uploadpref.dat
Para resumir, a continuación mostramos el contenido completo del archivo malicioso uploadpref.dat para cada una de las distintas etapas de ejecución.
Offset | Tamaño (en bytes) | Descripción |
---|---|---|
0x0 | 11 | Primer campo |
0x0B | 4 | "1\n", lo que significa que el archivo contiene una contraseña (para activar la vulnerabilidad) |
0x0F | 1 | A' (padding) |
0x10 | 138 | Etapa 2 |
0x9A | 326 | Cero bytes (padding) |
0x1E0 | 12 | A' (padding) |
0x1EC | 4 | Salta a la Etapa 0 |
0x1F0 | 4 | Apunta a un gadget pop pop ret |
0x1F4 | 66 | Etapa 0 |
0x236 | 832 | Etapa 1 empaquetada con marcador de finalización (0xFFFF) |
0x576 | 218 | Cero bytes (padding) |
0x650 | 3952 | Etapa 3 comprimida |
0x15C0 | 64 | Cero bytes (padding) |
0x1600 | 870912 | Archivo PE comprimido |
Payload malicioso
Cuando logra infectar el equipo correctamente, se crea un nuevo proceso con el archivo PE integrado en el archivo uploadpref.dat. Este nuevo proceso descarga y ejecuta la etapa final: una herramienta de administración remota (RAT, del inglés) basada en la RAT Gh0st.
Downloader de la primera etapa
Persistencia
Para mantener el nivel de persistencia en el sistema, este módulo copia el archivo exploit original y el Upload 3.5!.exe con el nombre msfeedssync.exe en el directorio Datos de programa del usuario. A continuación, agrega un acceso directo al archivo ejecutable en la carpeta de inicio del menú Inicio. Al reiniciar el equipo, el exploit se volverá a accionar y se repetirán todos los pasos.
Se instalan los siguientes archivos para mantener el nivel de persistencia:
Archivos instalados | Ruta | Hashes |
---|---|---|
uploadpref.dat | C:\Documents and Settings\%USER%\Application Data\ | 16d842b8746944cd29cea6237e210be2d185cbe2 |
msfeedssync.exe | C:\Documents and Settings\%USER%\Application Data\ | e2fc91f82b7db3221502d2582ac3be7a5b663498 (itself) |
msfeedssync.lnk | C:\Documents and Settings\All Users\Start Menu\Programs\Startup\ | 0fff6640f72115021f0e5d0514921eb856948f30 |
Descarga del payload
Cuando se asegura la persistencia del código, el archivo ejecutable trae el payload malicioso a través de HTTP. Se inician dos subprocesos con un intervalo de 30 minutos. Debido al usuario y al agente HTTP empleados en cada subproceso, llamamos al primer subproceso Alan_function y al segundo, BFunction.
Cada subproceso intenta descargar el payload desde direcciones URL distintas utilizando el mismo nombre de dominio. Cuando se descomprime el archivo descargado, las dos funciones inician el código de una forma diferente:
- Alan_function espera un archivo PE ejecutable y simplemente lo ejecutará.
- BFunction espera un archivo DLL que cargará la función exportada TestFunction.
URL | Usuario-Agente | Contenido de SHA-1 (hasta marzo de 2015) | Nombre de detección |
---|---|---|---|
http://biless.com/alan/19437192.txt | Alan_Function | e440eea118d1701ad7886af6c93ef7102326d4c8 | Win32/Farfli.PZ |
http://biless.com/alan/Alan.txt | BFunction | Desconocido |
En marzo de 2015 observamos que solo se empleaba el primer método de distribución. El archivo ejecutable descargado que analizamos estaba estrechamente relacionado con el downloader de la primera etapa, ya que su método de ofuscación incluye desempaquetar un archivo DLL, cuya función exportada se llama TestFunction. Este archivo DLL podría haberse entregado directamente al subproceso BFunction para obtener los mismos resultados.
El payload final es un troyano basado en la RAT Gh0st.
El troyano
La etapa final consiste en colocar una variante del malware de espionaje remoto basado en la RAT Gh0st. La herramienta Gh0st ya fue analizada con detalle y documentada por varios investigadores en el pasado. Si te interesa conocer más sobre esta herramienta, consulta los vínculos a las investigaciones relevantes incluidos en la sección Referencias al final de este artículo.
El protocolo de red de la RAT Gh0st incluye una cadena de cinco caracteres que identifica la campaña. Esta variante de Gh0st usa el código de campaña A1CEA. No queda claro si la campaña A1CEA le corresponde específicamente a un grupo. Encontramos algunas referencias online relacionadas con A1CEA:
- Muestra encontrada en diciembre de 2013 con este código de campaña en Malwr
- Regla de SNORT agregada el 3 de marzo de 2015
- Análisis de Wins en Corea
El servidor de C&C de la muestra es www.phw2015.com en el puerto TCP 2015. En el momento en que se escribe este artículo, el dominio resuelve a la IP 112.67.10.110.
Otras modificaciones menores a la fuente de la RAT Gh0st incluyen:
- La presencia de una función que recopila las especificaciones del equipo.
- La presencia de la función exportada "TestFunction", que carga los componentes maliciosos.
Todas las funcionalidades de la RAT Gh0st están presentes y confirmamos que el registrador de pulsaciones estaba habilitado.
Conclusión
Este es un exploit extraño porque Uploader! no es una aplicación de uso masivo. Nos faltaría algo de contexto para entender con claridad qué es lo que ocurrió. ¿Habrán utilizado este exploit para engañar a un objetivo específico? El vector de ataque inicial tampoco es claro. ¿Habrán utilizado Ingeniería Social para convencer al usuario de que debía reemplazar el archivo de preferencias original por este otro archivo "especial"? ¿Habrán usado esta técnica solamente para ocultar la persistencia del malware?
Agradecimientos
Agradecemos a Hugo Genese por su contribución a este análisis.
Referencias
Michael G. Spohn (McAfee), Know Your Digital Enemy: Anatomy of a Gh0st RAT (Conoce a tu enemigo digital: Anatomía de una RAT GH0st), http://www.mcafee.com/ca/resources/white-papers/foundstone/wp-know-your-digital-enemy.pdf, 2012
Snorre Fagerland (Norman), The many faces of Gh0st Rat (Las diversas caras de la RAT Gh0st), http://download01.norman.no/documents/ThemanyfacesofGh0stRat.pdf, 2012
Indicadores de sistemas comprometidos
Muestras
SHA-1 | Tipo | Nombre de detección de ESET |
---|---|---|
16d842b8746944cd29cea6237e210be2d185cbe2 | DAT file | Win32/Exploit.Ksoft |
e2fc91f82b7db3221502d2582ac3be7a5b663498 | Win32 PE | Win32/TrojanDownloader.Agent.BGF |
e440eea118d1701ad7886af6c93ef7102326d4c8 | Win32 PE | Win32/Farfli.PZ |
d7d65d44657af68ddeba821b4adee6285bcdb418 | Win32 PE | Win32/Farfli.PZ |
6b5095fcd9b230a34f9e51120c36a19908ef3885 | Win32 PE | Win32/Farfli.PZ |
Otros
Mutex | www.phw2015.comwww.phw2015.comwww.phw2015.com |
---|
Red
Host | Puerto | Descripción |
---|---|---|
www.phw2015.com | 2015 | Gh0stRAT C&C server |
www.biless.com | 80 | Usado para descargar el payload RAT Gh0st |
Ver también
- Emerging Threat’s snort rule
2809928 – ETPRO TROJAN PCRat/Gh0st CnC Beacon Request (A1CEA) (trojan.rules)