
Detección basada en firmas de características de malware basadas en secuencias de llamadas a la API de Windows. ¡Es como YARA para trazas de API de sandbox!
dynmx (pronunciado dynamics) es un enfoque de detección basado en firmas para características de comportamiento de malware basado en secuencias de llamadas a la API de Windows. De manera simplificada, puede pensar en dynmx como una especie de YARA para trazas de llamadas a la API (los llamados registros de funciones) provenientes de sandboxes de malware. Por lo tanto, la base de datos para el enfoque de detección no son las muestras de malware en sí mismas, que se analizan estáticamente, sino los datos generados durante un análisis dinámico de la muestra de malware en una sandbox de malware. Actualmente, dynmx admite registros de funciones de las siguientes sandboxes de malware:
report.json)report.json)El enfoque de detección se describe en detalle en la tesis de maestría Detección basada en firmas de características de comportamiento de malware con llamadas a la API de Windows. Este proyecto es la implementación prototipo de este enfoque y se desarrolló en el transcurso de la tesis de maestría. Las firmas son definidas manualmente por analistas de malware en el DSL de firmas dynmx y pueden detectarse en registros de funciones con la ayuda de esta herramienta. Las características y la sintaxis del DSL de firmas dynmx también se pueden encontrar en la tesis de maestría. Además, puede encontrar firmas de muestra de dynmx en el repositorio dynmx-signatures. Además de detectar características de malware basadas en llamadas a la API, dynmx puede extraer recursos del SO que son utilizados por el malware (el llamado Modelo de Actividad de Acceso). Estos recursos se extraen examinando las llamadas a la API y reconstruyendo operaciones sobre los recursos del SO. Actualmente, los recursos del SO de las categorías sistema de archivos, registro y red se consideran en el modelo.
En la siguiente sección, se muestran ejemplos de la detección de características de malware y de la extracción de recursos.
Para este ejemplo, elegimos la muestra de malware con la suma hash SHA-256 c0832b1008aa0fc828654f9762e37bda019080cbdd92bd2453a05cfb3b79abb3. Según MalwareBazaar, la muestra pertenece a la familia de malware Amadey. Hay un informe de análisis de VMRay público disponible de esta muestra, que también proporciona el registro de funciones rastreado por VMRay. Este registro de funciones será nuestra base de datos que utilizaremos para la detección.
Si quisiéramos saber si la muestra de malware utiliza una técnica de inyección llamada Process Hollowing, podemos intentar detectar la siguiente firma dynmx en el registro de funciones.```yaml dynmx_signature: meta: name: process_hollow title: Process Hollowing description: Detection of Process hollowing malware feature detection: proc_hollow: # Create legit process in suspended mode - api_call: ["CreateProcess[AW]", "CreateProcessInternal[AW]"] with: - argument: "dwCreationFlags" operation: "flag is set" value: 0x4 - return_value: "return" operation: "is not" value: 0 store: - name: "hProcess" as: "proc_handle" - name: "hThread" as: "thread_handle" # Injection of malicious code into memory of previously created process - variant: - path: # Allocate memory with read, write, execute permission - api_call: ["VirtualAllocEx", "VirtualAlloc", "(Nt|Zw)AllocateVirtualMemory"] with: - argument: ["hProcess", "ProcessHandle"] operation: "is" value: "$(proc_handle)" - argument: ["flProtect", "Protect"] operation: "is" value: 0x40 - api_call: ["WriteProcessMemory"] with: - argument: "hProcess" operation: "is" value: "$(proc_handle)" - api_call: ["SetThreadContext", "(Nt|Zw)SetContextThread"] with: - argument: "hThread" operation: "is" value: "$(thread_handle)" - path: # Map memory section with read, write, execute permission - api_call: "(Nt|Zw)MapViewOfSection" with: - argument: "ProcessHandle" operation: "is" value: "$(proc_handle)" - argument: "AccessProtection" operation: "is" value: 0x40 # Resume thread to run injected malicious code - api_call: ["ResumeThread", "(Nt|Zw)ResumeThread"] with: - argument: ["hThread", "ThreadHandle"] operation: "is" value: "$(thread_handle)" condition: proc_hollow as sequence
Basándose en la firma, podemos encontrar algunas características de DSL que hacen que *dynmx* sea potente:
* Definición de secuencias de llamadas a la API con rutas alternativas
* Coincidencia de nombres de funciones de llamadas a la API con expresiones regulares
* Coincidencia de valores de argumentos y retorno con varios operadores
* Almacenamiento de variables, por ejemplo, para hacer seguimiento de identificadores en la secuencia de llamadas a la API
* Definición de una condición de detección con operadores booleanos (`AND`, `OR`, `NOT`)
Si ejecutamos *dynmx* con la firma mostrada anteriormente contra la función de la muestra `c0832b1008aa0fc828654f9762e37bda019080cbdd92bd2453a05cfb3b79abb3`, obtenemos la siguiente salida que indica que la firma fue detectada.```
$ python3 dynmx.py detect -i 601941f00b194587c9e57c5fabaf1ef11596179bea007df9bdcdaa10f162cac9.json -s process_hollow.yml
|
__| _ _ _ _ _
/ | | | / |/ | / |/ |/ | /\/
\_/|_/ \_/|/ | |_/ | | |_/ /\_/
/|
\|
Ver. 0.5 (PoC), by 0x534a
[+] Parsing 1 function log(s)
[+] Loaded 1 dynmx signature(s)
[+] Starting detection process with 1 worker(s). This probably takes some time...
[+] Result
process_hollow c0832b1008aa0fc828654f9762e37bda019080cbdd92bd2453a05cfb3b79abb3.txt
Podemos obtener más detalles configurando el formato de salida a detail. Ahora, podemos ver la secuencia exacta de llamadas a la API que fue detectada en el registro de funciones. Además, podemos ver que la firma fue detectada en el proceso 51f0.exe.```
$ python3 dynmx.py -f detail detect -i 601941f00b194587c9e57c5fabaf1ef11596179bea007df9bdcdaa10f162cac9.json -s process_hollow.yml
|
__| _ _ _ _ _ / | | | / |/ | / |/ |/ | // _/|/ _/|/ | |/ | | |_/ /_/ /| |
Ver. 0.5 (PoC), by 0x534a
[+] Parsing 1 function log(s) [+] Loaded 1 dynmx signature(s) [+] Starting detection process with 1 worker(s). This probably takes some time...
[+] Result Function log: c0832b1008aa0fc828654f9762e37bda019080cbdd92bd2453a05cfb3b79abb3.txt Signature: process_hollow Process: 51f0.exe (PID: 3768) Number of Findings: 1 Finding 0 proc_hollow : API Call CreateProcessA (Function log line 20560, index 938) proc_hollow : API Call VirtualAllocEx (Function log line 20566, index 944) proc_hollow : API Call WriteProcessMemory (Function log line 20573, index 951) proc_hollow : API Call SetThreadContext (Function log line 20574, index 952) proc_hollow : API Call ResumeThread (Function log line 20575, index 953)
### Recursos
Para extraer los recursos del sistema operativo a los que se accede desde un registro de funciones, simplemente podemos ejecutar el comando *dynmx* `resources` contra el registro de funciones. A continuación se muestra un ejemplo de la salida detallada para la muestra con el hash SHA-256 `601941f00b194587c9e57c5fabaf1ef11596179bea007df9bdcdaa10f162cac9`. Este es un informe de CAPE sandbox que forma parte del [Avast-CTU Public CAPEv2 Dataset](https://github.com/avast/avast-ctu-cape-dataset).```
$ python3 dynmx.py -f detail resources --input 601941f00b194587c9e57c5fabaf1ef11596179bea007df9bdcdaa10f162cac9.json
|
__| _ _ _ _ _
/ | | | / |/ | / |/ |/ | /\/
\_/|_/ \_/|/ | |_/ | | |_/ /\_/
/|
\|
Ver. 0.5 (PoC), by 0x534a
[+] Parsing 1 function log(s)
[+] Processing function log(s) with the command 'resources'...
[+] Result
Function log: 601941f00b194587c9e57c5fabaf1ef11596179bea007df9bdcdaa10f162cac9.json (/Users/sijansen/Documents/dev/dynmx_flogs/cape/Public_Avast_CTU_CAPEv2_Dataset_Full/extracted/601941f00b194587c9e57c5fabaf1ef11596179bea007df9bdcdaa10f162cac9.json)
Process: 601941F00B194587C9E5.exe (PID: 2008)
Filesystem:
C:\Windows\SysWOW64\en-US\SETUPAPI.dll.mui (CREATE)
API-MS-Win-Core-LocalRegistry-L1-1-0.dll (EXECUTE)
C:\Windows\SysWOW64\ntdll.dll (READ)
USER32.dll (EXECUTE)
KERNEL32.dll (EXECUTE)
C:\Windows\Globalization\Sorting\sortdefault.nls (CREATE)
Registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OLEAUT (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup\SourcePath (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\DevicePath (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Internet Settings (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Internet Settings\DisableImprovedZoneCheck (READ)
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings (READ)
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Security_HKLM_only (READ)
Process: 601941F00B194587C9E5.exe (PID: 1800)
Filesystem:
C:\Windows\SysWOW64\en-US\SETUPAPI.dll.mui (CREATE)
API-MS-Win-Core-LocalRegistry-L1-1-0.dll (EXECUTE)
C:\Windows\SysWOW64\ntdll.dll (READ)
USER32.dll (EXECUTE)
KERNEL32.dll (EXECUTE)
[...]
C:\Users\comp\AppData\Local\vscmouse (READ)
C:\Users\comp\AppData\Local\vscmouse\vscmouse.exe:Zone.Identifier (DELETE)
Registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OLEAUT (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup (READ)
[...]
Process: vscmouse.exe (PID: 900)
Filesystem:
C:\Windows\SysWOW64\en-US\SETUPAPI.dll.mui (CREATE)
API-MS-Win-Core-LocalRegistry-L1-1-0.dll (EXECUTE)
C:\Windows\SysWOW64\ntdll.dll (READ)
USER32.dll (EXECUTE)
KERNEL32.dll (EXECUTE)
C:\Windows\Globalization\Sorting\sortdefault.nls (CREATE)
Registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OLEAUT (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup\SourcePath (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\DevicePath (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Internet Settings (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Internet Settings\DisableImprovedZoneCheck (READ)
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings (READ)
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Security_HKLM_only (READ)
Process: vscmouse.exe (PID: 3036)
Filesystem:
C:\Windows\SysWOW64\en-US\SETUPAPI.dll.mui (CREATE)
API-MS-Win-Core-LocalRegistry-L1-1-0.dll (EXECUTE)
C:\Windows\SysWOW64\ntdll.dll (READ)
USER32.dll (EXECUTE)
KERNEL32.dll (EXECUTE)
C:\Windows\Globalization\Sorting\sortdefault.nls (CREATE)
C:\ (READ)
C:\Windows\System32\uxtheme.dll (EXECUTE)
dwmapi.dll (EXECUTE)
advapi32.dll (EXECUTE)
shell32.dll (EXECUTE)
C:\Users\comp\AppData\Local\vscmouse\vscmouse.exe (CREATE,READ)
C:\Users\comp\AppData\Local\iproppass\iproppass.exe (DELETE)
crypt32.dll (EXECUTE)
urlmon.dll (EXECUTE)
userenv.dll (EXECUTE)
wininet.dll (EXECUTE)
wtsapi32.dll (EXECUTE)
CRYPTSP.dll (EXECUTE)
CRYPTBASE.dll (EXECUTE)
ole32.dll (EXECUTE)
OLEAUT32.dll (EXECUTE)
C:\Windows\SysWOW64\oleaut32.dll (EXECUTE)
IPHLPAPI.DLL (EXECUTE)
DHCPCSVC.DLL (EXECUTE)
C:\Users\comp\AppData\Roaming\Microsoft\Network\Connections\Pbk\_hiddenPbk\ (CREATE)
C:\Users\comp\AppData\Roaming\Microsoft\Network\Connections\Pbk\_hiddenPbk\rasphone.pbk (CREATE,READ)
Registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OLEAUT (READ)
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup (READ)
[...]
Network:
24.151.31.150:465 (READ)
http://24.151.31.150:465 (READ,WRITE)
107.10.49.252:80 (READ)
http://107.10.49.252:80 (READ,WRITE)
Basándonos en la salida mostrada y en los recursos accedidos, podemos deducir algunas características del malware:
601941F00B194587C9E5.exe (PID 1800), se elimina el identificador de zona del archivo C:\Users\comp\AppData\Local\vscmouse\vscmouse.exevscmouse.exe (PID: 3036) se conecta a los endpoints de red http://24.151.31.150:465 y http://107.10.49.252:80Los recursos accedidos son interesantes para identificar indicadores de detección basados en host y red. Además, los recursos pueden utilizarse en firmas de dynmx. Un ejemplo popular es la detección de mecanismos de persistencia en el Registro.``` dynmx_signature: meta: name: run_keys_persistence title: Run Keys Persistence description: Detection of persistence based on Registry Run Keys detection: run_keys: - resource: category: "registry" access_operations: ["write"] with: - attribute: "location" operation: "regex" value: "^(HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE)\\Software\\Microsoft\\Windows\\CurrentVersion\\(Run|RunOnce|RunOnceEx)\\" startup_folders_keys: - resource: category: "registry" access_operations: ["write"] with: - attribute: "location" operation: "regex" value: "^(HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE)\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\(Shell Folders|User Shell Folders)\\" condition: run_keys as simple or startup_folders_keys as simple
## Instalación
Para poder usar el software, Python 3.9 debe estar disponible en el sistema objetivo. Además, se deben instalar los siguientes paquetes de Python:
* `anytree`,
* `lxml`,
* `pyparsing`,
* `PyYAML`,
* `six` y
* `stringcase`
Para instalar los paquetes, ejecute el comando `pip3` que se muestra a continuación. Se recomienda usar un entorno virtual de Python en lugar de instalar los paquetes de forma general en el sistema.```
pip3 install -r requirements.txt
Para usar el prototipo, simplemente ejecute el punto de entrada principal dynmx.py. La información de uso se puede ver con el parámetro de línea de comandos -h como se muestra a continuación.```
$ python3 dynmx.py -h
usage: dynmx.py [-h] [--format {overview,detail}] [--show-log] [--log LOG] [--log-level {debug,info,error}] [--worker N] {detect,check,convert,stats,resources} ...
Detect dynmx signatures in dynamic program execution information (function logs)
optional arguments: -h, --help show this help message and exit --format {overview,detail}, -f {overview,detail} Output format --show-log Show all log output on stdout --log LOG, -l LOG log file --log-level {debug,info,error} Log level (default: info) --worker N, -w N Number of workers to spawn (default: number of processors - 2)
sub-commands: task to perform
{detect,check,convert,stats,resources} detect Detects a dynmx signature check Checks the syntax of dynmx signature(s) convert Converts function logs to the dynmx generic function log format stats Statistics of function logs resources Resource activity derived from function log
En general, como se muestra en la salida, varios parámetros de línea de comandos relacionados con el manejo de registros, el formato de salida para resultados o multiprocesamiento pueden definirse. Además, es necesario elegir un comando para ejecutar una tarea específica. Tenga en cuenta que el número de trabajadores solo afecta a los comandos que hacen uso del multiprocesamiento. Actualmente, estos son los comandos `detect` y `convert`.
Los comandos tienen parámetros de línea de comandos específicos que se pueden explorar proporcionando el parámetro `-h` al comando, por ejemplo, para el comando `detect` como se muestra a continuación.```
$ python3 dynmx.py detect -h
usage: dynmx.py detect [-h] --sig SIG [SIG ...] --input INPUT [INPUT ...] [--recursive] [--json-result JSON_RESULT] [--runtime-result RUNTIME_RESULT] [--detect-all]
optional arguments:
-h, --help show this help message and exit
--recursive, -r Search for input files recursively
--json-result JSON_RESULT
JSON formatted result file
--runtime-result RUNTIME_RESULT
Runtime statistics file formatted in CSV
--detect-all Detect signature in all processes and do not stop after the first detection
required arguments:
--sig SIG [SIG ...], -s SIG [SIG ...]
dynmx signature(s) to detect
--input INPUT [INPUT ...], -i INPUT [INPUT ...]
Input files
Como usuario de dynmx, puedes decidir cómo se estructura la salida. Si eliges mostrar el registro en la consola definiendo el parámetro --show-log, la salida consta de dos secciones (ver lista a continuación). El registro se muestra primero y después los resultados del comando utilizado. Por defecto, el registro no se muestra ni en la consola ni se escribe en un archivo de registro (que se puede definir usando el parámetro --log). Debido al multiprocesamiento, las entradas en el archivo de registro no están necesariamente en orden cronológico.```
|
__| _ _ _ _ _ / | | | / |/ | / |/ |/ | // _/|/ _/|/ | |/ | | |_/ /_/ /| |
Ver. 0.5 (PoC), by 0x534a
[+] Log output 2023-06-27 19:07:38,068+0000 [INFO] (main) [PID: 13315] []: Start of dynmx run [...] [+] End of log output
[+] Result [...]
El nivel de detalle de la salida del resultado se puede definir mediante el parámetro de línea de comandos `--output-format`, que se puede establecer en `overview` para un resultado de alto nivel o en `detail` para un resultado detallado. Por ejemplo, si define el formato de salida en `detail`, los resultados de detección que se muestran en la consola contendrán las llamadas API y los recursos exactos que causaron la detección. El formato de salida `overview` solo indicará qué firma fue detectada en qué registro de función.
## Líneas de comando de ejemplo
Detección de una firma *dynmx* en un registro de función con un proceso de trabajo```
python3 dynmx.py -w 1 detect -i "flog.txt" -s dynmx_signature.yml
Conversión de un registro de función al formato de registro de función genérico de dynmx``` python3 dynmx.py convert -i "flog.txt" -o /tmp/
Verificar una firma (solo comprobaciones básicas de coherencia)```
python3 dynmx.py check -s dynmx_signature.yml
Obtén una lista detallada de los recursos utilizados por una muestra de malware basada en el registro de funciones (modelo de actividad de acceso).``` python3 dynmx.py -f detail resources -i "flog.txt"
## Solución de problemas
Ten en cuenta que esta herramienta es una prueba de concepto desarrollada además de la redacción de la tesis de maestría. Por lo tanto, la calidad del código no siempre es la mejor y puede haber errores y fallos. Intenté hacer la herramienta lo más robusta posible dentro del marco de tiempo dado.
La mejor manera de solucionar errores es habilitar el registro (en la consola y/o en un archivo de registro) y establecer el nivel de registro en `debug`. Los manejadores de excepciones deberían escribir errores detallados en el registro, lo que puede ayudar a la solución de problemas.