Атака Kerberoasting без пароля пользователя — миф, или новая реальность?
Всем привет!
Меня зовут Алексей, я работаю в компании «Визум», и занимаюсь тестированием на проникновение, направления классические — инфраструктура и веб. Данную статью меня сподвиг написать мой друг и коллега — Михаил Л., совместно с которым мы и провели данный небольшой ресерч.
Все, кто, так или иначе, касался проведения атак на доменную инфраструктуру, построенную на основе Active Directory, почти 100% имели дело с атакой Kerberoasting, которая позволяет получить TGS-билеты для SPN, ассоциируемых с пользовательскими учетными записями, и далее — попробовать восстановить их пароли, при условии, что сами пароли достаточно простые (подробнее про атаку — прочитать можно тут).
Относительно недавно на Hack The Box появилась машина уровня INSANE — Rebound. Не буду расписывать, как ее решать, тем более — уже вышел официальный райтап от Ральфа. Хочу только обратить внимание на один момент из данного райтапа, а именно — проведение атаки Kerberoasing от имени доменного пользователя, к которому НЕТ пароля, но при этом — для пользователя не требуется прохождение Pre-Authentication (очень подробно про керберос можно почитать тут).
Рис. 1 Выдержка из райтапа по прохождению Rebound
Ральф просто говорит, что — там аутентификация не требуется, значит можно. Данное высказывание ввело нас с коллегами в ступор. До недавнего времени, мы все искренне считали, что ответом на вопрос «А можно ли проводить атаку Kerberoasting, не имея пароля пользователя?» будет однозначное «нет» (если речь не идет о какой-либо уязвимости, например, CVE-2022–33679). Ведь даже если у используемой нами учетной записи пользователя отсутствует предварительная аутентификация, мы получаем его TGT-билет, и если попытка сбрутить содержащийся в нем сессионный ключ успехом не увенчалась, то сделать запросы TGS-REQ, чтобы запросить множество TGS-билетов у нас не получится. А сессионный ключ как раз и подписывается секретом пользователя! Ну, т.е. без пароля — никак.
Смотрим райтап, и удостоверяемся, что сессионный ключ в получаемом TGT бруту не поддается. Так каким же образом делается Kerberoasting??? А он там делается!
Рис. 2 Наше с коллегами недоумение
Я решил, что мои знания касательно данного вопроса просто несколько устарели, и пошел гуглить и спрашивать коллег на данную тему. Каково же было мое удивление, когда все, что я смог нагуглить по данному вопросу — пара статей без подробностей (раз, два), а все коллеги, которые без преувеличения, гуру в области пентеста инфраструктуры, пожали плечами. При этом, данный метод был опробован как минимум на 3-х инфраструктурах с пользователем без предварительной аутентификации, и везде метод сработал.
Кстати, забегая вперед, стоит отметить, что функционал для данной атаки уже внесен в официальный репозиторий Impacket v12. Строчка для запуска атаки выглядит так:
GetUserSPNs.py -dc-ip
где
— ip-адрес Контроллера Домена;
— логин пользователя, у которого нет Pre-Authentication;
— список логинов доменных пользователей;
— домен.
Ставится инструмент таким образом:
Если не установлен pipx:
pip install pipx
pipx ensurepath
pipx install git+https://github.com/fortra/impacket --force
В один из вечеров, я и Михаил, вооружившись снифером, взяли стэнд, где есть все условия для проведения атаки, и пошли выяснять, что же посылает этот Impacket. Каково же было наше удивление, когда в дампе трафика мы увидели…отсутствие TGS-REQ, как факт.
Рис. 3 Дамп трафика во время проведения Kerberoasting без пароля
Для сравнения — вот так выглядит классический AS-REQ с выдачей TGT и последующим TGS-REQ (дамп взят с сайта Wireshark)
Рис. 4 Пример дампа трафика во время нормального соединения с помощью Kerberos
Итак…смотрим дамп, и видим массу AS-REQ, и несколько AS-REP…которые и содержат TGS-билеты! Посмотрев на структуру AS-REQ, и сравнив их с классическими AS-REQ…мы увидели, что запросы имеют отличия. Параметр sname содержит имя сервиса, к которому направляется запрос, что является аномальным. В случае AS-REQ данное поле ВСЕГДА должно запрашивать учетную запись krbtgt, посмотрите на скриншоты ниже.
Рис. 5 Содержание параметра sname при нормальном запросе AS-REQ
Рис. 6 Содержание параметра sname при нормальном запросе AS-REQ
Однако…давайте посмотрим на аналогичные запросы, которые шлет наш инструмент, и посмотрим, что там с параметром sname
Рис. 7 Содержание параметра sname при использовании параметра --no-preauth в Impacket
Рис. 8 Содержание параметра sname при использовании параметра --no-preauth в Impacket
Рис. 9 Содержание параметра sname при использовании параметра --no-preauth в Impacket
…и так по всему списку.
Опция -no-preauth в Impacket позволяет взять список пользователей, и направить измененные AS-REQ запросы, записывая вместо krbtgt в параметр sname список доменных пользователей…а KDC на это отвечает выдачей TGS-билета! А почему KDC так себя ведет? Вопросы к Microsoft… И получается — мы действительно проводим атаку Kerberoasting, получая TGS-билеты для SPN, ассоциирующихся с известными нам именами пользователей.
В заключение можно сказать, что мы и раньше знали, что пользователь в Active Directory без предварительной аутентификации — зло, и вектор для атаки. Так что теперь просто на один вектор стало больше. Но да — атака Kerberoasting без знания пароля — реальность. Нам это надо принять, простить и лишний раз напоминать всем (в первую очередь — себе), что оставлять такие дыры в своей инфраструктуре — верный путь к публикации Вашей конфиденциальной информации в даркнете!
Хочу выразить огромную благодарность своим коллегам — Михаилу Л. И Никите Р., без них данная статья просто не была бы написана!
Всем спасибо, и до скорых встреч!