Привет, Хабр! Ранее мы рассказывали о возможных способах выявления горизонтального перемещения (Lateral Movement) с помощью таких инструментов, как PsExec, SMBExec и AtExec. Сегодня мы продолжим "работать" с данной техникой и рассмотрим еще один инструмент - WMIExec. В статье мы разберем его принципы работы, а также покажем возможный способ детектирования инструмента как в теории, так и на практике. Чтобы понять, как действует WMIExec для начала нужно понять принцип работы самой технологии WMI и тех компонентов, на которых она основывается. Windows Management Instrumentation (WMI) - набор расширений, появившихся в Windows еще в 1998 году. Это мощный инструмент для удалённого и локального запуска процессов, чтения и записи файлов, управления реестром, логирования. WMI технологию нельзя назвать злонамеренной, так как она предназначена для администраторов сети и по-прежнему используется ими. Поэтому нам нужно распознать злонамеренные действия не по факту самого использования WMI, а по другим косвенным признакам. Забегая вперёд отметим, что таких признаков очень мало и они эфемерны. Из-за сильного сходства легитимного и нелегитимного использования WMI, детектирование больше переходит в раздел статистики и определения того, какие функции WMI используются администраторами, а какие атакующими. Поэтому попробуем рассмотреть существующие подходы аудита действий WMI, чтобы как раз иметь возможность отличить действия атакующего от действий администратора.  Самый частый случай использования WMI злоумышленником - это исполнение произвольной команды с помощью ExecMethod, поэтому его мы и будем рассматривать в первую очередь. По какому принципу строится работа WMI разберем ниже. Любая WMI команда для выполнения требует следующих компонентов: WMI инфраструктуры (WMI infrastructure) -  классический Windows сервис (рисунок 1), запускающийся следующим образом: 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 сервис идёт запрос на 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), который нужен для обращения к новосозданному объекту. Так же возвращается номер порта, на котором будет происходить взаимодействие с новым объектом. Вызов IWbemLevel1Login запускает сервис Winmgmt (если он ещё не запущен), который напрямую общается с клиентом через указанный в ответе порт. Первое действие, совершаемое на новом порту, это запрос IRemUnknown2::RemQueryInterface с аргументом IWbemLoginClientID, который возвращает дополнительные ссылки на объект и количество ссылок на этот объект у других процессов (рисунок 2). Теперь клиент может обращаться к объекту 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 для горизонтального перемещения. Здесь мы можем заметить несколько отличий: wmiexec.py не использует некоторые методы, которые использует wmic.exe, а именно: IWbemLoginClientID::SetClientInfo IWbemLevel1Login::EstablishPosition RemQueryInterface 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, предлагаем взглянуть на события, генерирующиеся в результате работы этих инструментов, а затем попробуем составить правило для их детектирования. Забегая немного вперед, подсветим ключевые события, которые будут включены в детект и которые показывают, что команда была запущена удалённо, а не локально: EventID 4688 - A new process has been created; EventID 4662 - An operation was performed on an object; EventID 4624 - An account was successfully logged on. А теперь посмотрим почему же именно на этих событиях будет строиться детект. Ранее мы говорили, что факт использования WMI для удалённого выполнения команд можно отследить с помощью запуска любого процесса как дочернего к WmiPrvSE.exe (EventID 4688). Любого, потому что этот процесс не запускает что-либо ещё кроме WMI. Пример события с EventID 4688 (рисунок 4): Для детектирования именно удалённого выполнения команд, можно воспользоваться событием с EventID 4662 - An operation was performed on an object, предварительно выставив SACL на WMI объекты через WMI Control Properties. SACL выставляется в оснастке wmimgmt.msc в WMI Control (Local) (рисунок 5), перейдя в: Свойства -> Безопасность -> Дополнительно -> Аудит  Данное событие показывает, что WMI использовался удаленно для запуска процесса (Parameter 1 и Parameter 2) (рисунок 6). При удаленном использовании WMI в журнале будет присутствовать событие логона EventID 4624 c LogonType 3, не с пустым полем SourceNetworkAddress и полем Authentication Package, в котором в случае использования wmiexec.py будет указан NTLM (рисунок 7), а в случае wmic.exe - Kerberos (рисунок 8):  Стоит отметить, что если машина не в домене, то при использовании 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)   Однако, данное событие может использоваться только как дополнительное, так как здесь нет полезной информации, кроме IP-адресов источника и цели и портов, а IP-адрес источника подключения мы можем взять из события 4624. Используя события журнала Security, можно определить применялся Wmic.exe или же WmiExec.py по протоколу аутентификации из события с EventID 4624. Но нельзя отметать вариант, что с wmiexec-ом при его модификации можно будет аутентифицироваться, используя и Kerberos, поэтому однозначно об их отличии нам может сказать только трафик. Предлагаем посмотреть на возможный вариант детектирования по логам журнала Security. Исходя из приведённых событий выше было написано псевдо-правило, которое детектирует использование Wmiс.exe и wmiexec.py для удалённого запуска процессов: Логика детектирования здесь следующая: если на одном и том же хосте в течении одной минуты появляются события: О запуске любого процесса от имени 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 имеет свои собственные журналы событий, которые теоретически могут быть нам полезны: Microsoft-Windows-WMI-Activity; Microsoft-Windows-DistributedCOM. Также, дополнительно есть возможность применять Sysmon в качестве источника информации. Однако, эти данные не использовались в детекте, потому что:  Журналы доступны не во всех версиях Windows, а те, что доступны (Microsoft-Windows-WMI-Activity) не дают какой-либо информации связанной с исполнением удалённого кода с помощью WMI; Sysmon не логирует взаимодействие с WMI при "wmiexec.py", хотя у него есть отведённый для этого функционал.  Таким образом, мы разобрали работу еще одного инструмента для горизонтального перемещения WMIExec, включая работу инструментов wmic.exe и wmiexec.py. Также мы рассмотрели потенциальные источники информации для построения возможного псевдо-правила и из этих данных поняли, что можем детектировать следующие ситуации: сам факт использования технологии WMI; использование wmiexec.py, но только при условии, что его не модифицировали. Понять, какое поведение злонамеренное, а какое нет, можно только с помощью статистики и других средств Threat Intelligence, так как это не "взлом" технологии, а просто её нелегитимное использование. Поэтому правила детектирования скорее играют больше вспомогательную роль, чем основную. Оставляйте ваши комментарии ниже и пишите вопросы. Надеемся, статья оказалась вам полезной! Авторы: - Мавлютова Валерия (@IceFlipper), младший аналитик-исследователь киберугроз.  Профиль команды SEA