Эксперименты с Golden Ticket
Пожалуй, одной из самых опасных и крайне нежелательных сущностей, которые могут завестись в скомпрометированной Windows-инфраструктуре, является Golden Ticket. Это абсолютно легитимный Kerberos-билет, содержащий специально созданные данные, позволяющие злоумышленнику обойти нормальные механизмы проверки и получить высокие привилегии в сети.
С помощью золотого билета злоумышленник может получить доступ к любому ресурсу в Active Directory, притворяясь валидным пользователем, без фактической аутентификации.
Про Golden Ticket написано уже очень много статей, и аналитики знают, что такую атаку очень сложно обнаружить (большой труд в этом направлении проделали коллеги из R-Vision, рекомендуем к прочтению статью о Golden Ticket).
Не так давно Microsoft выпустила поэтапные обновления безопасности, которые меняют правила использования Golden Ticket. В этой статье мы постараемся разобраться, как обстоят дела с этой атакой сейчас и как Microsoft упростила ее детектирование своими обновлениями. Мы возьмем два инструмента (Mimikatz и Rubeus), сделаем с помощью них Golden Ticket с разными параметрами, а потом попробуем ими воспользоваться и посмотрим, какие сгенерируются события и как отследить их в SOC.
Вводные данные
Итак, у нас есть контроллер домена (Windows Server 2016 Standard, версия ОС: 10.0.14393 с не самыми последними обновлениями — KB5021235) и рабочая станция (Windows 10, версия ОС: 10.0.19045), к которой по легенде уже получил доступ злоумышленник. На данных устройствах у нас раскатана доменная политика расширенного аудита, которая в том числе имеет следующие настройки:
Журнал Security:
Account Logon
• Kerberos Service Ticket Operations — Success, Failure
Для получения событий — 4769(S, F) A Kerberos service ticket was requested
Logon/Logoff
• Group Membership — Success
• Special Logon — Success
Для получения событий — 4627(S) Group membership information и 4672(S) Special privileges assigned to new logon
Журнал System: Все события, но нас будут интересовать только 37 и 38 от источника Microsoft-Windows-Kerberos-Key-Distribution-Center (об этом чуть позже).
Все эти события мы с нетерпением ждем в SIEM.
Теперь очень коротко рассмотрим, как в нормальных условиях работает протокол Kerberos:
При легитимной доменной аутентификации по протоколу Kerberos, прежде чем получить доступ к какому-либо доменному сервису, пользователь сначала проходит аутентификацию, которая вкратце сводится к следующим шагам, в которых участвуют пользователь, контроллер домена (сервер аутентификации — AS) и ресурс, к которому пользователь хочет получить доступ:
Начальный запрос на аутентификацию (AS-REQ — Authentication Service Request). Допустим, вы — сотрудник компании, и хотите получить доступ к важной информации на защищенном файловом сервере. Вы отправляете ваш запрос на аутентификацию (AS-REQ) — словно вы показываете вашу служебную карточку охраннику у входа.
Сервер аутентификации (AS - Authentication Service). Ваш запрос достигает сервера аутентификации (AS), и он проверяет вашу служебную карточку и подтверждает ваш статус сотрудника.
Выдача начального билета (TGT — Ticket Granting Ticket). Если вы ввели свой логин и пароль правильно с первой попытки, и аутентификация проходит успешно, то сервер аутентификации (AS) выдает вам специальный «начальный билет» (TGT). Этот билет подтверждает вашу легитимность и позволяет вам двигаться дальше, и, что очень важно, этот билет подписан и зашифрован специальной учетной записью KRBTGT, которая делает аналогичные действия для всех TGT-билетов в домене.
Запрос билета для доступа к службе (TGS-REQ — Ticket Granting Service Request). Теперь, когда вы хотите получить доступ к конкретному ресурсу (в нашем примере — к файловому серверу), вы отправляете запрос на билет доступа к службе (TGS-REQ), в котором предъявляете свой начальный билет (TGT).
Сервер выдачи билетов службы (TGS — Ticket Granting Service). Сервер выдачи билетов службы (TGS) действует как следующий охранник на вашем пути. Он проверяет ваш запрос и ваш начальный билет (TGT), а затем выдает вам «билет доступа к службе» (TGS-билет), который разрешает вам доступ к ресурсу.
Доступ к ресурсу. Теперь, с билетом доступа к службе (TGS), вы можете получить доступ к ресурсу. Вы предъявляете ваш TGS-билет, и сервер ресурса знает, что вы имеете разрешение.
В случае атаки с использованием Golden Ticket злоумышленнику не нужен сервер аутентификации (контроллер домена), чтобы получить TGT: он создает его сам, причем с абсолютно любыми параметрами. Например, он может сделать очень длинный срок действия билета или указать в билете принадлежность пользователя к привилегированным группам.
Рецепт приготовления Golden Ticket достаточно прост:
1) SID домена — узнать очень легко.
2) SID и имя пользователя — до недавнего времени могли быть любыми, но получить реальные значения в скомпрометированном домене не является проблемой.
3) Хэш учетной записи KRBTGT — самый «труднодобываемый» ингредиент, который потребует проведения более сложной атаки.
Хэш учетной записи KRBTGT злоумышленник может добыть в рамках дампа базы AD или же, например, атаки DCSync.
Атака DCSync заключается в легитимной возможности репликации базы данных Active Directory (ntds.dit) между контроллерами домена. Злоумышленник может заставить удаленный контроллер домена выполнить синхронизацию ndts.dit с подконтрольным ему хостом. Для проведения атаки DCSync злоумышленник должен предварительно скомпрометировать учетную запись с правами на репликацию изменений каталога домена (Replicating Directory Changes All и Replicating Directory Changes, имеющих соответствующие GUID). Необходимыми правами обладают члены групп «Администраторы», «Администраторы домена», «Администраторы предприятия» и «Контроллеры домена».
И тут может возникнуть резонный вопрос: зачем хакеру делать Golden Ticket, если для этого нужно провести атаку, которая, по сути, уже дает полный контроль над доменом?
Дело в том, что Golden Ticket — это идеальная техника для закрепления. Представьте, что злоумышленник скомпрометировал самую желанную учетную запись — администратора домена. Вот он ходит по сети, не слишком заботясь о том, что его обнаружат, запускает странные сервисы и попадается команде реагирования. Они оперативно блокируют эту УЗ, обнаруживают дамп базы AD и меняют пароли всем пользователям.
А теперь представим, что злоумышленник выпустил золотой билет сроком действия на 10 лет для пользователя, которого даже нет в AD, да еще указал для него принадлежность к группе администраторов домена. По сути, у вас в сети появляется всемогущий призрак с ключом от всех дверей с неограниченным сроком действия. Поверьте, такое очень сложно обнаружить, а еще сложнее — вычистить.
Вернемся к нашему стенду и представим, что наш условный злоумышленник добился успеха и заполучил хэш учетной записи KRBTGT. Теперь всё готово для того, чтобы выпустить золотой билет, осталось только выбрать подходящий инструмент.
Мы проведем несколько экспериментов и посмотрим на результаты. Нас будут интересовать две вещи: сработала ли атака и какие события сгенерировались/не сгенерировались после этого.
1. Начнем с Mimikatz — одного из самых популярных инструментов для получения учетных данных и подделки билетов.
Все действия будут выполняться от имени обычного доменного пользователя без особых привилегий (конечно же, мы выключили все СЗИ, поэтому наши инструменты работают :))
Эксперимент первый — Mimikatz: несуществующий пользователь
Возьмем несуществующего пользователя (NONEXISTENT), присвоим ему SID администратора (500) и скрафтим золотой билет со стандартными параметрами:
Обратите внимание на значения групп и на то, что мы не указывали никаких параметров для групп нашего пользователя. Это параметры, которые по умолчанию делает Mimikatz и много других инструментов.
Rubeus:
ticketer.py из состава impacket:
513 (Пользователи домена), 512 (Администраторы домена), 519 (Администраторы предприятия), 518 (Администраторы схемы), 520 (Владельцы-создатели групповой политики).
Аргументом /ptt мы подгрузили билет для нашей текущей сессии, так что можем посмотреть на него командой klist. По умолчанию Mimikatz выписывает билет на 10 лет:
Попробуем использовать этот билет. Для проверки достаточно будет просто просмотреть содержание административного ресурса C$ на удаленном сервере:
План провалился. Давайте разбираться — почему?
Всё дело в пошаговом обновлении KB5008380 от Microsoft, которое усложняет аутентификационный процесс Kerberos для устранения уязвимости CVE-2021–42287. Данная уязвимость позволяла выпустить сервисный TGS-билет с привилегиями, которые выше, чем у скомпрометированной учетной записи. Условно — выпустить билет с правами администратора на обычного пользователя.
Усовершенствованный процесс аутентификации добавляет новую информацию о том, кто запросил билет в Privilege Attribute Certificate (PAC), которая записывается в TGT.
Сведения в PAC отвечают за авторизацию пользователя, содержат разрешения на доступ к разным службам, а также сведения о членстве пользователя в группах, копируются из одного билета в другой в процессе аутентификации и авторизации Kerberos.
Когда пользователь впервые успешно аутентифицируется на контроллере домена (AS_REQ), то в ответ (AS_REP) получает TGT с зашифрованными данными PAC.
Позже, когда пользователь запрашивает TGS для доступа к конкретным службам (TGS_REQ), PAC копируется из TGT в TGS. Когда TGS используется для доступа (AP_REQ), служба проверяет PAC для подтверждения разрешений пользователя на доступ.
Вышеупомянутое обновление вводит новую структуру данных в PAC, содержащую идентификатор безопасности пользователя (SID). Таким образом, контроллер домена теперь проверяет, от кого приходит запрос (по имени пользователя), и соотносит его с SID в базе AD: если есть совпадение — выдаст TGS, а если нет — увидите дальше J
Вернемся к эксперименту. Мы скрафтили билет для несуществующего пользователя, еще и подложили ему SID 500 от другой учетной записи. Это, мягко говоря, ввело наш контроллер домена в ступор, и он решил не выдавать нам TGS для доступа к appserver-01.
Прежде чем мы проведем второй эксперимент, следует сказать, что обновление KB5008380 не только усложнило жизнь злоумышленникам, но и упростило ее аналитикам. Дело в том, что данное обновление также вводит специальные события в журнал System в случае, если контроллер домена по каким-то причинам не сможет выдать TGS, а именно:
Event ID — 35
Event Text
The Key Distribution Center (KDC) encountered a ticket-granting-ticket (TGT) from another KDC (»
Event ID — 36
Event Text
The Key Distribution Center (KDC) encountered a ticket that did not contain a PAC while processing a request for another ticket. This prevented security checks from running and could open security vulnerabilities.
Client:
Ticket for:
Event ID — 37
Event Text
The Key Distribution Center (KDC) encountered a ticket that did not contain information about the account that requested the ticket while processing a request for another ticket. This prevented security checks from running and could open security vulnerabilities.
Ticket PAC constructed by:
Client:
Ticket for:
Event ID — 38
Event Text
The Key Distribution Center (KDC) encountered a ticket that contained inconsistent information about the account that requested the ticket. This could mean that the account has been renamed since the ticket was issued, which may have been part of an attempted exploit.
Ticket PAC constructed by:
Client:
Ticket for:
Requesting Account SID from Active Directory:
Requesting Account SID from Ticket:
В основном нас будут интересовать события c ID 37 и 38: как можно заметить, Mimikatz сделал PAC, но контроллер домена не смог его валидировать.
Поскольку никаких проблем с PAC контроллер домена не обнаружил, то и новых событий мы не увидим. Однако кое-что любопытное всё-таки можно увидеть. Поскольку контроллер домена не может валидировать TGT, то он его отзывает, поэтому сгенерируется событие неуспешной выдачи TGS (4769) с соответствующей причиной: «TGT has been revoked» с указанием IP-адреса, откуда мы пробовали получить доступ к appserver-01.
Мы не увидим в деталях информации о пользователе, билет которого был отозван, однако стоит однозначно обращать внимание на подобные события:
Наверное, чтобы GT всё-таки сработал, нужно его скрафтить для реального пользователя с настоящим SID-ом? Давайте проверим.
Эксперимент второй — Mmikatz: существующий пользователь, реальный SID
Возьмем обычного доменного непривилегированного пользователя goldie и укажем его SID при подделке TGT-билета:
Билет на 10 лет получили:
Постучимся на сервер:
И в таком варианте не впускает.
Всё дело в том, что Mimikatz не поддерживает новый формат PAC, который содержит информацию о том, кто запросил билет.
Хотя pull-реквест на добавление этой функции в репозитории есть:
Посмотрим на события. Там мы увидим уже знакомый нам 4769 с ошибкой о том, что TGT отозван, и почему-то снова без информации о пользователе (кто знает, почему так — прошу в комментарии!), и еще одно очень любопытное событие c EventID 37 из журнала System:
Напомним его официальное его описание:
The Key Distribution Center (KDC) encountered a ticket that did not contain information about the account that requested the ticket while processing a request for another ticket. This prevented security checks from running and could open security vulnerabilities.
Короче, нашему контроллеру домена не понравился формат PAC.
Таким образом, Mimikatz больше не получится использовать против непропатченных контроллеров домена для создания золотых билетов, так как он не поддерживает новый формат PAC в билетах TGT (по крайней мере, пока Benjamin DELPY не смержит предлагаемые изменения в код инструмента J).
Для продолжения экспериментов воспользуемся инструментом, который может в новый формат.
Эксперимент третий — Rubeus: существующий пользователь, неправильный SID
У Rubeus есть аргументы, позволяющие задавать формат PAC для разных типов контроллеров домена — пропатченных и нет:
/newpac — новый формат PAC
/oldpac — старый формат
Так, мы знаем, что пропатченный контроллер домена не даст нам воспользоваться билетом с кривым SID, но, просто ради интереса, давайте скрафтим такой с помощью Rubeus. Снова возьмем УЗ goldie, но зададим кривой SID и сделаем билет с новым форматом PAC:
Постучимся на сервер:
Чего и следовало ожидать.
Зато в событиях, помимо знакомого 4769, появляется событие из журнала System 38:
Официальное описание:
The Key Distribution Center (KDC) encountered a ticket that contained inconsistent information about the account that requested the ticket.
Если переводить описание дословно, то окажется, что контроллер домена обнаружил билет с «противоречивой/непоследовательной» информацией о пользователе, который запрашивает билет.
То есть, да, пользователь в AD такой есть, но SID у него не такой, как в билете.
Эксперимент четвертый — Rubeus: существующий пользователь, правильный SID
Ок, давайте уже создадим настоящий работающий Golden Ticket. Для этого нам понадобится реальный пользователь и его реальный SID. Сделаем GT для goldie, нашего непривилегированного пользователя:
Проверяем доступность шары нашего сервера:
Успех! И вот она, реальная опасность — непривилегированный пользователь вдруг становится членом групп администраторов домена. На этот раз мы не увидим неуспешных событий выдачи или валидации билетов, но всё-таки и в этом случае есть за что зацепиться.
Помните, какие группы по умолчанию прописываются в билет (520,512,519,518)? А знаете, какое событие генерируется, когда происходит успешный вход пользователя с правами, эквивалентными администратору? Верно — 4672 (Special Privileges Assigned To New Logon)!
Согласитесь, странно, когда такое событие приходит для УЗ обычного доменного пользователя.
Кроме того, мы можем отслеживать события 4627 (Group Membership) и искать случаи, когда непривилегированный пользователь становится вдруг членом привилегированных групп:
Кстати, если злоумышленник будет создавать золотой билет для администратора домена, то события с информацией о группах нам тоже помогут.
Например, вот событие после обычного входа администратора домена:
А вот после входа того же админа по золотому билету:
Конечно, это будет работать только в том случае, если злоумышленник не удосужится изменить стандартный список групп, который делает Rubeus.
Реагирование
Что же всё-таки делать, если есть подозрение, что злоумышленники в инфраструктуре создали Golden Tiсket? Нужно сразу сказать, что процесс реагирования может включать различные действия в зависимости от вектора компрометации, используемых злоумышленником инструментов и, не в последнюю очередь, — его итоговой цели. Важно найти «точку входа» злоумышленника, все скомпрометированные учетные записи, сервисы, хосты и прочее. Если для создания Golden Ticket злоумышленник заполучил базу ndts.dit, то, к сожалению, это означает, что весь домен скомпрометирован. В скомпрометированном домене может быть создано множество различных бэкдоров для дальнейшего развития атаки и расширения контроля над информационными активами.
Однако если сконцентрироваться именно на Golden Ticket, то можно предпринять некоторые, достаточно радикальные действия для его деактивации и невозможности дальнейшего использования в домене.
База ntds.dit содержит хэши паролей всех доменных учетных записей и, самое главное, — учетной записи krbtgt, хэшом которой, напомним, подписываются все TGT-билеты.
Соответственно, для того чтобы Golden Ticket «потерял» свою силу, нужно предпринять следующие действия:
— Cменить пароль для krbtgt
Сделать это необходимо дважды, поскольку для krbtgt сохраняется история паролей, и билеты, зашифрованные с помощью предыдущего пароля, будут валидны. Таким образом, если сменить пароль один раз, то Golden Ticket останется юзабельным.
— Cменить пароли для ВСЕХ доменных учетных записей
Поскольку ntds.dit содержит хэши паролей всех учетных записей домена, то все они также скомпрометированы, и их пароли необходимо сменить. Не имеет значения уровень привилегий учетной записи: будь то рядовой пользователь, администратор домена или же компьютерная учетная запись — все они могут быть полезны злоумышленнику для развития атаки и закрепления в пораженной инфраструктуре.
Заключение
Golden Ticket — это очень опасная атака, которая на долгие годы может поставить под угрозу доменную инфраструктуру. Лучше, конечно же, вообще избегать появления GT у себя, но вот несколько рекомендаций, которые помогут быть чуть более защищенными относительно данных атак:
1) Установите обновление безопасности KB5008380. Это не только усложнит создание GT в вашем домене, но и упростит детектирование потенциальных неуспешных попыток им воспользоваться.
2) Отслеживайте события журнала System 36, 37 и 38 — это явный индикатор того, что с билетами Kerberos, как минимум, что-то идет не так.
3) Отслеживайте события неуспешной выдачи TGS, в которых контроллер домена ругается на отозванный TGT (4769).
4) Отслеживайте события присвоения специальных, эквивалентных администратору привилегий (4672). Создайте список членов привилегированных групп и детектируйте события, когда специальные привилегии назначаются обычным доменным пользователям.
5) Отслеживайте события о членстве пользователя в группе (4627) даже для администраторов. Редко, когда администратор домена будет одновременно являться администратором схемы и владельцем-редактором доменной политики.
Группа киберисследований Jet CSIRT