Обход защитных механизмов: как вредоносное ПО избегает обнаружения
Чтобы снизить вероятность обнаружения, а также замаскировать вредоносное ПО и усложнить анализ инцидента, злоумышленники используют различные техники, описанные в матрице MITRE ATT&CK. Киберпреступники часто комбинируют несколько методов и применяют их на разных этапах атаки: от первоначального доступа до дальнейшего передвижения по инфраструктуре.
В этой статье мы разберем несколько распространенных техник сокрытия вредоносного ПО, рассмотрим примеры их использования и покажем, как выявлять подобную активность с помощью правил корреляции.
Техники сокрытия вредоносного ПО
Living off the land
Название техники переводится как питание подножным кормом. Суть в том, что злоумышленники используют уже установленные в системе программы для достижения своих целей. Встроенные утилиты имеют легитимную цифровую подпись и чистый хеш в онлайн‑сервисах для анализа файлов (например, VirusTotal). Кроме того, администраторы также используют эти утилиты, поэтому вредоносная активность может затеряться среди легитимной. К часто используемым инструментам относятся PowerShell, WMI (Windows Management Instrumentation), PsExec и другие. Подробнее об этих инструментах мы говорили в статье «Утилиты Windows, которые любят злоумышленники (LOLBins)».
Однако использование легитимных утилит не гарантирует, что антивирус не сработает: эвристические алгоритмы могут выявить подозрительную активность. Чтобы скрыть содержимое команд, злоумышленники прибегают к обфускации.
Обфускация
Обфускация — преднамеренное усложнение кода программы, которое затрудняет его анализ. Этот метод используют не только злоумышленники, но и разработчики, чтобы защитить программы от взлома и нелегитимного распространения. Для обфускации могут применять кодирование, например Base64, присваивать переменным и функциям трудноразличимые имена, использовать шифрование, стеганографию, бесполезный код и другие приемы.
Вредоносное ПО часто запутывает ключевые строки в программе или ее поведение, чтобы затруднить обнаружение средствами защиты и усложнить анализ. Выигранное время злоумышленники могут использовать, чтобы дольше оставаться незаметными в инфраструктуре или заражать другие машины в сети, если их цель — массовое распространение, а не атака на конкретный объект.
Для обфускации часто используют готовые алгоритмы, которые находятся в свободном доступе. Многие из них уже изучены сообществом, поэтому вместо деобфускации с нуля проверьте, существуют ли уже готовые скрипты или методики для конкретного алгоритма.
В качестве примера использования обфускации рассмотрим следующий скрипт.
SHA‑256: c52be6c430af5af99dd11fd2dd7e854b49b201ddae555b4325ee4a5961e088e6.
Он отвечает за загрузку и выполнение следующего этапа полезной нагрузки. Следите за ходом анализа по скриншотам.
Приводим код в читаемый вид и сразу замечаем строки, закодированные в Base64:

В начале файла также есть подозрительные функции (они выделены цифрами и подчеркнуты):

Можно начать анализ с основной логики и разбирать код строка за строкой, чтобы не тратить время на неиспользуемые функции. Но в нашем примере таких нет, так что мы деобфусцируем и проанализируем сразу:
vekselsa(1)— выбирает из переданной строки каждый четвертый символ, начиная с индекса 3. Для деобфускации всех строк, которые передаются в эту функцию, можно использовать Python‑скрипт:
import sys
string = sys.argv[1]
for i in range(3, len(string), 4):
print(string[i],end='')
Klarin(2)— выполняет командуiex(Invoke-Expression), закодированную в переменной$retsopgret. Благодаря этому злоумышленник может выполнять команды при каждом вызове функции.verg(3)— представляет собой закодированную команду XOR.Indemn(4)— декодирует команды из Base64, выполняет операцию XOR с заранее заданным массивом$sightseeinи, в зависимости от значения аргумента$stal, запускает декодированную команду с помощью функцииvekselsa. Логика функции показана на скриншоте ниже:

Теперь разберем строки и основную логику. Для деобфускации строк можно использовать следующий код для PowerShell:
$input_base64 = $args[0];
$xor_array = @(75,97,116,111,100,101,115,116,114,97);
$decode_array = [Convert]::FromBase64String($input_base64);
For($iterator=0; $iterator -lt $decode_array.Length; $iterator++)
{
$decode_array[$iterator] = ($decode_array[$iterator] -bxor $xor_array[$iterator%10]);
}
$output = [Text.Encoding]::ASCII.GetString($decode_array);
Write-Output $output;
Приведенный скрипт принимает строку в Base64 и выводит декодированную команду или ее часть. После обработки всех обфусцированных строк и изменения исходного кода получаем следующий результат:

Выделим важные моменты в логике:
- Для доставки второй части полезной нагрузки используется Google Drive.
- Вторая фаза заражения содержит код в Base64.
- Скачанный файл сохраняется в
%APPDATA%под именемTriticin[.]pro.
Теперь понятно, что вредоносное ПО загружает с Google Drive полезную нагрузку, также закодированную в Base64, и запускает ее на скомпрометированной машине.
Обфускация усложняет статический анализ, при котором файл изучают без запуска, например, с помощью утилит для поиска строк. Однако песочницы используют другой подход: запускают подозрительный файл в изолированной среде и анализируют его поведение. Против этого обфускация малоэффективна. Поэтому следующая задача атакующего — не скрыть код, а обнаружить саму среду анализа.
Обход песочниц и виртуальных машин
Большинство крупных компаний используют песочницы как часть системы защиты, а специалисты по анализу ВПО проводят динамический анализ на виртуальных машинах, чтобы не подвергать риску рабочие станции. Принцип действия песочниц мы рассматривали в статье «Что такое песочница и как она работает: внутренняя кухня автоматического анализа».
Если ВПО не вызовет срабатывания правил корреляции в песочнице, средство защиты может классифицировать его как безопасное. В результате вредоносное ПО пройдет периметр и попадет в инфраструктуру компании. Чтобы ВПО определило, что работает в виртуальном окружении, а не на рабочей станции, злоумышленники используют техники виртуализации и обхода песочниц (Virtualization / Sandbox Evasion).
В этой главе рассмотрим следующие методы:
- Поиск строк в реестре (например, значение ключа
HKLM\SYSTEM\CurrentControlSet\Services\Disk\Enum). - Поиск специфичных драйверов (проверка на установленные Guest Additions или VMWare Tools).
- Поиск не используемых в настоящих системах аппаратных значений (например, значение BIOS вендора равно VMware или QEMU).
- Специфичные MAC‑адреса (например, у VMWare это префикс
00:05:69). - Низкоуровневые техники обнаружения работы в виртуализированной среде.
Информацию о BIOS или драйвере предоставляют встроенные в ОС инструменты.
# Запрос BIOS
$bios = Get-CimInstance -ClassName Win32_BIOS
if ($bios.Manufacturer -match 'VMware|Virtual|Xen|Microsoft|QEMU') {
$hints += "WMI BIOS Manufacturer: $($bios.Manufacturer)"
}
# Поиск драйверов на хосте с фильтром по характерным подстрокам
$drivers = Get-WmiObject Win32_SystemDriver | Where-Object {
$_.Name -match 'VBox|VMware|vmmem|hv|virtio'
}
if ($drivers) {
$hints += "Found virtual driver(s): $($drivers.Name -join ', ')"
}
Чтобы разобраться, как работают низкоуровневые техники обнаружения виртуализированной среды, необходимы знания ассемблера, поэтому их разберем чуть подробнее:
- Red‑Pill — эта техника ВПО использует инструкцию
sidt. Она сохраняет значение IDT (interrupt descriptor table, таблица дескрипторов прерываний). В некоторых эмуляторах IDT для виртуальной машины располагается по адресам, отличным от адресов основной таблицы хоста, что позволяет определить виртуальное окружение. - No Pill — техника обнаружения виртуального окружения с помощью инструкции
sldt. При вызове инструкции на 64‑битной хостовой машине значение нижних двух байтов будет равно нулю, а на 32‑битной — одному байту. Ненулевое значение может указывать на гостевую ОС. Это наблюдение основано на обычном поведении Windows при работе со структурой LDT (local descriptor table, локальная таблица дескрипторов). Она считается устаревшей, поэтому не используется на хостовых системах. Однако гипервизор может применять эту структуру для сегментации памяти гостевой ОС, в результате чего значения могут быть ненулевыми. - CPUID — техника, связанная с одноименной инструкцией. Если вызвать ее с
EAX = 1, результат сохранится вECX, где 31‑й бит содержит флагHypervisor Present. Если этот флаг установлен, значит, система работает под управлением гипервизора, то есть является виртуальной машиной, а не физическим устройством. В отличие от виртуализации памяти, которая используется в любой системе, этот флаг сигнализирует об эмуляции самого процессора или системы. Также инструкцию можно вызвать сEAX = 0x40000000. ВEBX,ECXиEDXвернется идентификатор гипервизора, напримерKVMKVMKVMдля QEMU,Microsoft Hvдля Hyper‑V илиVMwareVMwareдля VMware. - Hypervisor‑specific MSR (Model‑Specific Registers) — техника, заключающаяся в использовании инструкции
rdmsrсECX, равным0x4b564d00(MSR_KVM_WALL_CLOCK_NEW),0x4b564d01(MSR_KVM_SYSTEM_TIME_NEW) или0x4b564d02(MSR_KVM_ASYNC_PF_EN), команда вернет значения регистров, специфичных для гипервизора KVM. Однако перед такой проверкой рекомендуется вызватьCPUIDсEAX = 0x40000001и проверить бит 3: он должен быть установлен в1.
Эти техники можно заметить как при динамическом анализе (запросы к ключам реестра), так и при дизассемблировании ВПО (низкоуровневые техники, специфические строки).
Ниже — пример Sigma‑правила
"VirtualBox|VMware|KVM|HVM":
title: AntiVM
status: experimental
description: Detect virtual environment "VirtualBox|VMware|KVM|HVM"
author: Joe Security
date: 2019-11-06
id: 200020
threatname:
behaviorgroup: 5
classification: 8
mitreattack: T1497
logsource:
category: process_creation
product: windows
detection:
selection:
CommandLine:
- '*IlZpcnR1YWxCb3h8Vk13YXJlfEtWTXxIVk0i*'
condition: selection
level: critical
В качестве примера рассмотрим этот образец:
SHA‑256: a799052d8068f5f2ecfefee27c690abb3f3de90bbd98e5b0a4459f0827b3fec2.
Это вредоносное ПО относится к стилерам: оно собирает данные, но не закрепляется в системе.
Ниже приведены строки, связанные с данными браузера и загрузкой процессора:


Помимо строк можно заметить функции, используемые для сбора информации о зараженном хосте:



Разберем эти функции:
- GetComputerNameEx — получает FQDN хоста (доменного имени).
- GetUserNameW — получает учетную запись, под которой запущен процесс.
- GlobalMemoryStatusEx — извлекает сведения о том, как система использует физическую и виртуальную память прямо сейчас.
При просмотре строк файла можно заметить такие подстроки, как VMWareTray.exe или vmtoolsd.exe. Найденные строки на скриншоте:

При дальнейшем исследовании адресов, связанных с этими строками, можно увидеть, что ВПО сравнивает строки с некоторым буфером.

Этот буфер заполняется при помощи вызова функции NtQuerySystemInformation. Значение, помещенное в ECX, — это тип получаемой информации, в нашем случае это 5 (получение информации о запущенных процессах и потоках в системе).

Теперь каждый элемент из списка процессов будет искаться в ранее обнаруженной строке. Если совпадение найдено (memcmp возвращает 0 через EAX), инструкция test eax, eax изменяет zero flag, после чего выполняется переход к loc_14001EDBB. Затем программа определяет, что ее исследуют, и завершает работу.
Если поиск по процессам не дает результата, основная функция для проверки завершается с кодом 0, после чего вредоносный код продолжает выполнение.
В качестве примера Anti‑VM используем следующее вредоносное ПО.
SHA‑256: dd4a261e45a02d4a645ced0c80673a5eb91e08c5d345e248eb63d424528f494a.
В нем нет действий, описанных ранее, но он проверяет объем доступного кеша в процессоре.

Поскольку гипервизоры, например VirtualBox и VMware, не всегда эмулируют уровни кеша, запрос под номером 1 может вернуть пустой массив. Тогда проверка под номером 2 будет выглядеть примерно так: 0 < 2?. Функция вернет true, что указывает на работу внутри виртуальной машины.
На физическом хосте запрос вернет минимум три элемента, соответствующие уровням кеша L1, L2 и L3, если процессор не слишком старый. Если злоумышленник старается, чтобы песочница его не обнаружила, а также стремится затруднить или замедлить анализ, он может использовать антиотладочные техники.
Антиотладчик (anti‑debugger)
Отладка позволяет наблюдать за действиями вредоносного ПО при запуске, отслеживать поток выполнения, а также менять поведение исследуемой программы в зависимости от заданных условий. Поэтому наряду с обходом песочниц злоумышленники используют антиотладочные техники. Для обнаружения отладки применяют как встроенные возможности ОС, так и особенности самой отладки и системы в целом.
Ниже приведены несколько способов определить, что процесс отлаживается:
- Флаг
BeingDebuggedнаходится в Process Environment Block (PEB) и указывает, отлаживается процесс или нет. Его значение можно проверить напрямую или с помощью функции WinAPIIsDebuggerPresent(). - Поле
NtGlobalFlagтакже находится в PEB и содержит флагиFLG_HEAP_VALIDATE_PARAMETERS,FLG_HEAP_ENABLE_TAIL_CHECKиFLG_HEAP_ENABLE_FREE_CHECK. Чтобы проверить наличие отладки, их можно сопоставить с маской0x70: если результат не нулевой, программа, вероятнее всего, выполняется под отладчиком. - В архитектуре AMD64 доступны отладочные регистры
DR0–DR4,DR6иDR7. Если значение одного из них отлично от нуля, это может указывать на то, что процесс выполняется под отладчиком. - Замер времени между двумя участками кода с помощью
QueryPerformanceCounterилиGetTickCount. Поскольку при отладке выполнение программы замедляется, разница во времени может оказаться больше ожидаемой. Если измеренное значение превышает заданный злоумышленником порог, процесс, скорее всего, выполняется под отладчиком.
Рассмотрим пример. В качестве образца возьмем Lab16-03.exe из лабораторного практикума к книге «Вскрытие покажет! Практический анализ вредоносного ПО» (Practical Malware Analysis: The Hands‑On Guide to Dissecting Malicious Software) Майкла Сикорски и Эндрю Хонига:
SHA‑256: f36de55cf09c24045f241d50519a2ff1e5578336d0e8426eeabe5b39162d9006.
При статическом анализе в строках можно найти имена функций GetTickCount и QueryPerformanceCounter:

Наличие этих строк указывает на возможное использование антиотладочной техники с замером времени выполнения. Чтобы проверить эту гипотезу, можно перейти в IDA и изучить дизассемблированный код.
Если перейти в функцию sub_4011E0, можно увидеть два вызова QueryPerformanceCounter. Нас интересуют соседние с ними инструкции, выделенные красными прямоугольниками. Переменные PerformanceCount и var_110 хранят результаты этих вызовов. Если между ними проходит больше 1200 тактов процессора, вредоносное ПО считает, что работает под отладчиком.

На этом антиотладочные действия не заканчиваются. В функции main есть разветвление с GetTickCount:

Если функция sub_401000 выполняется не более чем за 1 мс, программа продолжает работу. Если выполнение занимает больше времени, возникает исключение при обращении к памяти по адресу 0x0.
При дальнейшем разборе функции sub_401300 можно заметить инструкцию RDTSC. По смыслу она похожа на рассмотренные ранее GetTickCount и QueryPerformanceCounter: инструкция возвращает значение счетчика тактов процессора (time‑stamp counter, TSC). Старшие 32 бита результата сохраняются в EDX, младшие — в EAX.

На скриншоте выше выделены важные блоки функции sub_401300. Разберем их:
- Первый вызов
RDTSC. - Манипуляции с регистрами и вызов исключения при делении на ноль по адресу
0x00401346. - Второй вызов
RDTSCи сравнение результата с ранее сохраненным в стеке значениемEAX. Если прошло больше0x7A120h(500 000) тиков, процесс считается отлаживаемым, после чего программа удаляет себя с помощью функцииsub_4010E0.
Чтобы нейтрализовать такие антиотладочные проверки, при отладке их можно заменить инструкциями NOP, как показано на рисунке:

Также можно изменять значение регистров при отладке, но есть риск не заметить повторную проверку.
Разберем еще пример из той же книги — Lab16-01.exe.
SHA‑256: 309217d8088871e09a7a03ee68ee46f60583a73945006f95021ec85fc1ec959e.
В этом примере проверим PEB, ProcessHeap и NtGlobalFlag. Флаги исследуются в самом начале функции main.

Цифрами выделены следующие аспекты:
- 1 — проверка флага
BeingDebugged: получаем PEB, затем смещаемся на 2 байта — там находится нужный флаг. - 2 — проверка
ProcessHeapс выставленнымForceFlag: получаем PEB, затем по смещению0x18извлекаем структуруProcessHeapи сохраняем ее в регистрEAX. В этой структуре нас интересует значение по смещению0x10, где хранится флаг. - 3 — проверка
NtGlobalFlag: загружаем PEB, обращаемся к значению по смещению0x68, где хранится нужный флаг. Он устанавливается только при запуске процесса под отладчиком. Если подключить отладчик к уже работающему процессу, значение флага не изменится.
Антиотладочные техники и AntiVM затрудняют динамический анализ. Следующая техника мешает уже статическому анализу — не только строк, но и дизассемблированного кода.
Упаковщики
Этот инструмент уменьшает размер приложения при помощи упаковки исходного кода, а в некоторых случаях — шифрования, при этом возможности самой программы не меняются. Как и в случае с обфускаторами, кастомные упаковщики встречаются редко. Обычно злоумышленники используют уже известные или немного модифицированные алгоритмы из открытого доступа.
Примеры используемых упаковщиков:
- UPX,
- ASPack,
- eXPressor,
- PECompact.
Логика работы упаковщика обычно выглядит так:
- Запуск программы‑заглушки, которая распаковывает или расшифровывает основную программу.
- Распаковка исходного кода программы.
- Импорт функций, которые использует упакованная логика.
- Передача управления в оригинальную точку входа (OTB).
Чтобы определить, используется ли упаковщик, следует обратить внимание на следующие характеристики или аспекты семпла:
- Малое количество импортов функций. Например, некоторые упаковщики используют только
LoadLibraryилиGetProcAddress. - Высокая энтропия разделов файла.
- Несоответствие размеров разделов программы. Например, для раздела
.textв полеSize of Raw Dataуказано значение0, а вVirtual Size— ненулевое. - Наличие разделов, характерных для конкретного упаковщика, например UPX.
Помимо наблюдения, для обнаружения упаковщиков используются специальные инструменты, такие как PEiD или Detect It Easy.
Интерфейс утилиты PEiD представлен на скриншоте:

Перейдем к практике и рассмотрим следующий образец вредоносного ПО, упакованный с помощью UPX:
SHA‑256: 4b16baf674e02084875303e4ae72066d7b6431340efe58a37b7840eb36b6a026.
Для ручной распаковки будем использовать x32dbg.
При распаковке файлов, упакованных с помощью UPX, важную роль играют инструкции PUSHAD и POPAD. Они помещают в стек или достают из стека соответственно значения всех регистров, чтобы вернуть программу к моменту старта заглушки.
Запускаем исследуемую программу в отладчике и попадаем на инструкцию PUSHAD:

Ставим аппаратную точку останова на доступ к значению ESP-4. Можно задействовать DWORD, WORD или BYTE, это не принципиально. Эта точка сработает при вызове инструкции POPAD. В нашем случае это значение 0x0019ff74.

При срабатывании точки останова мы будем сразу на POPAD или на следующей за ней инструкции.

Теперь переходим по JMP и видим следующий код:

Это и есть original entry point (OEP, оригинальная точка входа). Теперь необходимо восстановить import addresss table (IAT, таблицу импортов). Для этого надо нажать на комбинацию клавиш Ctrl + I. Откроется окно:

Нужно кликнуть на кнопки в следующей последовательности:
- IAT Autosearch.
- Get Imports.
- Dump.
- Fix Dump.
Обычно автоматический поиск IAT срабатывает корректно. Если этого не происходит, таблицу можно исправить вручную. В нашем случае IAT определилась автоматически. Остается загрузить распакованное вредоносное ПО в дизассемблер для анализа.
Можно не восстанавливать IAT: достаточно сделать дамп программы, загрузить его в дизассемблер и самостоятельно найти динамически связанные функции. Если ВПО планируется исследовать в динамике, можно работать с исходным упакованным образцом.
Рассмотренные техники помогают злоумышленникам обходить средства защиты и затруднять анализ. Чтобы дольше оставаться незамеченными, атакующие также могут дополнительно скрывать артефакты уже в скомпрометированной системе.
Сокрытие артефактов
В большинстве ОС предусмотрены механизмы, позволяющие скрывать разнообразные артефакты, включая:
- элементы выполнения административных задач;
- системные файлы;
- конфигурационные файлы или папки (например, пользовательская конфигурация SSH).
В обычной ситуации благодаря этим механизмам системные, конфигурационные и другие файлы не мешают пользователям при работе за компьютером. Но злоумышленники используют их для маскировки своей активности.
Некоторые способы, которые ВПО может использовать для сокрытия своей активности:
- скрытые файлы и директории;
- скрытые пользователи;
- скрытые окна;
- исключения для АВПО;
- мимикрия под легитимные процессы;
- расширенные атрибуты и альтернативные потоки данных NTFS.
Чтобы понять, как действуют злоумышленники и как обнаружить их активность, рассмотрим некоторые из перечисленных техник.
Исключения для АВПО
Самый простой способ скрыть активность от антивирусного ПО — использовать исключения. Злоумышленники могут добавить вредоносное ПО или каталог, в котором оно находится, в список исключений.
Например, для Windows Defender это можно сделать такой командой:
Add-MpPreference -ExclusionPath <path to folder/file>
Аналогичные исключения хранятся в ветке реестра HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions. В ней указаны каталоги, IP‑адреса и процессы, которые антивирус исключает из проверки.
Альтернативные потоки данных
В New Technology File System (NTFS) Microsoft добавила возможность создавать альтернативные потоки данных для поддержки Hierarchical File System (HFS) от Apple. Такие потоки есть не только у файлов, но и у директорий. У каждого файла есть как минимум один поток, который содержит все данные файла и называется mainstream (главный, основной поток).
При просмотре каталога с файлом, у которого есть альтернативный поток данных, отображается только сам файл:

На скриншоте ниже видно, что альтернативные потоки не влияют на размер основного потока (основного файла) в файловой системе:

Программа, скрытая в альтернативном потоке, может быть запущена, например, такой командой:

Вручную обнаружить альтернативные потоки в папке поможет утилита Streams.exe от Марка Руссиновича или dir /r из командной строки.
Ниже — пример вывода утилиты dir с флагом /r:

Скрытые пользователи
Чтобы закрепиться в системе, злоумышленники могут создать отдельную учетную запись, которая позволит не менять пароль скомпрометированной учетной записи и не привлечет внимание. Эту учетную запись используют для дальнейшего доступа или запуска программ.
Однако при входе на скомпрометированный хост пользователь может заметить незнакомую учетную запись, что вызовет подозрение и может заставить обратиться в поддержку или службу безопасности. Также пользователь может переустановить ОС.
Чтобы избежать таких ситуаций, злоумышленники создают скрытую учетную запись. В Windows для этого можно создать подключ SpecialAccounts\UserList в ключе реестра HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon. Одно из значений DWORD в нем называют именем учетной записи и задают ему значение 0.
Мимикрия под легитимные процессы
Еще один способ скрыть артефакты — мимикрия под легитимные программы или сервисы. Для этого злоумышленники используют похожие названия, которые легко не заметить при беглом просмотре. Например, процесс могут назвать expIorer.exe вместо explorer.exe.
Мимикрия может затрагивать и расположение файла. Например, вредоносную программу можно сохранить по пути %APPDATA%\svchost.exe. В этом случае на подозрительную активность указывает несвойственный для процесса каталог: легитимный svchost.exe находится по пути C:\Windows\System32\svchost.exe.
Детектирование и мониторинг
Чтобы обнаружить и залогировать действия злоумышленников, можно настроить базовый аудит безопасности или использовать сторонние средства мониторинга. Так как Event ID или средства мониторинга могут использоваться для разных техник, их настройку повторно рассматривать не будем. Корреляционные правила будем писать на языке запросов Lucene для Elasticsearch.
LoTL
Чтобы обнаружить использование легитимных утилит, помогут следующие события:
- Event ID 1 — Process Create (Sysmon).
- Event ID 19 — WmiEvent WmiEventFilter (Sysmon).
- Event ID 20 — WmiEvent WmiEventConsumer (Sysmon).
- Event ID 21 — WmiEvent WmiEventConsumerToFilter (Sysmon).
- Event ID 4697 — A service was installed in the system (Windows Security).
- Event ID 7045 — New Service was installed (Windows System).
Чтобы получать события Sysmon, его можно скачать с официального сайта Microsoft и установить.
Подготовим корреляционные правила для запуска и использования PsExec или WMI:
# Старт PsExec
(
event_id:("1" OR "4688") AND
process.file_path:*PsExec*
) OR
(
event_id:"11" AND
file_path:*PsExec*
)
OR
(
event_id:("4697" OR "7045") AND
service_name:"PsExeSvc"
)
# WMI для запуска интерпретатора командной строки
(
event_id:("1" OR "4688") AND
process.file_path:(*powershell* OR *cmd*)
process_parent.file_path:*wmiprvse*
)
# WMI для работы с Consumer и/или Filter
event_id:("5861" OR "21" OR "19" OR "20")
Обфускация
Из базовых логов Windows нас могут интересовать следующие события:
- Event ID 4104/800 — PowerShell Script Block Logging (PowerShell\Operational).
- Event ID 4103 — Module logging (PowerShell\Operational).
- Event ID 1 — Process Create (Sysmon).
Все эти события Windows по умолчанию не логирует. Чтобы включить первые два, необходимо настроить групповую политику. Для этого нужно:
- Перейти по следующему пути:
Computer Configuration/Administrative Templates/Windows Components/Windows PowerShell
- Включить аудит пунктов
Module LoggingиPowerShell Script Block Logging.
После чего можно приступить к написанию детектирующей логики:
# Ловим Invoke-Expression
(
event_id:("1" OR "800") AND
process.cmdline: ("iex" OR "Invoke-Expression")
) OR
(
event_id:"4104" AND
powershell.script_block_text: ("iex" OR "Invoke-Expression")
) OR
(
event_id:"4103" AND
powershell.data_payload:"Invoke-Expression"
)
# Ловим Base64 строки
(
event_id: "1" AND
(
process.file_path:"powershell.exe" AND
process.cmdline:(*FromBase64String* AND "-EncodedCommand")
)
) OR
(
event_id:"4104" AND
(
powershell.script_block_text: ("-EncodedCommand" OR *FromBase64String*)
) OR
event_id:"800" AND
(
powershell.cmdline: ("-EncodedCommand" OR *FromBase64String*)
)
)
Правило переносится в SIEM‑систему, где отслеживаются события с хоста. Если событие соответствует заданному фильтру, пользователь, администратор или аналитик SOC получает уведомление. Такие правила можно использовать и в песочницах, чтобы точнее детектировать поведение анализируемого образца.
Сокрытие артефактов
Чтобы обнаружить техники маскировки, могут потребоваться следующие Event ID:
- Event ID 1 — Process Create (Sysmon).
- Event ID 4104/800 — Powershell Script Block Logging (PowerShell\Operational).
- Event ID 12 — Registry object added or deleted (Sysmon).
- Event ID 13 — Registry value modifications (Sysmon).
- Event ID 4657 — A registry value was modified (Windows Security).
Для логирования событий 4657 необходимо включить аудит в групповой политике:
Computer Configuration/Windows Settings/Security Settings/Advanced Audit Policy Configuration/Object Access/Audit Registry
Детектирующая логика:
# Ловим скрытого пользователя
(
event_id: ("12" OR "13" OR "4657") AND
register_key:"windows nt\\currentversion\\winlogon\\specialaccounts\\userlist" AND
register_data:"0"
) OR
(
event_id:"1" AND
process.cmdline:(*reg* AND "Windows NT\\CurrentVersion\\Winlogon\\SpecialAccounts\\UserList" AND "0")
)
# Добавление исключения для Windows Defender
(
event_id: ("12" OR "13" OR "4657") AND
register_key:"SOFTWARE\\Microsoft\\Windows Defender\\Exclusions"
) OR
(
event_id:("1" OR "800") AND
process.cmdline:("Add-MpPreference" AND "ExclusionPath")
)
OR
(
event_id:"4104" AND
(
powershell.script_block_text: ("Add-MpPreference" AND "ExclusionPath")
)
)
# Запуск скрипта из альтернативного потока
event_id:"1" AND
process.cmdline:("wscript" OR "cscript") AND
process.cmdline.keyword:/.*\.[a-zA-Z0-9_\-]+\:[a-zA-Z0-9_\- ]+?\.(vbs|vbe|vba|js|bat|cmd|php).*/
# Запуск мимикрирующего процесса
event_id:("1" OR "4688") AND
process.file_path:(\\services.exe~3 OR \\explorer.exe~3 OR \\svchost.exe~3) AND # название файла процесса различается на 3 символа максимум
-process.file_path:("\\svchost.exe" OR "\\services.exe" OR "\\explorer.exe") # исключаем название легитимного файла
# Запуск процесса из несвойственной ему папки
event_id:("1" OR "4688") AND
process.file_path:("\\taskhostw.exe" OR "\\lsass.exe" OR "\\winlogon.exe") AND
-process.file_path:("C:\\Windows\\System32\\taskhostw.exe" OR "C:\\Windows\\System32\\lsass.exe" OR "C:\\Windows\\System32\\winlogon.exe") # исключаем легитимный файл
Упаковщики и техники Anti‑Debugger / Anti‑VM
Обнаруживать такие техники сложнее, потому что сами по себе они не оставляют характерных событий в логах. Попытки Anti‑VM можно обнаруживать по командной строке, например по запуску процессов для поиска признаков виртуализации — такой пример мы уже разбирали в Sigma‑правиле. Для антиотладочных техник и упаковщиков этот подход не работает. Здесь специалистам по анализу помогают YARA‑правила
В правилах можно указывать автора, ссылку на статью или пример ВПО, описание логики, условия срабатывания правила (condition), интересующие подстроки внутри файла (strings) и другие параметры. Ниже представлены по два YARA‑правила для каждой техники:
# Антиотладка
rule DebuggerCheck__QueryInfo : AntiDebug DebuggerCheck {
meta:
weight = 1
Author = "naxonez"
reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara"
strings:
$ ="QueryInformationProcess"
condition:
any of them
}
rule DebuggerCheck__PEB : AntiDebug DebuggerCheck {
meta:
weight = 1
Author = "naxonez"
reference = "https://github.com/naxonez/yaraRules/blob/master/AntiDebugging.yara"
strings:
$ ="IsDebugged"
condition:
any of them
}
# Анти-виртуализация/Anti-Virtualization
rule Check_VBox_Description
{
meta:
Author = "Nick Hoffman"
Description = "Checks Vbox description reg key"
Sample = "de1af0e97e94859d372be7fcf3a5daa5"
strings:
$key = "HARDWARE\\Description\\System" nocase wide ascii
$value = "SystemBiosVersion" nocase wide ascii
$data = "VBOX" nocase wide ascii
condition:
all of them
}
rule Check_VmTools
{
meta:
Author = "Nick Hoffman"
Description = "Checks for the existence of VmTools reg key"
Sample = "de1af0e97e94859d372be7fcf3a5daa5"
strings:
$ ="SOFTWARE\\VMware, Inc.\\VMware Tools" nocase ascii wide
condition:
any of them
}
# Упаковщики
rule vmprotect {
meta:
description = "VMProtect packed file"
reference = "https://github.com/godaddy/yara-rules/blob/master/packers/vmprotect.yara"
block = false
quarantine = false
strings:
$mz = "MZ"
$vmp0 = {2E766D7030000000}
$vmp1 = {2E766D7031000000}
condition:
$mz at 0 and $vmp0 in (0x100..0x300) and $vmp1 in (0x100..0x300)
}
rule upx {
meta:
description = "UPX packed file"
reference = "https://github.com/godaddy/yara-rules/blob/master/packers/upx.yara"
block = false
quarantine = false
strings:
$mz = "MZ"
$upx1 = {55505830000000}
$upx2 = {55505831000000}
$upx_sig = "UPX!"
condition:
$mz at 0 and $upx1 in (0..1024) and $upx2 in (0..1024) and $upx_sig in (0..1024)
}
Чтобы просканировать файлы, можно использовать утилиту YARA. Пример запуска:

Заключение
В статье мы разобрали техники, которые злоумышленники используют для сокрытия активности, и написали детектирующую логику для ее обнаружения. Описанные методы не исчерпывают все возможные варианты: по мере развития средств защиты атакующие усложняют техники и комбинируют их между собой.
Именно поэтому аналитику SOC важно смотреть на атаку глазами злоумышленника. Понимание, как вредоносное ПО пытается остаться незамеченным, помогает точнее настраивать детектирующие правила и быстрее реагировать на инциденты. Чем глубже это понимание, тем сложнее атакующему действовать незаметно.