Kerberoasting для FreeIPA. Как я искал доступ к домену, а нашел CVE

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Самые веселые баги можно найти там, где их никто не ждал, — например, в популярных решениях управления доступом, таких как FreeIPA. Представь: у нас есть возможность запросить важные данные из системы, казавшейся абсолютно защищенной. Что, если это не просто удача? Забегая вперед, скажу, что она привела меня к нескольким интереснейшим находкам.

FreeIPA — это платформа для управления идентификацией и доступом пользователей в сети, которая часто применяется для централизованного контроля прав и аутентификации. По сути, Active Directory, но для Linux.

Когда я в рамках пентеста получил учетную запись из домена на FreeIPA, оказалось, что прав у учетки почти нет. Однако выяснилось, что с помощью утилиты kvno можно запросить тикеты TGS для любого пользователя в домене FreeIPA, хотя обычные инструменты, такие как Impacket, в этом случае не работали. Вспомнив про метод подбора паролей, известный как Kerberoasting, я запустил hashcat, но и в этом случае ничего не вышло — даже при известном пароле для моего пользователя.

Тем не менее возможность получать TGS для любого пользователя домена заинтриговала меня и подтолкнула к дальнейшему исследованию.

Ищем уязвимость и пишем PoC​

Сначала попробуем поискать, что вообще пишут про это.

image1.png


Вот, например, Ли Чаголла‑Кристенсен пишет, что FreeIPA не позволяет создавать сервисы с паролем, заданным пользователем (в AD это соответствует учетной записи с SPN). Обычные учетные записи не могут использоваться как сервисы Kerberos, что делает невозможным применение атаки Kerberoasting. Это должно обеспечивать высокий уровень безопасности по умолчанию.

Что ж, раз по теме ничего нет, начинаем свое исследование. Я развернул тестовую инфраструктуру и начал изучать MIT Kerberos (который входит в состав FreeIPA). Важно было понять, как он интегрируется с 389 Directory Server — местным аналогом Active Directory.

Мне удалось установить, что при смене пароля пользователя меняется его ключ AES. Однако если у пользователей одинаковые пароли, то ключи будут разные. Значит, все дело в соли (в AD все знают, что это домен плюс имя пользователя).

После долгого исследования исходников (так как документации нигде нет) и просмотра трафика в Wireshark я установил, что для каждого пользователя во время его заведения в домен используется произвольная соль и при получении TGT-билета в первом ответе с ошибкой о необходимости преаутентификации она добавляется в специальное поле. Также ее можно обнаружить при использовании утилиты kinit с локальной переменной KRB5_TRACE.

image2.png


Как видишь, пароль может вообще состоять из произвольных символов, в том числе с пробелами и обратными слешами. Также я обнаружил, что FreeIPA работает только с AES256, что грустно.

Знание всех этих фактов позволило мне написать на Python простой скрипт, который перебирал пароли по захваченному билету и соли.

image3_Hlhb1f2.png


Билет в данном случае был взят из Wireshark, а соль для конкретного пользователя — из kinit. Полную версию скрипта ты можешь найти на моем GitHub.

Теперь оставалось разобраться с hashcat для ускорения перебора билетов. Анализируя модуль 19700, приходим к некоторым выводам.

image5_qM0GcEA.png



image6_Bn9Nw5e.png


Видим, что hashcat берет предоставленный домен, переводит его в верхний регистр и склеивает с именем пользователя, а результирующую строку использует как соль. Значит, необходимо переписать модуль. Измененный модуль выдал заветное cracked на тестовом стенде, а это значит, что можно было вернуться к заказчику.

Также я установил, что такая проблема возникает из‑за неправильной реализации модулей для MIT Kerberos, а именно не была реализована функция check_policy_tgs, которая как раз и отвечает за контроль над выдачей билетов TGS.

Компрометация домена и путь к эксплуатации​

Используя на тот момент zero day, описанный выше, и список популярных паролей, я восстановил пароль администратора домена и мог наслаждаться полной компрометацией инфраструктуры.

Для эксплуатации уязвимости сначала необходимо получить TGT на любого пользователя домена. На рисунке ниже показан запрос билета TGT для пользователя user через утилиту kinit.

Запрос TGT для user



Далее можно запросить TGS на атакуемого пользователя с помощью утилиты kvno.

Результат запроса TGS-билета для пользователя admin


Благодаря Wireshark можно вытащить TGS в исходном виде.

Далее необходимо получить уникальную соль для пользователя admin. Для этого можно использовать kinit, а как параметр передать имя пользователя, для которого нужно запросить TGS.

Результат запроса kinit для получения соли для аккаунта пользователя


Далее с помощью программы на Python можно перебрать гипотетические пароли для расшифровки захваченного TGS.

Общение с вендором​

Параллельно я сообщил об уязвимости разработчику FreeIPA, то есть в Red Hat.

image9.png



В ответ — двухнедельная тишина. Однако потом ответ все же пришел. Параллельно я написал разработчикам MIT Kerberos:
Я обнаружил уязвимость, позволяющую запрашивать тикеты TGS (сервиса выдачи тикетов) для доменных пользователей в FreeIPA. Эта уязвимость позволяет получать хеши пользователей, что также известно как Kerberoasting в Microsoft AD. Насколько я понимаю, ограничение на запросы TGS реализовано в LDAP, поэтому эта уязвимость не относится к MIT Kerberos. Это так?
Нажмите, чтобы раскрыть...

В ответ мне подробно объяснили, откуда проблема.
image10.png


В базовой версии MIT Kerberos администраторам следует установить флаг -allow_srv для пользовательских принципалов. Это подробно описано в dictionary.html и упоминается в database.html. Это, возможно, проблема, что у нас нет возможности «создать пользовательский принципал» с этим флагом по умолчанию, но этот вопрос можно обсудить публично.
В интеграциях, таких как FreeIPA и Samba, присутствуют возможности создания пользователей, для которых должен быть установлен флаг -allow_srv, если он еще не установлен.
Нажмите, чтобы раскрыть...
Я переслал и это письмо в Red Hat, после чего там все же признали баг и к концу июня этого года таки исправили его. Также присвоили ему CVE-2024-3183 и упомянули его в обновлении.

Выводы​

В результате из‑за банальной ошибки, которая существовала с самого начала разработки FreeIPA, но которую никто не замечал (скорее всего, из‑за нестандартной соли), появилась возможность не только получить результат при пентесте, но и раскрутить его до CVE.

А на тестовом стенде я также нашел CVE-2024-3657 (уязвимость в 389-ds-base, приводящая к сбою сервера каталогов) и CVE-2024-1481 (возможность специально сформированным запросом передавать аргументы для kinit), которые тоже относятся к FreeIPA и могут привести к отказу в обслуживании. Но это уже совсем другая история.

Автор @Im10n
Источник xakep.ru
 
Сверху Снизу