Тестирование на проникновение Active Directory – зрелище не для слабонервных. Стоит только взглянуть на дорожную карту Пентеста Active Directory: “Active Directory Penetration Mind Map” как сразу становится ясным то, что это вовсе не «легкая прогулка». Тем не менее, к настоящему времени исследователями, энтузиастами и другими неравнодушными собрано достаточно большое количество статей и материалов, в которых (по моему скромному мнению) можно найти ответ на любой вопрос, и при этом рассмотреть проблему с разных сторон! По-моему мнению, данный материал возможно «размылит» тот самый замыленный глаз после использования несметного числа утилит и методик при тестировании на проникновение, и возможно заставит задуматься о тех средствах и методах, которые мы применяем в повседневной деятельности!
Более подробно о Kerberoasting вы сможете прочитать у данных авторов:
https://habr.com/ru/post/650889/
https://ardent101.github.io/posts/kerberos_general_attacks/#kerberoasting
Далее будут рассмотрены лишь типовые ошибки RedTeam при проведении данной атаки и предложен способ, который позволит их избежать.
Исходные данные: у нас есть credentials от доменного пользователя (история умалчивает о том, откуда они у нас). По большому счету их наличие может (в теории) открыть перед нами все двери. И одно из тех самых минимальных действий, которое нам доступно, является подключение по протоколу LDAP к контроллеру домена. Существуют разные способы отправки LDAP requests, в данной статье я буду использовать LDAPAdmin для более удобного восприятия информации!
SPN ( Service Principal Name)
На вид это самая безобидная строка, но по сути, любой аутентифицированный пользователь обладает возможностью запросить Service Ticket для учетной записи [c атрибутом servicePrincipalName], затем экспортировать STicket, и ввиду того, что он зашифрован на секрете сервиса, может (попытаться) подобрать пароль по словарю offline.
Impacket-GetUserSPNs
Во многих обзорах на Kerberoasting (вполне заслужено) в практической части, для демонстрации данной атаки используют Impacket-GetUserSPNs
В описании к опции –request говорится, что происходит запрос TGS для пользователей и дальнейший вывод в формате JtR/hashcat формате. Но давайте захватим Wireshark трафик при использовании данной утилиты и посмотрим, а что собственно запрашиваем!
Перед собой мы наблюдаем LDAP request, содержащий определенный набор фильтров. Рассмотрим каждый из них по отдельности!
Filter: (!(objectCategory=computer)) в данном случае говорит, что нас интересуют исключительно пользователи, а не (!) компьютеры, так как пароль к учетным записям компьютеров не является словарным.
Filter: (!(UserAccountControl:1.2.840.113556.1.4.803:=2)) означает следующее: мы ищем активные учетные записи (не отключенные (!))
Значение 2 в поле UserAccountControl [обрати внимание, что «!» знак – НЕ]
Filter: (UserAccountControl:1.2.840.113556.1.4.803:=512)
Значение 512 в поле UserAccountControl
Более детальное описание атрибута UserAccountControl можно посмотреть:
https://winitpro.ru/index.php/2018/05/14/convertaciya-atributa-useraccountcontrol-v-ad/
Filter: (servicePrincipalName=*) в данном фильтре джокерный символ «*» предполагает поиск всех значений. (Берем все, без разбору)
По большому счету, данный набор фильтров – достаточно редкое явление в бескрайних просторах сетевого трафика, а посему по праву может являться «красной тряпкой» для сотрудников подразделений ИБ и программно-аппаратных средств мониторинга сетевой активности. Более того, если мы взглянем на EventLog на контроллере домена, то увидим следующую картину.
Когда мы запрашиваем все Service Tickets для всех учетных записей, то тем самым генерируем множественные event ID 4769 на контроллере домена. Согласитесь, как минимум выглядит это очень подозрительно…
Honeypot
К одному из способов борьбы с Kerberoasting относят создание Honeypot аккаунтов с установленным атрибутом servicePrincipalName, и отслеживания запросов к ним. Действительно, при таком прямолинейном подходе, который был продемонстрирован выше этот способ борьбы будет работать прекрасно.
Как мы можем заметить, запрашивая ServiceTicket для всех учетных записей, имеющих SPN мы невольно захватили и ST для учетной записи Honeypot, при этом Blue Team специалист видит не только само событие, но также аккаунт, выполнявший его…
Дорогу осилит идущий
Кажется, мы начинаем понимать, что самый легкий способ - прямой путь к провалу! И понимая риски мы стараемся действовать аккуратнее.
Именно поэтому первым нашим действием будет подключение к контроллеру домена (например) через LDAPAdmin с последующим поиском представляющих для нас интерес SPNs.
1) Используем для поиска учетных записей те же фильтры что и в Impacket-GetUserSPNs
Это лишь 50% успеха, так как таким образом, мы не запрашиваем TGS а лишь выполняем поиск в дереве. Сетевой трафик с точки зрения LDAP запроса не поменялся, но давайте взглянем на EventLog.
Ожидаемая картина, так как билеты не запрашивались, то и нечему появляться! (Простите уж за столь очевидные комментарии). Но трафик все такой же грязный. Но почему же мы можем сказать, что это лишь 50% успеха??? Да, действительно, трафик выдает нас с потрохами, но уже сейчас мы можем начать отбор, интересующих нас учетных записей с SPN. А это в теории поможет нам не вляпаться обойти уловку с Honeypot.
Разумеется, это лишь демонстрация, и никто в здравом уме не будет называть учетную запись Honeypot. А поэтому без дополнительного анализа учетных записей нам не обойтись.
2) Ищем интересные учетки используя свои фильтры
Прелесть LDAPAdmin заключается в его наглядности (кэп). Мы уже сразу можем визуально выделить интересные названия и производить поиск в (кажущихся на первый взгляд интересными) OU. В примере я делаю поиск по всему домену. Но даже так, мы уже избавляемся от столь очевидного фильтра (servicePrincipalName=*)
Далее нам предстоит отбор только валидных учеток. Сделать это можно с использованием следующего набора атрибутов: sAMAccountName, servicePrincipalName, userAccountControl, whenCreated, whenChanged, lastLogon, pwdLastSet
В любом случае, каждый уже сам разрабатывает стратегию поиска, это лишь пример)
3) Запрос Service Ticket к интересующей нас учетной записи
Ну вот мы и определили нашу потенциальную жертву. А значит пришла пора запрашивать заветный Service Ticket. Сделать это можно с использованием Power Shell скрипта.
https://github.com/cyberark/RiskySPN/blob/master/Get-TGSCipher.ps1
Get-TGSCipher -SPN "SRV-DC01/SQLDatabase.evil.corp" -Format Hashcat
Теперь посмотрим сперва на запрос с помощью Wireshark, а уже потом на EventLog
Согласитесь, выглядит это гораздо приятнее! И вполне может сойти за легитимный запрос.
А что же в EventLog, думаю результат будет ожидаемым)
И действительно, запрос ServiceTicket выполнялся для одной учетной записи!
В данной статье я не открывал Америку, а лишь подчеркнул, на мой взгляд один из очень важных принципов деятельности Red Team – скрытность. Думаю, что если есть шанс остаться незамеченным, то его нужно использовать! Источник Вдохновения.