
Rilevamento basato su firme di caratteristiche malware basate su sequenze di chiamate API di Windows. È come YARA per le tracce API sandbox!
dynmx (pronunciato dinamiche) è un approccio di rilevamento basato su firme per caratteristiche comportamentali di malware basate su sequenze di chiamate API di Windows. In modo semplificato, puoi pensare a dynmx come una sorta di YARA per tracce di chiamate API (i cosiddetti function log) provenienti da sandbox di malware. Quindi, la base dati per l'approccio di rilevamento non sono i campioni di malware stessi che vengono analizzati staticamente, ma i dati generati durante un'analisi dinamica del campione di malware in una sandbox di malware. Attualmente, dynmx supporta function log delle seguenti sandbox di malware:
report.json)report.json)L'approccio di rilevamento è descritto in dettaglio nella tesi magistrale Rilevamento basato su firme di caratteristiche comportamentali di malware con chiamate API di Windows. Questo progetto è l'implementazione prototipale di questo approccio ed è stato sviluppato durante la tesi magistrale. Le firme sono definite manualmente dagli analisti di malware nel DSL di firme dynmx e possono essere rilevate nei function log con l'aiuto di questo strumento. Caratteristiche e sintassi del DSL di firme dynmx si trovano anche nella tesi magistrale. Inoltre, puoi trovare firme di esempio di dynmx nel repository dynmx-signatures. Oltre a rilevare caratteristiche di malware basate su chiamate API, dynmx può estrarre risorse del sistema operativo utilizzate dal malware (un cosiddetto Modello di Attività di Accesso). Queste risorse vengono estratte esaminando le chiamate API e ricostruendo le operazioni sulle risorse del sistema operativo. Attualmente, nel modello vengono considerate le risorse del sistema operativo delle categorie filesystem, registro di sistema e rete.
Nella sezione seguente vengono mostrati esempi per il rilevamento di caratteristiche di malware e per l'estrazione di risorse.
Per questo esempio, scegliamo il campione di malware con hash SHA-256 c0832b1008aa0fc828654f9762e37bda019080cbdd92bd2453a05cfb3b79abb3. Secondo MalwareBazaar, il campione appartiene alla famiglia di malware Amadey. È disponibile un rapporto di analisi VMRay pubblico di questo campione che fornisce anche il function log tracciato da VMRay. Questo function log sarà la nostra base dati che useremo per il rilevamento.
Se volessimo sapere se il campione di malware utilizza una tecnica di iniezione chiamata Process Hollowing, possiamo provare a rilevare la seguente firma dynmx nel function log.```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
Basandoci sulla firma, possiamo trovare alcune funzionalità DSL che rendono *dynmx* potente:
* Definizione di sequenze di chiamate API con percorsi alternativi
* Corrispondenza di nomi di funzioni API con espressioni regolari
* Corrispondenza di argomenti e valori di ritorno con diversi operatori
* Archiviazione di variabili, ad esempio per tracciare gli handle nella sequenza di chiamate API
* Definizione di una condizione di rilevamento con operatori booleani (`AND`, `OR`, `NOT`)
Se eseguiamo *dynmx* con la firma mostrata sopra sulla funzione del campione `c0832b1008aa0fc828654f9762e37bda019080cbdd92bd2453a05cfb3b79abb3`, otteniamo il seguente output che indica che la firma è stata rilevata.```
$ 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
Possiamo approfondire impostando il formato di output su detail. Ora possiamo vedere la sequenza esatta delle chiamate API rilevata nel log delle funzioni. Inoltre, possiamo vedere che la firma è stata rilevata nel processo 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)
### Risorse
Per estrarre le risorse del sistema operativo accedute da un log di funzioni, possiamo semplicemente eseguire il comando *dynmx* `resources` sul log di funzioni. Un esempio dell'output dettagliato è mostrato di seguito per il campione con la somma hash SHA-256 `601941f00b194587c9e57c5fabaf1ef11596179bea007df9bdcdaa10f162cac9`. Questo è un report della sandbox CAPE che fa 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)
Basandoci sull'output mostrato e sulle risorse accedute, possiamo dedurre alcune caratteristiche del malware:
601941F00B194587C9E5.exe (PID 1800), l'identificatore di zona del file C:\Users\comp\AppData\Local\vscmouse\vscmouse.exe viene eliminatovscmouse.exe (PID: 3036) si connette agli endpoint di rete http://24.151.31.150:465 e http://107.10.49.252:80Le risorse accedute sono interessanti per identificare indicatori di rilevamento basati su host e rete. Inoltre, le risorse possono essere utilizzate nelle firme dynmx. Un esempio popolare è il rilevamento dei meccanismi di persistenza nel Registro di sistema.``` 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
## Installazione
Per utilizzare il software, Python 3.9 deve essere disponibile sul sistema di destinazione. Inoltre, è necessario installare i seguenti pacchetti Python:
* `anytree`,
* `lxml`,
* `pyparsing`,
* `PyYAML`,
* `six` e
* `stringcase`
Per installare i pacchetti, esegui il comando `pip3` mostrato di seguito. Si consiglia di utilizzare un ambiente virtuale Python anziché installare i pacchetti a livello di sistema.```
pip3 install -r requirements.txt
Per utilizzare il prototipo, esegui semplicemente il punto di ingresso principale dynmx.py. Le informazioni sull'utilizzo possono essere visualizzate con il parametro della riga di comando -h come mostrato di seguito.```
$ 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
In generale, come mostrato nell'output, è possibile definire diversi parametri della riga di comando relativi alla gestione dei log, al formato di output per i risultati o all'elaborazione multiprocesso. Inoltre, è necessario scegliere un comando per eseguire un'attività specifica. Si noti che il numero di worker influisce solo sui comandi che utilizzano il multiprocessing. Attualmente, questi sono i comandi `detect` e `convert`.
I comandi hanno parametri specifici della riga di comando che possono essere esplorati fornendo il parametro `-h` al comando, ad esempio per il comando `detect` come mostrato di seguito.```
$ 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
Come utente di dynmx, puoi decidere come è strutturato l'output. Se scegli di mostrare il log sulla console definendo il parametro --show-log, l'output è composto da due sezioni (vedi elenco sotto). Il log viene mostrato per primo e successivamente i risultati del comando utilizzato. Per impostazione predefinita, il log non viene mostrato né nella console né scritto in un file di log (che può essere definito utilizzando il parametro --log). A causa del multiprocessing, le voci nel file di log non sono necessariamente in ordine cronologico.```
|
__| _ _ _ _ _ / | | | / |/ | / |/ |/ | // _/|/ _/|/ | |/ | | |_/ /_/ /| |
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 [...]
Il livello di dettaglio dell'output dei risultati può essere definito utilizzando il parametro da riga di comando `--output-format` che può essere impostato su `overview` per un risultato di alto livello o su `detail` per un risultato dettagliato. Ad esempio, se si definisce il formato di output su `detail`, i risultati di rilevamento mostrati nella console conterranno le esatte chiamate API e le risorse che hanno causato il rilevamento. Il formato di output `overview` indicherà solo quale firma è stata rilevata in quale log di funzione.
## Esempi di righe di comando
Rilevamento di una firma *dynmx* in un log di funzione con un processo worker```
python3 dynmx.py -w 1 detect -i "flog.txt" -s dynmx_signature.yml
Conversione di un log di funzione nel formato dynmx di log di funzione generico``` python3 dynmx.py convert -i "flog.txt" -o /tmp/
Verifica una firma (solo controlli di base di integrità)```
python3 dynmx.py check -s dynmx_signature.yml
Ottieni un elenco dettagliato delle risorse utilizzate da un campione di malware basato sul log delle funzioni (modello di attività di accesso)``` python3 dynmx.py -f detail resources -i "flog.txt"
## Risoluzione dei problemi
Si prega di considerare che questo strumento è un proof-of-concept sviluppato parallelamente alla scrittura della tesi di laurea magistrale. Di conseguenza, la qualità del codice non è sempre ottimale e potrebbero esserci bug ed errori. Ho cercato di rendere lo strumento il più robusto possibile nel tempo a disposizione.
Il modo migliore per risolvere gli errori è abilitare il logging (sulla console e/o su un file di log) e impostare il livello di log a `debug`. I gestori delle eccezioni dovrebbero scrivere errori dettagliati nel log che possono aiutare nella risoluzione dei problemi.