Когда на руках валидные креды и нужно двигаться дальше по сети, самая тупая ошибка - дропнуть на диск что-то, что EDR распознает за секунду. По данным CrowdStrike Global Threat Report 2025, около 79% детектируемых атак проходят без вредоносного ПО: атакующие берут валидные учётные данные и встроенные инструменты ОС. Медианное время breakout (от первичного доступа до начала горизонтального перемещения) - 48 минут, а рекорд - 51 секунда. Пятьдесят одна, Карл.
Lateral movement Windows без малвари - не теоретический концепт и не хитрость для обхода конкретного антивируса. Это рабочая методология на трёх штатных механизмах Windows: WMI, PowerShell Remoting и DCOM. Каждый легитимен, подписан Microsoft, используется админами ежедневно - и именно поэтому правила детекта на них буксуют. WMI, PsExec и RDP идут следом по популярности.
Дальше разберу каждую из трёх техник с позиции оператора: какие команды использовать, что происходит на сетевом уровне, какие артефакты остаются в логах и - главное - почему одни подходы палятся мгновенно, а другие проходят мимо SOC незамеченными.
Требования к окружению
Прежде чем лезть в конкретные техники, зафиксирую стартовые условия. Lateral movement не начинается из воздуха - нужны предпосылки.Учётные данные. Для всех трёх техник нужен аккаунт с административными правами на целевом хосте. Доменная учётка из Domain Admins, локальный админ с одинаковым паролем на нескольких хостах, или NTLM-хэш из дампа LSASS - подойдёт любой вариант. Для WMI и DCOM работает Pass-the-Hash (T1550.002, Lateral Movement / Defense Evasion по MITRE ATT&CK); PSRemoting поддерживает Kerberos (при обращении по FQDN) и NTLM (при обращении по IP или недоступности Kerberos); Pass-the-Hash через WinRM требует принудительного NTLM (Negotiate fallback при недоступности Kerberos). Evil-WinRM и NetExec делают это корректно:
nxc winrm <target_IP> -u user -H <NTLM_hash> -x "whoami". При ручном использовании winrs/Invoke-Command PtH напрямую не пройдёт без инъекции хэша в текущий logon session (например, через Mimikatz sekurlsa::pth).Сетевая связность. WMI и DCOM используют TCP 135 (RPC Endpoint Mapper) плюс динамические порты из верхнего диапазона (49152–65535). PSRemoting работает по TCP 5985 (HTTP) или 5986 (HTTPS). Если между хостами стоит файрвол, разрешающий только RDP, - WMI и DCOM не пройдут. Тут без вариантов.
Инструментарий атакующего. На стороне оператора: Impacket (
wmiexec.py, dcomexec.py, smbexec.py), CrackMapExec / NetExec, Evil-WinRM. На стороне целевой системы не нужно ничего - используются исключительно встроенные инструменты Windows. В этом вся суть LOTL-подхода: код выполняется штатными процессами ОС.Версии ОС. Всё описанное работает на Windows Server 2012 R2 и новее, Windows 10/11. На более старых системах WinRM может быть не включён по умолчанию, но WMI и DCOM доступны практически везде - они торчат наружу с незапамятных времён.
WMI: удалённое выполнение через подсистему управления Windows
WMI (Windows Management Instrumentation) - одна из самых тихих техник lateral movement. В терминах MITRE ATT&CK это T1047 (Windows Management Instrumentation, тактика Execution). Суть проста: через WMI можно создать процесс на удалённом хосте, не копируя на него ни одного файла.Нативные средства и Impacket
Классический способ -wmic.exe /node:<target> process call create "<command>". Работает из cmd, ничего дополнительного не требует. LOLBAS классифицирует wmic.exe как LOLBin для T1047, T1105, T1218 и T1564.004. Проблема: Microsoft объявил wmic.exe deprecated ещё в 2016 году, а начиная с Windows 11 24H2 и Windows Server 2025 его выпилили из установки по умолчанию (доступен как Feature on Demand). Замена - PowerShell-командлет Invoke-WmiMethod -ComputerName <target> -Class Win32_Process -Name Create -ArgumentList "<command>" или Invoke-CimMethod. Нюанс, на котором многие спотыкаются: при удалённом вызове Invoke-CimMethod с -ComputerName по умолчанию используется WSMan (TCP 5985/5986); чтобы работать через DCOM, нужно явно создать CimSession с New-CimSessionOption -Protocol DCOM.С атакующей машины на Linux удобнее всего
wmiexec.py из Impacket. Утилита устанавливает WMI-соединение через DCOM (TCP 135 + динамический порт), создаёт процесс на удалённом хосте и забирает вывод через временный файл на шаре ADMIN$. Типичный вызов: wmiexec.py domain/user:password@target - и у вас полуинтерактивный шелл.CrackMapExec (или его форк NetExec) делает то же самое, но массово:
nxc wmi <subnet>/24 -u user -p password -x "whoami" пробежит по всем живым хостам подсети и выполнит команду через WMI. Удобно для разведки - за минуту видишь, где креды валидны.Что происходит на сетевом уровне
WMI lateral movement генерирует следующий трафик: сначала TCP-соединение на порт 135 (RPC Endpoint Mapper), затем второе соединение на динамический порт DCOM. Аутентификация - NTLM или Kerberos, зависит от того, что подаёте на вход. При использованииwmiexec.py вывод команды пишется во временный файл на ADMIN$ и забирается обратно по SMB (TCP 445) - это дополнительный артефакт, которого нет при нативном WMI-вызове.Артефакты WMI в Event Log
На целевом хосте WMI-вызов оставляет характерный след:- Event ID 4624 (Security log) - Logon Type 3 (Network) от учётной записи, использованной для подключения.
- Event ID 4688 (Security log, если включён аудит создания процессов) - создание процесса
wmiprvse.exeкак родителя вашей команды. Вот это - ключевой артефакт: еслиwmiprvse.exeпорождаетcmd.exeилиpowershell.exe, нормально настроенный SIEM это поймает. - Microsoft-Windows-WMI-Activity/Operational - журнал WMI-операций. При создании процесса через
Win32_Process.Createздесь появится событие с деталями вызова.
wmiexec.py дополнительно светится в SMB-логах из-за операций с временным файлом на ADMIN$. Нативный WMI-вызов через Invoke-WmiMethod этого не делает - он просто создаёт процесс без получения вывода. Значительно тише.PSRemoting: PowerShell как канал перемещения по сети без вредоносного ПО
PowerShell Remoting (T1021.006, Lateral Movement по MITRE ATT&CK) - самый функциональный канал для горизонтального перемещения. В отличие от WMI, который даёт только «запустил процесс и ушёл», PSRemoting предоставляет полноценную интерактивную сессию: командлеты, передача объектов, работа с файловой системой удалённого хоста.Enter-PSSession, Invoke-Command и массовое выполнение
Два основных командлета:Enter-PSSession -ComputerName <target> для интерактивной работы и Invoke-Command -ComputerName <target> -ScriptBlock { <code> } для выполнения команды и получения результата. Invoke-Command принимает массив хостов - это инструмент массового перемещения: Invoke-Command -ComputerName srv01,srv02,dc01 -ScriptBlock { Get-Process lsass } выполнит команду параллельно на трёх хостах.Для PSRemoting пентест-сценариев с Linux-хоста стандарт - Evil-WinRM:
evil-winrm -i <target> -u user -p password. Поддерживает Pass-the-Hash (-H <hash>), загрузку файлов в память, выполнение .NET-assembly без дропа на диск. Альтернатива - нативный winrs.exe на Windows: winrs -r:<target> -u:domain\user -p:password whoami (при работе вне домена нужна настройка TrustedHosts). winrs хорош тем, что это LOLBin - встроенная утилита, которая не вызывает подозрений.Сетевое поведение PSRemoting
Весь трафик идёт по TCP 5985 (WinRM over HTTP) или TCP 5986 (WinRM over HTTPS). Протокол - WS-Management поверх HTTP/SOAP. В отличие от WMI, здесь нет динамических портов и нет обращений к SMB. Данные передаются внутри HTTP-запросов, что делает PSRemoting дружелюбным к сегментированным сетям: достаточно открыть один порт.При использовании HTTPS (порт 5986) содержимое сессии шифруется TLS, и промежуточные средства мониторинга не видят команд внутри канала. Для red team операций в сетях с DPI - существенное преимущество.
Артефакты PSRemoting в логах
PSRemoting оставляет свой набор следов:- Event ID 4624 - Logon Type 3 (Network). Учётная запись, источник - IP атакующего хоста.
- Event ID 4688 - ключевой родительский процесс здесь
wsmprovhost.exe(WS-Management Provider Host). Каждая PSRemoting-сессия порождает свой экземплярwsmprovhost.exe, который становится родителем всех запущенных внутри сессии процессов. - Microsoft-Windows-PowerShell/Operational (Event ID 4103, 4104) - журнал PowerShell Script Block Logging. Если включён - здесь будут все выполненные команды. На практике многие организации не включают Script Block Logging, и вот тут защита теряет видимость.
- Microsoft-Windows-WinRM/Operational - события подключения и отключения WinRM-сессий.
Invoke-Command вместо Enter-PSSession. Интерактивная сессия генерирует больше событий WinRM (heartbeat, keep-alive), тогда как одиночный Invoke-Command - один запрос и один ответ. Залетел, сделал дело, вышел.DCOM: COM-объекты для lateral movement через встроенные механизмы Windows
DCOM (Distributed COM) - самый «экзотический» из тройки, но при правильном использовании - самый тихий. MITRE ATT&CK классифицирует это как T1021.003 (Distributed Component Object Model). Суть: некоторые COM-объекты Windows позволяют вызывать методы удалённо, а эти методы могут включать выполнение произвольных команд. Microsoft, по сути, сама оставила эти двери открытыми.Три рабочих COM-объекта
MMC20.Application - объект Microsoft Management Console. МетодDocument.ActiveView.ExecuteShellCommand позволяет запустить произвольную программу на удалённом хосте. Самый известный вектор DCOM lateral movement, описанный Matt Nelson ещё в 2017 году. На целевом хосте процесс mmc.exe порождает дочерний процесс с вашей командой.ShellWindows (CLSID
{9BA05972-F6A8-11CF-A442-00A0C90A8F39}) - коллекция открытых окон Explorer, получаемая через GetObject. Метод Windows.Item().Document.Application.ShellExecute позволяет запускать команды от имени explorer.exe. Менее известен, реже попадает в сигнатуры - лично я предпочитаю именно его, когда SOC бдит.ShellBrowserWindow (CLSID
{C08AFD90-F2A1-11D1-8455-00A0C91F3880}) - аналогичен ShellWindows, но использует другой экземпляр COM-объекта. По данным исследований Enigma0x3, ShellBrowserWindow работает преимущественно на Windows 7/Server 2008 R2 и может быть недоступен на современных Windows 10/11. Как актуальные альтернативы для DCOM lateral movement используются Excel.Application и Outlook.Application.С Linux удобнее всего
dcomexec.py из Impacket: dcomexec.py -object MMC20 domain/user:password@target. Поддерживает Pass-the-Hash через -hashes. CrackMapExec и NetExec тоже умеют выполнение через DCOM (метод mmcexec).По данным Huntress, в реальных инцидентах DCOM-перемещение через MMC20.Application - один из частых паттернов. Типичная картина: процесс
mmc.exe порождает cmd.exe, powershell.exe или закодированный PowerShell-вызов. Именно этот паттерн наблюдался при использовании dcomexec.py из Impacket и mmcexec.py из NetExec.Сетевое поведение и артефакты DCOM
DCOM lateral movement использует тот же транспорт, что и WMI: TCP 135 (RPC Endpoint Mapper) + динамический порт. Аутентификация - NTLM или Kerberos. Как иwmiexec.py, dcomexec.py по умолчанию забирает вывод через временный файл на ADMIN$ (SMB TCP 445). Чтобы избежать SMB-артефактов, можно вызвать без чтения вывода или использовать нативный вызов COM-объекта напрямую.Артефакты на целевом хосте:
- Event ID 4624 - Logon Type 3, как и в случае WMI.
- Event ID 4688 - родительский процесс зависит от COM-объекта. Для MMC20.Application это
mmc.exe(LOLBAS классифицирует как T1218.014 - MMC proxy execution). Для ShellWindows и ShellBrowserWindow -explorer.exe(LOLBAS: T1202 - Indirect Command Execution). Дочерний процесс - то, что вы запустили. - В журнале System могут появляться Event ID 10016 (DistributedCOM) при ошибках прав доступа к COM-объектам. Побочный шум, который иногда выдаёт попытку DCOM-abuse.
mmc.exe (T1218.014), порождающий cmd.exe, powershell.exe (T1059.001) или rundll32.exe (T1218.011) - почти всегда аномалия. Легитимное использование MMC не создаёт таких цепочек. Но если SOC не мониторит parent-child relationships - техника проходит как по маслу.Сравнение техник: что выбрать для горизонтального перемещения
Выбор между WMI, PSRemoting и DCOM зависит от ситуации: сетевая сегментация, включённые сервисы на целевом хосте, уровень мониторинга. Вот практическая таблица:| Параметр | WMI | PSRemoting | DCOM |
|---|---|---|---|
| Порты | 135 + динамический + 445 (wmiexec) | 5985 / 5986 | 135 + динамический |
| Pass-the-Hash | Да (Impacket, CrackMapExec) | Через Evil-WinRM | Да (Impacket, CrackMapExec) |
| Интерактивный шелл | Полуинтерактивный (wmiexec) | Полноценный | Полуинтерактивный (dcomexec) |
| Файлы на диске | Временный файл на ADMIN$ (wmiexec) | Нет | Временный файл на ADMIN$ (dcomexec, по умолчанию) |
| Характерный parent-процесс | wmiprvse.exe | wsmprovhost.exe | mmc.exe / explorer.exe |
| Шумность в логах | Средняя | Высокая (при включённом ScriptBlock Logging) | Низкая |
| Включён по умолчанию | Да | Серверы - да, рабочие станции - нет | Да |
| Лучший сценарий | Одиночное выполнение команды, разведка | Длительная работа, передача данных | Скрытное точечное выполнение |
На внутреннем пентесте я обычно начинаю с проверки WinRM (
Test-WSMan <target> или nxc winrm <target>). Порт 5985 открыт - PSRemoting даёт максимум возможностей. Закрыт - проверяю 135/445 и выбираю между WMI и DCOM. Через CrackMapExec/NetExec можно за одну команду протестировать все три метода по подсети и понять, что доступно.Почему правила детекта буксуют на LOTL-перемещении
Практика внутренних пентестов подтверждает: при имитации lateral movement с использованием PowerShell Remoting и WMI в рабочие часы, с сохранением обычной активности на скомпрометированных хостах, типовые rule-based детекты нередко дают ноль срабатываний. Ноль.Правило на нетипичное использование административных инструментов - ноль. PowerShell и WMI используются в каждой корпоративной сети постоянно, пороги настроены, чтобы не заваливать SOC ложными срабатываниями. Эта настройка и создаёт слепую зону.
Правило на внеурочную административную активность - ноль, если перемещение проводится с 8:00 до 19:00. Правило ловит ночную активность, а дневное окно остаётся невидимым.
Правило на аномальное количество подключений к контроллерам домена - снова ноль. DC получают сотни легитимных подключений в день, и умеренный атакующий трафик (несколько подключений с каждого скомпрометированного хоста) растворяется в фоновом шуме.
Это не баг конкретного SIEM. Это фундаментальная проблема rule-based детекта: если атакующий использует те же инструменты, в то же время и с тем же масштабом, что и администратор - поведенческий паттерн неотличим.
Что реально работает против LOTL lateral movement
Несмотря на сложность детектирования, есть подходы, которые дают результат.Parent-child мониторинг - самый надёжный детект для WMI и DCOM. Цепочка
wmiprvse.exe -> cmd.exe -> whoami или mmc.exe -> powershell.exe -enc ... - аномалия, которая крайне редко встречается в легитимном администрировании. Sigma-правила на process lineage здесь работают лучше, чем правила на конкретные команды.Корреляция 4624 + 4688 - подход, описанный Huntress. Связывание события аутентификации (кто зашёл, с какого IP, какой Logon Type) с последующими процессами в рамках того же LogonID даёт контекст, которого не хватает при анализе отдельных событий. Если с одного IP за час приходят Network Logon на 15 хостов с одной учёткой - это подозрительно, даже если каждое отдельное событие выглядит легитимно.
WinRM: Script Block Logging - если включён (Event ID 4104), фиксирует полный текст каждого выполненного блока PowerShell. Единственный способ видеть, что происходит внутри PSRemoting-сессии. Без него видна только оболочка
wsmprovhost.exe - содержимое остаётся за кулисами.Сетевая сегментация - не детект, но митигация. Если рабочая станция бухгалтера не может обратиться на порт 135 контроллера домена, lateral movement через WMI и DCOM физически невозможен. По данным Elisity, организации, наиболее уязвимые к Pass-the-Hash и LOTL-перемещению - те, где каждая рабочая станция может достучаться до любого сервера по SMB или RPC. Плоская сеть - подарок атакующему.
Как NTLM-хэши попадают в руки атакующего
Все три техники требуют учётных данных. В контексте LOTL-подхода наиболее актуален Pass-the-Hash (T1550.002), где вместо пароля используется NTLM-хэш. Хэши добываются из LSASS, SAM-базы, или перехватываются на сетевом уровне. Показательный свежий пример: CVE-2025-24054 - уязвимость в обработке NTLM-аутентификации Windows (CVSS 6.5, MEDIUM, вектор CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N, CWE-73 - External Control of File Name or Path). Эта уязвимость позволяла собирать NTLMv2-хэши через специально сформированные файлы.library-ms: достаточно было, чтобы пользователь просто открыл папку с таким файлом. По данным Check Point Research (апрель 2025), в марте 2025 года кампания с CVE-2025-24054 была направлена против государственных учреждений Польши и Румынии - собранные хэши далее использовались для горизонтального перемещения по сети. Затронут широкий спектр поддерживаемых версий Windows и Windows Server, включая Windows 10/11 и Windows Server 2016–2025 (полный список - в MSRC advisory).Это иллюстрирует принцип, о котором часто забывают: lateral movement Windows без малвари начинается задолго до самого перемещения - на этапе получения учётных данных, который тоже может быть fileless.
Практический чеклист: три шага перед перемещением
Перед тем как использовать любую из описанных техник, я прохожу стандартную проверку:Шаг 1 - Определить доступные транспорты. CrackMapExec или NetExec позволяют за одну команду протестировать SMB, WinRM и WMI по подсети. Результат покажет, какие порты открыты и где текущие креды дают административный доступ. Например,
nxc smb 10.10.10.0/24 -u admin -p 'P@ss' --shares проверит SMB-доступ и покажет доступные шары.Шаг 2 - Выбрать технику под ситуацию. WinRM открыт? PSRemoting - первый выбор. Только 135+445? WMI через
wmiexec.py или DCOM через dcomexec.py. EDR агрессивно мониторит wmiprvse.exe? Переключаюсь на DCOM через ShellWindows - parent-процесс explorer.exe менее подозрителен.Шаг 3 - Проверить, что оставляете. Перед массовым перемещением выполните одну тестовую команду и проверьте логи на целевом хосте: какие Event ID сгенерировались, какой parent-child видит Sysmon (если стоит), есть ли файлы на ADMIN$. Пять минут на валидацию лучше, чем спалиться на третьем хосте.
Пример тестовой команды через
dcomexec.py (Impacket), которая минимально шумит:
Код:
dcomexec.py -object MMC20 corp.local/svc_admin:'Str0ngP@ss'@10.10.10.50 'hostname'
mmc.exe и child cmd.exe.Вопрос к читателям
На пентестах с Sysmon на эндпоинтах я вижу, что правило на цепочкуwmiprvse.exe -> cmd.exe (Sysmon Event ID 1, ParentImage contains wmiprvse) ловит wmiexec.py почти всегда, но dcomexec.py с -object ShellWindows проходит - parent explorer.exe, а на него правила обычно не настроены. Кто из вас настраивал детект конкретно на DCOM abuse через ShellWindows/ShellBrowserWindow? Какой ParentImage + CommandLine паттерн в Sysmon или Sigma дал минимум false positive при мониторинге explorer.exe как родителя подозрительных дочерних процессов? Поделитесь правилом или хотя бы набором фильтров - будет интересно сравнить подходы.
Последнее редактирование: