
Обнаружение вредоносного ПО на основе сигнатур по последовательностям вызовов Windows API. Это как YARA для трейсов API из песочницы!
dynmx (произносится динамикс) — это подход к обнаружению на основе сигнатур поведенческих особенностей вредоносного ПО, использующий последовательности вызовов Windows API. Упрощенно можно считать dynmx своего рода YARA для трассировок вызовов API (так называемых функциональных логов), получаемых из песочниц для вредоносного ПО. Таким образом, основой данных для обнаружения являются не сами образцы вредоносного ПО, анализируемые статически, а данные, генерируемые в ходе динамического анализа образца в песочнице. В настоящее время dynmx поддерживает функциональные логи следующих песочниц:
report.json)report.json)Подход к обнаружению подробно описан в магистерской диссертации Signature-Based Detection of Behavioural Malware Features with Windows API Calls. Данный проект является прототипной реализацией этого подхода и был разработан в рамках магистерской диссертации. Сигнатуры вручную определяются аналитиками вредоносного ПО на предметно-ориентированном языке сигнатур dynmx и могут быть обнаружены в функциональных логах с помощью этого инструмента. Особенности и синтаксис предметно-ориентированного языка dynmx также описаны в магистерской диссертации. Кроме того, примеры сигнатур dynmx можно найти в репозитории dynmx-signatures. Помимо обнаружения особенностей вредоносного ПО на основе вызовов API, dynmx может извлекать ресурсы операционной системы, используемые вредоносным ПО (так называемая Модель Доступа к Ресурсам). Эти ресурсы извлекаются путём анализа вызовов API и восстановления операций с ресурсами ОС. В настоящее время в модели учитываются ресурсы ОС категорий файловая система, реестр и сеть.
В следующем разделе приведены примеры обнаружения особенностей вредоносного ПО и извлечения ресурсов.
Для этого примера выберем образец вредоносного ПО с SHA-256 хеш-суммой c0832b1008aa0fc828654f9762e37bda019080cbdd92bd2453a05cfb3b79abb3. Согласно MalwareBazaar, образец относится к семейству вредоносного ПО Amadey. Существует публичный отчёт анализа VMRay этого образца, который также предоставляет функциональный лог, записанный VMRay. Этот функциональный лог будет нашей основной базой данных, которую мы используем для обнаружения.
Если мы хотим узнать, использует ли образец вредоносного ПО технику внедрения, называемую Process Hollowing, мы можем попытаться обнаружить следующую сигнатуру dynmx в функциональном логе.```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
Основываясь на сигнатуре, можно выделить некоторые возможности DSL, которые делают *dynmx* мощным:
* Определение последовательностей вызовов API с альтернативными путями
* Сопоставление имен функций вызовов API с регулярными выражениями
* Сопоставление аргументов и возвращаемых значений с помощью нескольких операторов
* Хранение переменных, например, для отслеживания дескрипторов в последовательности вызовов API
* Определение условия обнаружения с помощью булевых операторов (AND, OR, NOT)
Если запустить *dynmx* с показанной выше сигнатурой для функции образца `c0832b1008aa0fc828654f9762e37bda019080cbdd92bd2453a05cfb3b79abb3`, мы получим следующий вывод, указывающий, что сигнатура была обнаружена.```
$ 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
Мы можем углубиться в детали, установив формат вывода в detail. Теперь мы можем увидеть точную последовательность вызовов API, которая была обнаружена в журнале функций. Кроме того, мы можем видеть, что сигнатура была обнаружена в процессе 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)
### Ресурсы
Для извлечения используемых ресурсов ОС из журнала функций можно просто выполнить команду *dynmx* `resources` для этого журнала функций. Пример подробного вывода показан ниже для образца с хеш-суммой SHA-256 `601941f00b194587c9e57c5fabaf1ef11596179bea007df9bdcdaa10f162cac9`. Это отчет песочницы CAPE, который является частью [набора данных Avast-CTU Public CAPEv2](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)
На основе показанного вывода и полученных ресурсов можно сделать вывод о некоторых функциях вредоносного ПО:
601941F00B194587C9E5.exe (PID 1800) удаляется Zone Identifier файла C:\Users\comp\AppData\Local\vscmouse\vscmouse.exevscmouse.exe (PID: 3036) подключается к сетевым конечным точкам http://24.151.31.150:465 и http://107.10.49.252:80Полученные ресурсы представляют интерес для идентификации индикаторов обнаружения на уровне хоста и сети. Кроме того, ресурсы могут использоваться в сигнатурах dynmx. Популярным примером является обнаружение механизмов сохранения в реестре.``` 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
## Установка
Для использования программного обеспечения на целевой системе должен быть доступен Python 3.9. Кроме того, необходимо установить следующие пакеты Python:
* `anytree`,
* `lxml`,
* `pyparsing`,
* `PyYAML`,
* `six` и
* `stringcase`
Чтобы установить пакеты, выполните команду `pip3`, показанную ниже. Рекомендуется использовать виртуальное окружение Python вместо установки пакетов в систему.```
pip3 install -r requirements.txt
Чтобы использовать прототип, просто запустите главную точку входа dynmx.py. Информацию об использовании можно просмотреть с помощью параметра командной строки -h, как показано ниже.```
$ 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
В целом, как показано в выводе, можно задать несколько параметров командной строки, касающихся обработки журналов, формата вывода результатов или многопроцессорной обработки. Кроме того, необходимо выбрать команду для выполнения конкретной задачи. Обратите внимание, что количество рабочих процессов влияет только на команды, использующие многопроцессорную обработку. В настоящее время это команды `detect` и `convert`.
Команды имеют свои параметры командной строки, которые можно просмотреть, передав параметр `-h` команде, например, для команды `detect`, как показано ниже.```
$ 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
Как пользователь dynmx, вы можете решить, как будет структурирован вывод. Если вы решите показывать журнал на консоли, задав параметр --show-log, вывод будет состоять из двух разделов (см. листинг ниже). Сначала отображается журнал, а затем результаты использованной команды. По умолчанию журнал не отображается на консоли и не записывается в файл журнала (который можно задать с помощью параметра --log). Из-за многопроцессорной обработки записи в файле журнала не обязательно находятся в хронологическом порядке.```
|
__| _ _ _ _ _ / | | | / |/ | / |/ |/ | // _/|/ _/|/ | |/ | | |_/ /_/ /| |
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 [...]
Уровень детализации выводимого результата можно задать с помощью параметра командной строки `--output-format`, который может быть установлен в `overview` для общего результата или в `detail` для подробного результата. Например, если задать формат вывода `detail`, то результаты обнаружения, отображаемые в консоли, будут содержать точные вызовы API и ресурсы, вызвавшие обнаружение. Формат вывода `overview` лишь укажет, какая сигнатура была обнаружена в каком журнале функции.
## Примеры командных строк
Обнаружение сигнатуры *dynmx* в журнале функции с одним рабочим процессом```
python3 dynmx.py -w 1 detect -i "flog.txt" -s dynmx_signature.yml
Преобразование лога функций в универсальный формат журнала функций dynmx``` python3 dynmx.py convert -i "flog.txt" -o /tmp/
Проверить подпись (только базовые проверки)```
python3 dynmx.py check -s dynmx_signature.yml
Получить подробный список ресурсов, использованных образцом вредоносного ПО, на основе журнала функций (модель активности доступа).``` python3 dynmx.py -f detail resources -i "flog.txt"
## Устранение неполадок
Пожалуйста, учтите, что этот инструмент является proof-of-concept, разработанным параллельно с написанием магистерской диссертации. Поэтому качество кода не всегда идеальное, и могут присутствовать ошибки и баги. Я старался сделать инструмент максимально надёжным в рамках отведённого времени.
Лучший способ устранения ошибок — включить ведение журнала (в консоль и/или в файл) и установить уровень логирования на `debug`. Обработчики исключений должны записывать подробные ошибки в журнал, что может помочь в диагностике.