Cuando, en el primer semestre del año 2019, apareció el nuevo cifrador Sodin (también conocido como Sodinokibi y Revile) llamó de inmediato nuestra atención, porque para propagarse utilizaba una vulnerabilidad en Oracle Weblogic y ataques a los proveedores de MSP. Al analizarlo en detalle, encontramos que también usa la vulnerabilidad CVE-2018-8453 para obtener privilegios en el sistema operativo Windows, algo poco frecuente entre los cifradores, y utiliza funciones legítimas del procesador para evadir las soluciones de seguridad.
Según nuestras estadísticas, la mayoría de sus víctimas se encontraban en la región de Asia y el Pacífico: Taiwán, Hong Kong y Corea del Sur.
Geografía de la distribución del cifrador Sodin, abril – junio de 2019
Descripción técnica
Explotación de la vulnerabilidad
Para obtener privilegios, Trojan-Ransom.Win32.Sodin hace uso de una vulnerabilidad en win32k.sys, cuyos intentos de explotación fueron descubiertos por nuestras tecnologías proactivas (Automatic Exploit Protection, AEP) en agosto del año pasado. La vulnerabilidad recibió la denominación CVE-2018-8453. Una vez ejecutado el exploit, el troyano obtiene el nivel máximo de privilegios.
Dependiendo de la arquitectura del procesador, se ejecuta una de las dos opciones de código de shell contenidas en el cuerpo del troyano:
Como el binario que estamos analizando es un archivo ejecutable de 32 bits, nos interesa cómo ejecuta el código de 64 bits en su espacio de direcciones. La captura de pantalla muestra un fragmento del código de shell que permite la ejecución de instrucciones del procesador de 64 bits:
En un sistema operativo de 64 bits, el selector del segmento de código de modo de usuario de 32 bits es 0x23, y el selector de segmento de 64 bits es 0x33. Es fácil comprobarlo mirando la tabla de descriptores globales de GDT en el depurador de kernel:
El selector 0x23 apunta al cuarto descriptor de segmento (0x23 >> 3), y el selector 0x33 apunta al sexto (no se usa el descriptor de cero). El marcador Nl indica que el segmento tiene direccionamiento de 32 bits, y el marcador Lo, de 64 bits. ¡Lo importante es que las direcciones base de estos segmentos son iguales! En el momento de la ejecución del shellcode, en el registro de segmento cs habrá un selector 0x23, ya que el código se ejecuta en un espacio de direcciones de 32 bits. Con esto en mente, veamos la lista del comienzo del código de shell:
Después de ejecutar el comando en las direcciones RVA 6 y 7, se almacenará una dirección de retorno larga en la parte superior de la pila en el formato selector:desplazamiento y será similar a 0x23:0x0C. En el desplazamiento 0x11, se coloca un DWORD en la pila, cuya palabra baja contiene el selector 0x33, mientras que la palabra alta tiene codificada la instrucción retf, cuyo código de operación es 0xCB.
La siguiente instrucción es call (en la dirección 0x16 RVA), que hace la transición cercana a la instrucción dada retf (RVA 0x14), habiendo enviado previamente a la pila la dirección de retorno más cercana (desplazamiento 0x1b). Así, en el momento en el que se ejecuta la instrucción retf, en la parte superior de la pila estará la dirección en el formato selector:desplazamiento donde el selector es 0x33 y el desplazamiento es 0x1b. Después de ejecutar el comando retf, el procesador comenzará a ejecutar el código en esta dirección, pero ya en modo de 64 bits.
El retorno al modo de 32 bits se lleva a cabo al final del código de shell.
El comando retf realiza una transición a una dirección distante, 0x23:0x0C (ubicada en la pila de instrucciones al comienzo del código de shell, en la dirección RVA 6-7). Una técnica similar para ejecutar el código de 64 bits en un espacio de direcciones de 32 bits denominada Heaven’s Gate fue descrita hace unos 10 años.
Configuración del troyano
El bloque de configuración se almacena cifrado en el cuerpo de cada ejemplar de Sodin, y contiene la configuración y los datos necesarios para el funcionamiento del troyano.
En la configuración de Sodin están presentes los siguientes campos:
Campo | Propósito |
pk | clave pública del distribuidor |
pid | probable Id. del distribuidor |
sub | probable Id. de la campaña |
dbg | compilación de depuración |
fast | modo de cifrado rápido (máximo 0x100000 bytes) |
wipe | eliminación de ciertos archivos con sobrescritura de sus contenidos con bytes aleatorios |
wfld | nombres de los directorios en los que el troyano eliminará archivos |
wht | nombres de directorios, archivos y una lista de extensiones que no se cifrarán |
prc | nombre de los procesos que se finalizarán |
dmn | direcciones de servidores a los que se enviarán las estadísticas |
net | envío de estadísticas de infección |
nbody | plantilla de texto con las exigencias del pago |
nname | patrón de nombre de archivo con las exigencias |
exp | uso del exploit para la escalada de privilegios |
img | texto para el fondo de escritorio |
Esquema criptográfico
Sodin utiliza un esquema híbrido para cifrar los archivos de la víctima. El contenido de los archivos se cifra con el algoritmo de flujo simétrico Salsa20 y las claves para ello se cifran con un algoritmo asimétrico basado en curvas elípticas. Analicemos el esquema en detalle.
Dado que algunos datos se almacenan en el registro, usaremos en el artículo los nombres que utiliza el cifrador. Para aquellas entidades que no son parte del registro, usaremos nombres ficticios.
Generación de claves
El archivo de configuración de Sodin contiene el campo pk, que también entra en el registro bajo el nombre sub_key. Esta es la clave pública de 32 bytes del distribuidor de troyanos. La clave es un punto en la curva elíptica Curve 25519.
Al ejecutarse, el troyano genera un nuevo par de claves de sesión en la curva elíptica; la clave pública de este par se almacena en el registro con el nombre pk_key, y la privada está cifrada con el algoritmo ECIES en la clave sub_key y se guarda en el registro bajo el nombre sk_key. La implementación de ECIES en este caso incluye la curva Curve 25519, el hash criptográfico SHA3-256 y el cifrado de bloques AES-256 en modo CFB. Anteriormente se encontraron otras implementaciones de ECIES en troyanos, por ejemplo, en el cifrador Synack.
Un punto curioso: la misma clave privada de la sesión se cifrará en otra clave pública, indicada explícitamente en el cuerpo del troyano, sin importar su configuración. La llamaremos clave maestra pública. El resultado del cifrado se almacena en el registro con el nombre 0_key. Entonces, resulta que la persona que conoce la clave privada correspondiente a public skeleton keypodrá descifrar los archivos de la víctima, incluso si no tiene la clave privada de sub_key. Al parecer, el desarrollador del troyano incluyó en el algoritmo una función secreta que le permite descifrar archivos sin que los distribuidores se enteren.
Cifrado de los archivos
Al cifrar cada archivo, se genera un nuevo par de claves asimétricas en la curva elíptica, que llamaremos file_pub y file_priv. Luego se calcula el SHA3-256 (ECDH (file_priv, pk_key)), y el resultado se utiliza como una clave simétrica para cifrar el contenido del archivo con el algoritmo Salsa20. La siguiente información también se guarda en el archivo cifrado:
Además de los campos ya mencionados, también está nonce (inicialización aleatoria de 8 bytes para cifrado Salsa20), file_pub_crc32 (suma de control de file_pub) flag_fast (si está configurado, significa que solo algunos datos están cifrados en el archivo), zero_encr_by_salsa (dword nulo, encriptado con la misma clave Salsa20 que el contenido del archivo, al parecer para verificar la exactitud del descifrado).
Los archivos cifrados obtienen una nueva extensión arbitraria (la misma para cada caso de infección); el texto con las exigencias se guarda junto a ellos y el fondo de pantalla generado por el malware se instala en el escritorio.
Interacción de red
Si el marcador correspondiente está puesto en el archivo de configuración, el troyano enviará información sobre la máquina infectada a sus servidores. Los datos transmitidos también se cifran utilizando el algoritmo ECIES utilizando otra clave pública indicada explícitamente en el cuerpo de Sodin.
Campo | Propósito |
ver | versión del troyano |
pid | probable Id. del distribuidor |
sub | probable Id. de la campaña |
pk | clave pública del distribuidor |
uid | Id. de la infección |
sk | valor de sk_key (ver descripción arriba) |
unm | nombre del usuario del sistema infectado |
net | nombre de la máquina |
grp | dominio o grupo de trabajo de la máquina |
lng | idioma del sistema |
bro | idioma o distribución del teclado de la lista (abajo) |
os | versión del sistema operativo |
bit | arquitectura |
dsk | información sobre los discos en el sistema |
ext | extensión de los archivos cifrados |
En el proceso de ejecución, el troyano comprueba el idioma del sistema y las distribuciones de teclado disponibles:
Si se encuentran coincidencias con la lista, el proceso del malware se finaliza y no se procede a enviar las estadísticas.
MITRE ATT&CK techniques
IOC
1ce1ca85bff4517a1ef7e8f9a7c22b16
El cifrador Sodin explota una vulnerabilidad de Windows y ciertas características arquitectónicas del procesador
Danilo
Hola!
Donde puedo obtener una muestra de SODIN para analizarlo y explotarlo en un ambiente controlado?