Controlador
El controlador es el primer componente de Duqu que se carga en el sistema. Hemos descubierto que el controlador y los otros componentes maliciosos se instalan con un dropper que explota una vulnerabilidad día-cero (CVE-2011-3402). El controlador se registra en la ruta HKLMSystemCurrentControlSetServices registry. El nombre exacto de la llave de registro varía según las distintas versiones de los controladores de Duqu.
Después de cargarse, el controlador procede a descifrar un pequeño bloque que contiene la llave de registro y el nombre del valor de registro que aparece en esa llave. También contiene el nombre del objeto controlador a crear.
Todas las versiones del controlador disponibles en ese momento tienen el mismo nombre de valor de registro: “FILTER”.
Después, el controlador registra la DriverReinitializationRoutine que envía la WorkerRoutine, que es donde se realiza la inicialización del controlador. En la WorkerRoutine el controlador lee el valor “FILTER” en el registro y lo descifra con una llave hard-code de cifrado. Existen dos versiones conocidas de rutinas de descifrado y dos correspondientes llaves de descifrado. El controlador también localiza el módulo NT OSKRNL.EXE o el NTKRNLPA.EXE y obtiene las direcciones de las funciones API para usarlas posteriormente.
El valor “FILTER” descifrado desde el registro contiene la lista de registros que contienen el nombre del proceso (“services.exe”), la ruta al correspondiente archivo PNF DLL que se inyectará en dicho proceso, y la llave decodificadora (0xAE240682) que se usa para descifrar el PNF DLL.
Tras inicializarse, el controlador registra LoadImageNotifyRoutine a la que después Windows llamará cada vez que se cargue un nuevo módulo. La rutina verifica si el nombre de la imagen coincide con uno de los valores “FILTER” especificados, y si lo hace, comienza la inyección: Descifra y copia el PNF DLL a un archivo en la región de memoria asignada para ese proceso. También construye y copia un archivo stub EXE en ese proceso y que después se usa para cargar el PNF DLL.
Una vez que “KERNEL32.DLL” se carga en el mismo proceso, localiza las direcciones de funciones API que el cargador EXE requiere y modifica el punto original de entrada del módulo principal del proceso de manera que pase la ejecución al código EXE del cargador.
El módulo del cargador EXE realiza la inicialización primaria del módulo PNF DLL y después ejecuta la exportación como se especifica en la configuración (“FILTER”). Posteriormente, restaura el código del punto original de entrada y regresa la ejecución al módulo original del proceso. El cargador también interactúa con el módulo del controlador mediante un código IOCTL ajustable para cambiar la protección de la memoria del código del punto original de entrada.
Archivo PNF DLL
Este módulo se guarda en el disco como un bloque codificado de datos. Tan pronto como se descifra, resulta ser un DLL comprimido con UPX. Versiones conocidas de los módulos PNF DLL exportan 8 ó 6 diferentes funciones por números ordinales.
La exportación 2 ejecuta la exportación 6 en un proceso separado.
La exportación 4 ejecuta la exportación 5 en un proceso separado.
La exportación 5 comienza un hilo en el proceso “services.exe” que cargó el recurso 302 (ver más abajo) y, si cuenta con la información apropiada de parte del destinatario, instala un juego completamente nuevo de componentes de Duqu.
La exportación 6 detiene el controlador y desinstala por completo todos los componentes de Duqu. Las exportaciones 8 y 1 inicializan el módulo PNF DLL y comienzan los hilos principales.
Aparentemente, el ordinal 1 tiene la función de exportar la funcionalidad primaria del DLL. Primero, carga la información para la configuración desde otro archivo PNF, el PNF Config. Si no se encuentra este archivo, se lo crea desde una copia codificada hard-coded que se guarda en el archivo PNF DLL.
El nombre del archivo de configuración es diferente para cada versión de Duqu. El PNF Config contiene el nombre y la ruta al componente del controlador, al PNF DLL y al mismo PNF Config.
Cuando se crea el PNF Config, la fecha de creación se escribe en el archivo. El archivo también contiene el valor TTL (“time to live”): un hilo separado iniciado por el PNF DLL monitorea si han transcurrido TTL días desde la fecha de creación, y después ejecuta la rutina de desinstalación.
Algunas versiones del PNF DLL también comienzan un servidor RPC similar al encontrado en Stuxnet.
El PNF DLL también proporciona API para manipular el archivo de configuración desde módulos externos recurriendo a los acontecimientos disponibles a nivel global.
Según las señales en el archivo PNF Config, el código PNF DLL busca procesos específicos: la lista de nombres de procesos en el PNF Config, “explorer.exe”, “svchost.exe” y luego les inyecta el código. El código que se inyecta se guarda en el recurso binario 302 que se encuentra en el PNF DLL.
Recurso 302
Según la señal en el archivo de configuración PNF, se trata de un módulo cargador DLL o de un bloque de datos (equivalente al descomprimido “.zdata”, como se ve más abajo). Se han encontrado ambas configuraciones en distintas versiones de Duqu. El PNF DLL verifica una señal en el PNF Config y determina si pasa la ejecución al cargador DLL o si localiza la carga DLL y la llama directamente.
El módulo cargador DLL es similar al PNF DLL. El principal propósito de este cargador es descomprimir su sección “.zdata” y pasar la ejecución a la carga (maliciosa) principal contenida en los datos descomprimidos.
El bloque .zdata contiene el encabezado que comienza con el número mágico 0x48747193. Contiene los desplazamientos y tamaños del cargador DLL, el bloque de configuración de la carga (maliciosa) y la carga (maliciosa) DLL.
Bloque de configuración
El bloque de configuración contiene el nombre del archivo temporal a usar %TEMP%~DR0001.tmp, datos binarios adicionales que controlan el comportamiento de la carga (maliciosa) y la información requerida para conectarse a los servidores de comando y control (C&C). Existen dos listas de servidores C&C, una que puede contener los nombres de dominios, direcciones IP o nombres de recursos compartidos en la red, y la otra contiene direcciones IP en formato binario y se usa para conectarse mediante servicios Windows HTTP (winhttp). Aunque los bloques de configuración que hemos encontrado son similares y están configurados para conectarse a sus servidores C&C mediante HTTP y HTPPS, la carga (maliciosa) DLL es capaz de conectarse a un recurso compartido en la red e incluso convertirse en un servidor.
Carga (maliciosa)
Seguimos analizando la carga (maliciosa). Contiene 256 K de código C++ con uso extenso de STL y sus propias jerarquías complejas de clase, probablemente con su propio marco.
La carga (maliciosa) es capaz de conectarse al servidor C&C mediante la biblioteca winhttp o una conexión a un recurso compartido en la red IPC$ endpoint. Es capaz de conectarse mediante la configuración para servidor proxy de Internet Explorer. También contiene un código para funcionar como un servidor HTTP y procesar las mismas peticiones que el servidor C&C. La carga (maliciosa) es capaz de cargar un módulo DLL externo provisto por el servidor C&C e interactuar con él mediante un API predefinido. El módulo más notable que hemos descubierto es el infostealer. También existen módulos para actualizar el valor TTL en la configuración del PNF DLL, para leer la configuración de la red y del almacenamiento en el disco del ordenador infectado.
También puede formar un PNF DLL con un bloque de configuración y la carga (maliciosa) DLL lista para distribuirse a otros ordenadores.
El misterio de Duqu: parte V