Категория: Windows Internals / Blue Team / Purple Team
Уровень: Intermediate → Advanced
Оригинал: core-jmp.org by Jonathan Johnson
Компонент: WMI, CIMOM, COM, DCOM, WmiPrvSe.exe
Перевод: Aka Tor
Дата: Март 2026
Введение
Двухчастная статья исследует внутреннюю архитектуру Windows Management Instrumentation (WMI) и объясняет как запросы управления и действия выполняются внутри Windows. Первая часть фокусируется на основных компонентах WMI, вторая погружается глубже в механизмы COM и DCOM.
Этот первый релиз покрывает основы WMI и как отследить WMI-активность до процесса WMI Provider Host (WmiPrvSe.exe), исполняемого файла ответственного за выполнение WMI-активности.
Часть 1: Словарь WMI
Microsoft хотели иметь свою технологию для сбора информации и управления активами в масштабе предприятия. Для этого они реализовали свою версию Web-Based Enterprise Management, которую назвали Windows Management Instrumentation (WMI).
WMI имеет 4 основных компонента:
- WMI Providers: COM-серверы мониторящие управляемые объекты. Состоят из DLL (COM-сервер) и файла MOF (Managed Object Format), служащего определением WMI-класса. Обычно находятся в
C:\Windows\System32\wbem\* - Managed Objects: WMI-классы представляющие объекты — процессы, сервисы, ОС и т.д.
- WMI Infrastructure: Сервис WMI (Winmgmt), содержащий:
- CIM Object Manager (CIMOM) — обрабатывает соединение между приложениями управления и провайдерами (ядро WMI)
- WMI/CIMOM Object Repository — хранилище на диске, организованное по пространствам имён (напр.
root\cimv2). Находится вC:\Windows\System32\wbem\Repository\
- Management Application (WMI Consumer): Клиентское приложение — EXE, VBScript, PowerShell скрипт
Сервис WMI (WinMgmt) хранится в wmisvc.dll, загружается и работает внутри svchost.exe:
Бинарник WmiPrvSe.exe (WMI Provider Host) загружает правильные COM-серверы (WMI провайдеры) для выполнения задач. Запускается через C:\Windows\system32\wbem\wmiprvse.exe -secured -Embedding, родительский процесс — svchost с DcomLaunch.
Пример высокоуровневого вызова WMI:
- Сервис WMI (
wmisvc.dll) запущен в процессе SVCHOST - Приложение управления (powershell.exe) выполняет WMI метод
- WmiPrvSe запускается под DcomLaunch svchost
- Сервис WMI загружает соответствующий WMI провайдер в WmiPrvSe
- WmiPrvSe выполняет функцию, выраженную методом
Часть 1: Пошаговый разбор WMI
Поиск WMI класса
PS > Get-CimClass -MethodName *Create*
NameSpace: ROOT/cimv2
CimClassName CimClassMethods CimClassProperties
------------ --------------- ------------------
Win32_Process {Create, Terminat... {Caption, Description, ...}
Win32_BaseService {StartService, St... {Caption, Description, ...}
Win32_Service {StartService, St... {Caption, Description, ...}
Поиск WMI провайдера
PS > (Get-CimInstance __Provider -Filter "Name = '$(([WmiClass] 'Win32_Process').Qualifiers['provider'].Value)'").CLSID
{d63a5850-8f16-11cf-9f47-00aa00bf345c}
PS > Get-ItemPropertyValue -Path "Registry::HKEY_CLASSES_ROOT\CLSID\{d63a5850-8f16-11cf-9f47-00aa00bf345c}\InprocServer32\" -Name '(default)'
C:\WINDOWS\system32\wbem\cimwin32.dll
Итого:
- WMI Class:
Win32_Process - Method:
Create - Provider:
cimwin32.dll - Namespace:
ROOT/cimv2
Параметры метода
PS > (Get-CimClass -ClassName Win32_Process).CimClassMethods['Create'].Parameters
Name CimType Qualifiers ReferenceClassName
---- ------- ---------- ------------------
CommandLine String {ID, In, MappingStrings}
CurrentDirectory String {ID, In, MappingStrings}
ProcessStartupInformation Instance {EmbeddedInstance, ID, In, MappingStrings}
ProcessId UInt32 {ID, MappingStrings, Out}
Создание скрытого процесса
PS > $Win32_ProcessStartupClass = Get-CimClass -ClassName Win32_ProcessStartup
PS > $ProcessStartupInformation = New-CimInstance -CimClass $Win32_ProcessStartupClass -Property @{'ShowWindow' = 0} -ClientOnly
PS > Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine='notepad.exe'; CurrentDirectory='C:\'; ProcessStartupInformation=$ProcessStartupInformation}
ProcessId ReturnValue PSComputerName
--------- ----------- --------------
2432 0
Процесс создан под WmiPrvSe.exe:
Загруженные DLL в WmiPrvSe.exe подтверждают провайдер cimwin32.dll:
Получение информации о процессе через WMI
PS > Get-CimInstance -ClassName Win32_Process -Filter "ProcessId = 15444" ProcessId Name HandleCount WorkingSetSize VirtualSize --------- ---- ----------- -------------- ----------- 15444 notepad.exe 190 13496320 2203470827520
Часть 2: WMI и COM — глубокое погружение
Шаг 1: Идентификация PowerShell команды
Фокусируемся на Register-ScheduledTask:
Это функция (не PS cmdlet), использующая CDXML (cmdlet definition XML) — автогенерированную обёртку для WMI класса.
Шаг 2: Найти CDXML
Файл: C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ScheduledTasks\PS_ScheduledTask_v1.0.cdxml
WMI класс: PS_ScheduledTask в пространстве имён Root/Microsoft/Windows/TaskScheduler.
Шаг 3: Найти WMI провайдер
Get-CimClass -Namespace root/Microsoft/Windows/TaskScheduler -ClassName PS_ScheduledTask | Select-Object -ExpandProperty CimClassQualifiers
Шаг 4: Получить бинарник WMI провайдера
WMI провайдер: schedprov.dll
Шаг 5: Анализ WMI провайдера в IDA
Открываем schedprov.dll в IDA, ищем функцию RegisterByUser:
Находим вызов CoCreateInstance:
Три ключевых параметра CoCreateInstance:
- rclsid (Параметр 1) — CLSID объекта (
CLSID_TaskScheduler — 0F87369F-A4E5-4CFC-BD3E-73E6154572DD) - riid (Параметр 4) — идентификатор интерфейса
- ppv (Параметр 5) — адрес указателя на полученный интерфейс
Через OleViewDotNet определяем интерфейс — ITaskService:
Декомпилированный пример
Применяя структуру к ppv, видим вызываемые методы:
Ассемблерный пример
PPV и var_218 содержат одну и ту же ячейку памяти. var_218 разыменовывается дважды, затем вызывается смещение 50h — это COM метод в интерфейсе ITaskService:
Применяя структуру ITaskServiceVtbl и наведя на 50h:
Документация Microsoft для ITaskService::NewTask:
Собираем всё вместе
Применив бинарный анализ к WMI провайдеру (schedprov.dll) мы определили что WMI класс PS_ScheduledTask в итоге вызывает COM метод NewTask::ITaskService. Поток функций:
Цель этого поста — подчеркнуть как некоторые технологии вызывают другие для выполнения задачи «под капотом». Следует отметить что не каждый WMI класс работает именно так — хотя WMI построен на основе COM, класс может просто вызывать Win32 API для выполнения задачи.
Атаки полагаются на технологии, предоставляемые операционной системой. Понимание этих концепций помогает лучше понимать эти технологии и, в свою очередь, эти атаки.
Благодарности
Спасибо Matt Graeber и Alex Ionescu за ревью блога.
Ссылки
- core-jmp.org — оригинал
- Автор: Jonathan Johnson
- Windows Internals Book Part 2, Chapter 10
















