D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Самые веселые баги можно найти там, где их никто не ждал, — например, в популярных решениях управления доступом, таких как FreeIPA. Представь: у нас есть возможность запросить важные данные из системы, казавшейся абсолютно защищенной. Что, если это не просто удача? Забегая вперед, скажу, что она привела меня к нескольким интереснейшим находкам.
FreeIPA — это платформа для управления идентификацией и доступом пользователей в сети, которая часто применяется для централизованного контроля прав и аутентификации. По сути, Active Directory, но для Linux.
Когда я в рамках пентеста получил учетную запись из домена на FreeIPA, оказалось, что прав у учетки почти нет. Однако выяснилось, что с помощью утилиты kvno можно запросить тикеты TGS для любого пользователя в домене FreeIPA, хотя обычные инструменты, такие как Impacket, в этом случае не работали. Вспомнив про метод подбора паролей, известный как Kerberoasting, я запустил hashcat, но и в этом случае ничего не вышло — даже при известном пароле для моего пользователя.
Тем не менее возможность получать TGS для любого пользователя домена заинтриговала меня и подтолкнула к дальнейшему исследованию.
Вот, например, Ли Чаголла‑Кристенсен пишет, что FreeIPA не позволяет создавать сервисы с паролем, заданным пользователем (в AD это соответствует учетной записи с SPN). Обычные учетные записи не могут использоваться как сервисы Kerberos, что делает невозможным применение атаки Kerberoasting. Это должно обеспечивать высокий уровень безопасности по умолчанию.
Что ж, раз по теме ничего нет, начинаем свое исследование. Я развернул тестовую инфраструктуру и начал изучать MIT Kerberos (который входит в состав FreeIPA). Важно было понять, как он интегрируется с 389 Directory Server — местным аналогом Active Directory.
Мне удалось установить, что при смене пароля пользователя меняется его ключ AES. Однако если у пользователей одинаковые пароли, то ключи будут разные. Значит, все дело в соли (в AD все знают, что это домен плюс имя пользователя).
После долгого исследования исходников (так как документации нигде нет) и просмотра трафика в Wireshark я установил, что для каждого пользователя во время его заведения в домен используется произвольная соль и при получении TGT-билета в первом ответе с ошибкой о необходимости преаутентификации она добавляется в специальное поле. Также ее можно обнаружить при использовании утилиты kinit с локальной переменной KRB5_TRACE.
Как видишь, пароль может вообще состоять из произвольных символов, в том числе с пробелами и обратными слешами. Также я обнаружил, что FreeIPA работает только с AES256, что грустно.
Знание всех этих фактов позволило мне написать на Python простой скрипт, который перебирал пароли по захваченному билету и соли.
Билет в данном случае был взят из Wireshark, а соль для конкретного пользователя — из kinit. Полную версию скрипта ты можешь найти на моем GitHub.
Теперь оставалось разобраться с hashcat для ускорения перебора билетов. Анализируя модуль 19700, приходим к некоторым выводам.
Видим, что hashcat берет предоставленный домен, переводит его в верхний регистр и склеивает с именем пользователя, а результирующую строку использует как соль. Значит, необходимо переписать модуль. Измененный модуль выдал заветное cracked на тестовом стенде, а это значит, что можно было вернуться к заказчику.
Также я установил, что такая проблема возникает из‑за неправильной реализации модулей для MIT Kerberos, а именно не была реализована функция check_policy_tgs, которая как раз и отвечает за контроль над выдачей билетов TGS.
Для эксплуатации уязвимости сначала необходимо получить TGT на любого пользователя домена. На рисунке ниже показан запрос билета TGT для пользователя user через утилиту kinit.
Далее можно запросить TGS на атакуемого пользователя с помощью утилиты kvno.
Благодаря Wireshark можно вытащить TGS в исходном виде.
Далее необходимо получить уникальную соль для пользователя admin. Для этого можно использовать kinit, а как параметр передать имя пользователя, для которого нужно запросить TGS.
Далее с помощью программы на Python можно перебрать гипотетические пароли для расшифровки захваченного TGS.
В ответ — двухнедельная тишина. Однако потом ответ все же пришел. Параллельно я написал разработчикам MIT Kerberos:
В ответ мне подробно объяснили, откуда проблема.
А на тестовом стенде я также нашел CVE-2024-3657 (уязвимость в 389-ds-base, приводящая к сбою сервера каталогов) и CVE-2024-1481 (возможность специально сформированным запросом передавать аргументы для kinit), которые тоже относятся к FreeIPA и могут привести к отказу в обслуживании. Но это уже совсем другая история.
Автор @Im10n
Источник xakep.ru
FreeIPA — это платформа для управления идентификацией и доступом пользователей в сети, которая часто применяется для централизованного контроля прав и аутентификации. По сути, Active Directory, но для Linux.
Когда я в рамках пентеста получил учетную запись из домена на FreeIPA, оказалось, что прав у учетки почти нет. Однако выяснилось, что с помощью утилиты kvno можно запросить тикеты TGS для любого пользователя в домене FreeIPA, хотя обычные инструменты, такие как Impacket, в этом случае не работали. Вспомнив про метод подбора паролей, известный как Kerberoasting, я запустил hashcat, но и в этом случае ничего не вышло — даже при известном пароле для моего пользователя.
Тем не менее возможность получать TGS для любого пользователя домена заинтриговала меня и подтолкнула к дальнейшему исследованию.
Ищем уязвимость и пишем PoC
Сначала попробуем поискать, что вообще пишут про это.
Вот, например, Ли Чаголла‑Кристенсен пишет, что FreeIPA не позволяет создавать сервисы с паролем, заданным пользователем (в AD это соответствует учетной записи с SPN). Обычные учетные записи не могут использоваться как сервисы Kerberos, что делает невозможным применение атаки Kerberoasting. Это должно обеспечивать высокий уровень безопасности по умолчанию.
Что ж, раз по теме ничего нет, начинаем свое исследование. Я развернул тестовую инфраструктуру и начал изучать MIT Kerberos (который входит в состав FreeIPA). Важно было понять, как он интегрируется с 389 Directory Server — местным аналогом Active Directory.
Мне удалось установить, что при смене пароля пользователя меняется его ключ AES. Однако если у пользователей одинаковые пароли, то ключи будут разные. Значит, все дело в соли (в AD все знают, что это домен плюс имя пользователя).
После долгого исследования исходников (так как документации нигде нет) и просмотра трафика в Wireshark я установил, что для каждого пользователя во время его заведения в домен используется произвольная соль и при получении TGT-билета в первом ответе с ошибкой о необходимости преаутентификации она добавляется в специальное поле. Также ее можно обнаружить при использовании утилиты kinit с локальной переменной KRB5_TRACE.

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

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


Видим, что hashcat берет предоставленный домен, переводит его в верхний регистр и склеивает с именем пользователя, а результирующую строку использует как соль. Значит, необходимо переписать модуль. Измененный модуль выдал заветное cracked на тестовом стенде, а это значит, что можно было вернуться к заказчику.
Также я установил, что такая проблема возникает из‑за неправильной реализации модулей для MIT Kerberos, а именно не была реализована функция check_policy_tgs, которая как раз и отвечает за контроль над выдачей билетов TGS.
Компрометация домена и путь к эксплуатации
Используя на тот момент zero day, описанный выше, и список популярных паролей, я восстановил пароль администратора домена и мог наслаждаться полной компрометацией инфраструктуры.Для эксплуатации уязвимости сначала необходимо получить TGT на любого пользователя домена. На рисунке ниже показан запрос билета TGT для пользователя user через утилиту kinit.

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

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

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

Я переслал и это письмо в Red Hat, после чего там все же признали баг и к концу июня этого года таки исправили его. Также присвоили ему CVE-2024-3183 и упомянули его в обновлении.В базовой версии MIT Kerberos администраторам следует установить флаг -allow_srv для пользовательских принципалов. Это подробно описано в dictionary.html и упоминается в database.html. Это, возможно, проблема, что у нас нет возможности «создать пользовательский принципал» с этим флагом по умолчанию, но этот вопрос можно обсудить публично.
В интеграциях, таких как FreeIPA и Samba, присутствуют возможности создания пользователей, для которых должен быть установлен флаг -allow_srv, если он еще не установлен.
Нажмите, чтобы раскрыть...
Выводы
В результате из‑за банальной ошибки, которая существовала с самого начала разработки FreeIPA, но которую никто не замечал (скорее всего, из‑за нестандартной соли), появилась возможность не только получить результат при пентесте, но и раскрутить его до CVE.А на тестовом стенде я также нашел CVE-2024-3657 (уязвимость в 389-ds-base, приводящая к сбою сервера каталогов) и CVE-2024-1481 (возможность специально сформированным запросом передавать аргументы для kinit), которые тоже относятся к FreeIPA и могут привести к отказу в обслуживании. Но это уже совсем другая история.
Автор @Im10n
Источник xakep.ru