Análisis de malware
Análisis de Petya Ransomware Parte I
julio por Souhail Hammou
Introducción
Lo que hace que Petya sea un ransomware especial es que no tiene como objetivo cifrar cada archivo individualmente, sino que apunta a un cifrado de disco de bajo nivel. En esta serie, analizaremos la variante «verde» de Petya que viene con Mischa. Mischa se inicia cuando Petya no se ejecuta como proceso privilegiado. Todo lo que hace Mischa es cifrar archivos uno por uno y luego colocar una página web y un archivo de texto en cada directorio.
La muestra
La muestra con la que me topé viene disfrazada de currículum. El archivo contiene los siguientes archivos:
Cuando la víctima abre, por ejemplo, BewerbungPDF.exe, se le solicita que lo ejecute como administrador.
Si lo niega, Mischa ejecutará y cifrará todos los archivos (archivo por archivo) como lo hace un ransomware típico. Sin embargo, si la víctima acepta, Petya tendrá la oportunidad de ejecutar y realizar el cifrado de disco de bajo nivel.
Petya hace BSOD al sistema usando NtRaiseHardError y engaña a la víctima haciéndole creer que CHKDSK está reparando el disco.
Cuando la máquina se reinicia, el gestor de arranque malicioso se ejecuta y exige un rescate:
Solo cuando el usuario ingresa la clave de descifrado, los datos se descifrarán y el sistema se desinfectará.
Desembalaje
El proceso de desempaquetado es bastante sencillo, la única técnica que utilizaron los autores es evitar la detección de la zona de pruebas. Consiste en ejecutar largos fragmentos de código basura en los que existe algún código importante, por lo que estos fragmentos no se pueden eliminar simplemente. Repasemos los pasos importantes del proceso de desembalaje.
La función de interés es sub_4531F0 ; comienza ejecutando código basura que involucra bucles largos que toman algunos minutos, luego obtiene la dirección de VirtualAlloc y lo llama con PAGE_EXECUTE_READWRITE. A continuación, se ejecuta algún código basura en el que las partes relevantes 97702 bytes (también el tamaño del fragmento asignado) se mueven de 0x00453BD6 al fragmento asignado. Luego, la instrucción JMP EAX en 0x00453bab se ejecuta saltando al inicio del fragmento asignado.
Los primeros 1445 bytes del área asignada representan el código auxiliar de descompresión . El código auxiliar se utiliza para descifrar un archivo DLL que se encuentra justo después de él. Al final del proceso de descifrado, se realiza un salto a una función exportada de la DLL llamada: _ZuWQdweafdsg345312.
Cargando la DLL de Petya
La rutina es bastante larga, veamos qué hace de manera superficial:
- Busque el encabezado MZ del archivo DLL descomprimido: esto se hace llamando a una función que devolverá su dirección de retorno a la persona que llama. Luego la búsqueda se hace al revés.
- Recorra la lista de módulos cargados (PEB.Ldr-InMemoryOrderModuleList)
- Para cada BaseDllName en la lista doblemente enlazada, calcule un hash y compárelo con los hash de interés (hash ntdll.dll).
- Si lo encuentra, recorra la tabla de exportación de la DLL y busque los nombres de las funciones exportadas. La comparación de hash también realiza esta búsqueda.
- Si se encuentra la función de interés, se usa su ordinal para obtener su dirección ( AddressOfFunctions[Ordinal] + DllBase ) y el ciclo continúa hasta que se encuentran todas las funciones.
- Estas funciones son: LoadLibraryA, GetProcAddress, NtFlushInstructionCache y VirtualAlloc
- El malware ahora está listo para iniciar el proceso de carga de la DLL (simular el proceso del cargador de Windows).
- Primero, copia todo el archivo PE en un espacio de memoria recién asignado del tamaño SizeOfImage. Todas las modificaciones se realizan en los siguientes pasos relacionados con esta copia del archivo.
- Cargue las bibliotecas necesarias.
- Obtenga las direcciones de las funciones importadas.
- Establecer importaciones y reubicaciones.
- Ahora que la DLL está cargada, se llama a DllMain.
Descifrando la sección xxxx:
Tras la ejecución desde DllMain, pronto nos encontramos en la primera rutina de interés sub_1000D7E0. Comienza llamando a sub_100014F0 , al que le cambié el nombre a Decrypt_xxxx. Esta rutina toma un puntero de salida a una estructura como parámetro y primero ubica la dirección virtual del encabezado de la sección .xxxx. Luego, a partir de ahí, encuentra el puntero al primer byte de esta sección cifrada. La sección se descifra utilizando este sencillo algoritmo de xoring:
¿Petya o Mischa?
Al regresar de decrypt_xxxx, el ejemplo hace lo siguiente:
- Se llama a OpenProcessToken para obtener un identificador del token del proceso actual.
- Llame a GetTokenInformation con TokenElevated TokenInformationClass.
- Petya puede correr directamente si:
- Las llamadas a OpenProcessToken y GetTokenInformation fueron exitosas
- TOKEN_ELEVATED.TokenIsElevated != 0, lo que significa que el token está elevado.
Si no se cumple una de las condiciones anteriores, se le solicita al usuario que elija si desea ejecutar un nuevo proceso con privilegios o no.
Cuando el usuario hace clic en Sí, el nuevo proceso privilegiado comienza a ejecutarse (comienza descomprimiendo, cargando la DLL, luego descubre que el token tiene privilegios y finalmente toma la ruta del código de cifrado de disco de bajo nivel) mientras el proceso actual espera infinitamente hasta que el privilegio se da por terminado el proceso. Sin embargo, si el usuario no elige ejecutar el proceso como administrador, la función devuelve 0, lo que significa que Mischa se ejecutará.
En la siguiente parte, veremos cómo Petya infecta el sistema y cómo realiza el cifrado de disco de bajo nivel.
Recursos
Descarga de muestra aquí