Детектируем горизонтальное перемещение с WMIExec
Привет, Хабр!
Ранее мы рассказывали о возможных способах выявления горизонтального перемещения (Lateral Movement) с помощью таких инструментов, как PsExec, SMBExec и AtExec. Сегодня мы продолжим «работать» с данной техникой и рассмотрим еще один инструмент — WMIExec. В статье мы разберем его принципы работы, а также покажем возможный способ детектирования инструмента как в теории, так и на практике.
Чтобы понять, как действует WMIExec для начала нужно понять принцип работы самой технологии WMI и тех компонентов, на которых она основывается.
Технология WMI
Windows Management Instrumentation (WMI) — набор расширений, появившихся в Windows еще в 1998 году. Это мощный инструмент для удалённого и локального запуска процессов, чтения и записи файлов, управления реестром, логирования.
WMI технологию нельзя назвать злонамеренной, так как она предназначена для администраторов сети и по-прежнему используется ими. Поэтому нам нужно распознать злонамеренные действия не по факту самого использования WMI, а по другим косвенным признакам. Забегая вперёд отметим, что таких признаков очень мало и они эфемерны.
Из-за сильного сходства легитимного и нелегитимного использования WMI, детектирование больше переходит в раздел статистики и определения того, какие функции WMI используются администраторами, а какие атакующими. Поэтому попробуем рассмотреть существующие подходы аудита действий WMI, чтобы как раз иметь возможность отличить действия атакующего от действий администратора.
Самый частый случай использования WMI злоумышленником — это исполнение произвольной команды с помощью ExecMethod, поэтому его мы и будем рассматривать в первую очередь. По какому принципу строится работа WMI разберем ниже.
Работа WMI в системе
Любая WMI команда для выполнения требует следующих компонентов:
svchost.exe -k netsvcs -p -s Winmgmt
Рисунок 1. Сервис Winmgmt в списке сервисов
DCOM Сервис (DCOM Service), который служит для обработки удалённых взаимодействий с WMI через DCOM, но не принимает участия при локальном использовании WMI, кроме запуска wmiprvse.exe;
WMI Хост для провайдеров (WMI Provider Host) — он же процесс wmiprvse.exe, служащий той же целью, что и dllhost.exe. Он загружает и исполняет в своём процессе провайдеры и является дочерним по отношению к DCOM сервису;
WMI провайдеры (WMI provider) — это COM объекты, которые загружаются в виде .dll файлов в хост-процесс wmiprvse.exe (по аналогии c dllhost.exe).
Если разбирать случай с удалённым запуском процесса, то алгоритм действия будет следующим.
Первый этап DCOM
Сначала через DCOM сервис идёт запрос на ISystemActivator: RemoteCreateInstance, которому передаётся в качестве аргументов CLSID 8BC3F05E-D86B-11D0-A075-00C04FB68820
и F309AD18-D86A-11d0-A075-00C04FB68820
(рисунок 2). Эти CLSID обозначают интерфейсы WbemLevel1Login и IWbemLevel1Login соответственно.
ISystemActivator: RemoteCreateInstance выполняет функцию вызова и загрузчика COM объектов, которые были ему переданы как CLSID, а так же отвечает за авторизацию клиента. Возвращает он interface pointer identifier (IPID), который нужен для обращения к новосозданному объекту. Так же возвращается номер порта, на котором будет происходить взаимодействие с новым объектом.
Второй этап — Winmgmt
Вызов IWbemLevel1Login запускает сервис Winmgmt (если он ещё не запущен), который напрямую общается с клиентом через указанный в ответе порт.
Первое действие, совершаемое на новом порту, это запрос IRemUnknown2:: RemQueryInterface с аргументом IWbemLoginClientID, который возвращает дополнительные ссылки на объект и количество ссылок на этот объект у других процессов (рисунок 2).
Рисунок 2 .Трафик при использовании Windows wmic.exe
Теперь клиент может обращаться к объекту IWbemLoginClientID и использует его метод SetClientInfo, который передаёт на сервер NETBIOS имя клиента, ничего при этом не возвращая.
Далее клиент вызывает IWbemLevel1Login: EstablishPosition. Цель этого метода в понимании, какой язык и регион использует сервер, чтобы клиент под него подстроился. При вызове этой функции сервер возвращает LocaleVersion.
После определения LocaleVersion клиент может вызывать IWbemLevel1Login: NTLMLogin. Этот метод подключает клиента уже напрямую к WMI интерфейсу. Метод принимает на вход пространство имён WMI, к которому хочет подключиться клиент (например //./root/cimv2), а также желаемый язык и выясненный в прошлом вызове метода регион. Сервер возвращает указатель на новый объект IWbemServices, после чего вызывается метод IRemUnknown2:: RemRelese. Его цель прекратить использование уже ненужных объектов, тем самым будут стёрты их указатели для клиента. В параметры передаются IPID объектов IWbemLevel1Login и IWdemLoginClientID.
С этого момента клиенту нужен только объект IWbemServices, у которого используются два метода: GetObject и ExecMethod:
GetObject применяется с целью извлечения указателя для определённого CIM класса или экземпляра.В случае с удалённым выполнением команд этим классом будет Win32_Process;
ExecMethod говорит сам за себя, он будет запускать произвольную команду на удалённой машине. Этот метод берёт в качестве аргументов CIM класс и метод этого CIM класса. В нашем случае это Create, а также аргументы к самому методу, который уже и исполняет команду.
В этот момент Winmgmt сервис совершит API вызовы и передаст команду в процесс wmiprvse.exe, импортирующий необходимые DLL библиотеки (они же COM объекты/ провайдеры) и запустит переданную ему команду.
Потенциальные артефакты
Отследить сам факт удалённого использования WMI для запуска каких-либо команд — относительно тривиальная задача. Всё, что нам нужно — это наблюдать за процессами, которые запускаются как дочерние от wmiprvse.exe.
Как уже было сказано, отличить легитимное использование WMI от вредоносного достаточно сложно. Посмотрим на трафик, сгенерированный с помощью инструмента wmiexec.py из многочисленной коллекции Impacket и стандартной утилиты Microsoft Windows wmic.exe. Для этого нам нужно вернуться к рисунку 2 и взглянуть на рисунок 3. Трафик покажет какие именно действия выполнялись утилитами:
wmic.exe — встроенная в Windows утилита для использования WMI как на локальной машине, так и на удалённой. С помощью неё можно также вызывать процессы удалённо;
wmiexec.py — утилита из состава скриптов Impacket для горизонтального перемещения.
Рисунок 2. Трафик при использовании Windows wmic.exe
Здесь мы можем заметить несколько отличий:
wmiexec.py не использует некоторые методы, которые использует wmic.exe, а именно:
wmiexec.py использует IRemUnknown вместо IRemUnknown2 (если сервер поддерживает COM-версию 5.6 или выше, Remote Unknown объект должен поддерживать интерфейс IRemUnknown2);
wmiexec.py по умолчанию применяет шифрование;
wmiexec.py аутентифицируется через NTLM, в то время как Windows машины, расположенные в домене, аутентифицируются через Kerberos.
Каждый из этих пунктов достаточно легко исправить, поскольку атакующий может добавить использование IWbemLoginClientID: SetClientInfo, IWbemLevel1Login: EstablishPosition и RemQueryInterface. Причина, по которой они не используются, кроется в их опциональности: в документации Microsoft они отмечены как методы SHOULD, а не MUST.
Также можно использовать IRemUnkown2 вместо IRemUnkown, отключить шифрование, и аутентифицироваться, применяя Kerberos. Хотя на данный момент такой функциональности нет в wmiexec.py.
Получается, что все отличия между двумя решениями сводятся лишь к признакам ленивого злоумышленника. Если у него будет желание оставлять как можно меньше следов и мимикрировать под использование wmic.exe, то мы будем бессильны без дополнительного контекста.
Перейдем к детектированию.
Возможности детектирования
Если подвести итог всего вышесказанного, то получается мы можем детектировать:
Использование WMI для выполнения команд на удалённом хосте и распознавать его от локального применения;
Использование wmiexec.py в его оригинальной (на данный момент) версии.
Единственное, что мы точно можем классифицировать как злонамеренное действие — это использование wmiexec.py, но с рядом озвученных выше оговорок.
Теперь, когда мы выяснили ключевые отличия между wmic.exe и wmiexec.py, предлагаем взглянуть на события, генерирующиеся в результате работы этих инструментов, а затем попробуем составить правило для их детектирования.
Журнал Security
Забегая немного вперед, подсветим ключевые события, которые будут включены в детект и которые показывают, что команда была запущена удалённо, а не локально:
А теперь посмотрим почему же именно на этих событиях будет строиться детект.
Ранее мы говорили, что факт использования WMI для удалённого выполнения команд можно отследить с помощью запуска любого процесса как дочернего к WmiPrvSE.exe (EventID 4688). Любого, потому что этот процесс не запускает что-либо ещё кроме WMI.
Пример события с EventID 4688 (рисунок 4):
Рисунок 4. Запуск calc.exe от имени WmiPrvSE.exe
Для детектирования именно удалённого выполнения команд, можно воспользоваться событием с EventID 4662 — An operation was performed on an object, предварительно выставив SACL на WMI объекты через WMI Control Properties.
Выставление SACL
SACL выставляется в оснастке wmimgmt.msc в WMI Control (Local) (рисунок 5), перейдя в: Свойства → Безопасность → Дополнительно → Аудит
Рисунок 5. Выставление SACL в оснастке wmimgmt.msc
Данное событие показывает, что WMI использовался удаленно для запуска процесса (Parameter 1 и Parameter 2) (рисунок 6).
Рисунок 6. Событие удаленного запуска процесса с помощью WMI
При удаленном использовании WMI в журнале будет присутствовать событие логона EventID 4624 c LogonType 3, не с пустым полем SourceNetworkAddress и полем Authentication Package, в котором в случае использования wmiexec.py будет указан NTLM (рисунок 7), а в случае wmic.exe — Kerberos (рисунок 8):
Рисунок 7. Событие сетевого входа в систему по протоколу NTLM с ip-адресом источника
Рисунок 8. Событие сетевого входа в систему по протоколу Kerberos с ip-адресом источника
Стоит отметить, что если машина не в домене, то при использовании wmic.exe для аутентификации будет также использоваться NTLM. Но при построении правила детекта мы будем считать, что атака производится на хосты, находящиеся в домене.
В качестве дополнительного события можно использовать событие c EventID 5156 The Windows Filtering Platform has permitted a connection: по нему можно отследить сетевые соединения сервиса Winmgmt, который использует сеть только в случае удалённого использования WMI (рисунок 9). Однако, для данного события необходимо дополнительно настроить аудит:
Настройка аудита
Для присутствия события с EventID 5156 нужно включить политику Audit Computer Account Management (путь: Computer Configuration\Policies\Windows Settings\Security Settings\Advanced Audit Policy Configuration\Audit Policies\Object Access\Audit Filtering Platform Connection)
Рисунок 9. Сетевое соединение сервиса Winmgmt
Однако, данное событие может использоваться только как дополнительное, так как здесь нет полезной информации, кроме IP-адресов источника и цели и портов, а IP-адрес источника подключения мы можем взять из события 4624.
Используя события журнала Security, можно определить применялся Wmic.exe или же WmiExec.py по протоколу аутентификации из события с EventID 4624. Но нельзя отметать вариант, что с wmiexec-ом при его модификации можно будет аутентифицироваться, используя и Kerberos, поэтому однозначно об их отличии нам может сказать только трафик.
Предлагаем посмотреть на возможный вариант детектирования по логам журнала Security.
Возможное правило детектирования
Исходя из приведённых событий выше было написано псевдо-правило, которое детектирует использование Wmiс.exe и wmiexec.py для удалённого запуска процессов:
SELECT (host, TargetUserName)
FROM EventCode = 4688
WHERE (parent_process_path="C:\\Windows\\System32\\wbem\\WmiPrvSE.exe") IN
(
SELECT (host, TargetUserName)
FROM EventCode = 4662
WHERE
AdditionalInfo="Remote Execute (ExecMethod)" AND
AdditionalInfo2="ROOT\\CIMV2:Win32_Process::Create"
SELECT (host, TargetUserName)
FROM EventCode = 4624
WHERE
IpAddress!="-" AND
AuthenticationPackageName IN (NTLM, Kerberos)
)
Логика детектирования здесь следующая: если на одном и том же хосте в течении одной минуты появляются события:
О запуске любого процесса от имени WmiPrvSe.exe.
Об применении WMI для удаленного запуска чего-либо.
Об успешном логоне по сети с использованием протокола NTLM, и все это происходит от имени одного пользователя.
То мы имеем дело с использованием утилиты WmiExec.py. Если же вместо NTLM мы видим протокол Kerberos, то использовался стандартный wmic.exe.
Сетевой трафик
При мониторинге сети можно детектировать как сам факт использования WMI, так и определить использовался ли его «брат» wmiexec.py. Сделать это возможно с помощью наблюдения за использованием определённых OpNum и UUID объектов в DCERPC трафике, которые будут видны даже если применять DCOM шифрование.
DCERPC — это протокол удалённого вызова процедур. Он позволяет вызывать методы/функции DLL файлов на удалённом хосте так, будто эти методы доступны на локальном хосте без нужды продумывать сетевое взаимодействие между этими хостами. DCOM является надстройкой над DCERPC и работает с COM технологией по такому же принципу.
Разница в трафике между wmic.exe и wmiexec.py уже была рассмотрена ранее (рисунок 2 и 3), поэтому тут мы выделим моменты, на которые стоит основываться при детекте:
WMI для удалённого выполнения команд можно отследить с помощью использования UUID
00011009-07e0-0000-e7a5-ca1a7da0bc2f
и OpNum сначала 6, а затем 24. Это UUID объекта IWbemServices, OpNum 6 означает вызов GetObject, а 24 — ExecMethod.Детект wmiexec.py возможно строить на множестве отличий (не забываем, что они могут быть минимизированы) и в целом детектировать по любому из них. Например, применение IRemUnknown, его хорошо видно и при DCOM шифровании.
Дополнительный аудит WMI
Стоит отметить, что WMI имеет свои собственные журналы событий, которые теоретически могут быть нам полезны:
Также, дополнительно есть возможность применять Sysmon в качестве источника информации. Однако, эти данные не использовались в детекте, потому что:
Журналы доступны не во всех версиях Windows, а те, что доступны (Microsoft-Windows-WMI-Activity) не дают какой-либо информации связанной с исполнением удалённого кода с помощью WMI;
Sysmon не логирует взаимодействие с WMI при «wmiexec.py», хотя у него есть отведённый для этого функционал.
Заключение
Таким образом, мы разобрали работу еще одного инструмента для горизонтального перемещения WMIExec, включая работу инструментов wmic.exe и wmiexec.py. Также мы рассмотрели потенциальные источники информации для построения возможного псевдо-правила и из этих данных поняли, что можем детектировать следующие ситуации:
сам факт использования технологии WMI;
использование wmiexec.py, но только при условии, что его не модифицировали.
Понять, какое поведение злонамеренное, а какое нет, можно только с помощью статистики и других средств Threat Intelligence, так как это не «взлом» технологии, а просто её нелегитимное использование. Поэтому правила детектирования скорее играют больше вспомогательную роль, чем основную.
Оставляйте ваши комментарии ниже и пишите вопросы. Надеемся, статья оказалась вам полезной!
Авторы:
— Мавлютова Валерия (@IceFlipper), младший аналитик-исследователь киберугроз.