Всем привет!

Меня зовут Алексей, я работаю в компании «Визум», и занимаюсь тестированием на проникновение, направления классические – инфраструктура и веб. Данную статью меня сподвиг написать мой друг и коллега – Михаил Л., совместно с которым мы и провели данный небольшой ресерч.

 Все, кто, так или иначе, касался проведения атак на доменную инфраструктуру, построенную на основе Active Directory, почти 100% имели дело с атакой Kerberoasting, которая позволяет получить TGS-билеты для SPN, ассоциируемых с пользовательскими учетными записями, и далее - попробовать восстановить их пароли, при условии, что сами пароли достаточно простые (подробнее про атаку – прочитать можно тут).

Относительно недавно на Hack The Box появилась машина уровня INSANE – Rebound. Не буду расписывать, как ее решать, тем более – уже вышел официальный райтап от Ральфа. Хочу только обратить внимание на один момент из данного райтапа, а именно – проведение атаки Kerberoasing от имени доменного пользователя, к которому НЕТ пароля, но при этом - для пользователя не требуется прохождение Pre-Authentication (очень подробно про керберос можно почитать тут). 

Рис.1 Выдержка из райтапа по прохождению Rebound
Рис.1 Выдержка из райтапа по прохождению Rebound

Ральф просто говорит, что – там аутентификация не требуется, значит можно. Данное высказывание ввело нас с коллегами в ступор. До недавнего времени, мы все искренне считали, что ответом на вопрос «А можно ли проводить атаку Kerberoasting, не имея пароля пользователя?» будет однозначное «нет» (если речь не идет о какой-либо уязвимости, например, CVE-2022-33679). Ведь даже если у используемой нами учетной записи пользователя отсутствует предварительная аутентификация, мы получаем его TGT-билет, и если попытка сбрутить содержащийся в нем сессионный ключ успехом не увенчалась, то сделать запросы TGS-REQ, чтобы запросить множество TGS-билетов у нас не получится. А сессионный ключ как раз и подписывается секретом пользователя! Ну, т.е. без пароля – никак.

Смотрим райтап, и удостоверяемся, что сессионный ключ в получаемом TGT бруту не поддается. Так каким же образом делается Kerberoasting??? А он там делается!

Рис.2 Наше с коллегами недоумение
Рис.2 Наше с коллегами недоумение

Я решил, что мои знания касательно данного вопроса просто несколько устарели, и пошел гуглить и спрашивать коллег на данную тему. Каково же было мое удивление, когда все, что я смог нагуглить по данному вопросу – пара статей без подробностей (раз, два), а все коллеги, которые без преувеличения, гуру в области пентеста инфраструктуры, пожали плечами. При этом, данный метод был опробован как минимум на 3-х инфраструктурах с пользователем без предварительной аутентификации, и везде метод сработал.

Кстати, забегая вперед, стоит отметить, что функционал для данной атаки уже внесен в официальный репозиторий Impacket v12. Строчка для запуска атаки выглядит так:

GetUserSPNs.py -dc-ip <ip> -no-preauth <domain_user_without_preauth> -request -usersfile <userfile.txt> <domain>/

где

<ip> - ip-адрес Контроллера Домена;

<domain_user_without_preauth> - логин пользователя, у которого нет Pre-Authentication;

<userfile.txt> - список логинов доменных пользователей;

<domain> - домен.

 

Ставится инструмент таким образом:

Если не установлен pipx:

pip install pipx

pipx ensurepath

pipx install git+https://github.com/fortra/impacket --force

В один из вечеров, я и Михаил, вооружившись снифером, взяли стэнд, где есть все условия для проведения атаки, и пошли выяснять, что же посылает этот Impacket. Каково же было наше удивление, когда в дампе трафика мы увидели…отсутствие TGS-REQ, как факт.

Рис.3 Дамп трафика во время проведения Kerberoasting без пароля
Рис.3 Дамп трафика во время проведения Kerberoasting без пароля

Для сравнения – вот так выглядит классический AS-REQ с выдачей TGT и последующим TGS-REQ (дамп взят с сайта Wireshark)

Рис.4 Пример дампа трафика во время нормального соединения с помощью Kerberos
Рис.4 Пример дампа трафика во время нормального соединения с помощью Kerberos

Итак…смотрим дамп, и видим массу AS-REQ, и несколько AS-REP…которые и содержат TGS-билеты! Посмотрев на структуру AS-REQ, и сравнив их с классическими AS-REQ …мы увидели, что запросы имеют отличия. Параметр sname содержит имя сервиса, к которому направляется запрос, что является аномальным. В случае AS-REQ данное поле ВСЕГДА должно запрашивать учетную запись krbtgt, посмотрите на скриншоты ниже.

Рис.5 Содержание параметра sname при нормальном запросе AS-REQ
Рис.5 Содержание параметра sname при нормальном запросе AS-REQ
Рис.6 Содержание параметра sname при нормальном запросе AS-REQ
Рис.6 Содержание параметра sname при нормальном запросе AS-REQ

Однако…давайте посмотрим на аналогичные запросы, которые шлет наш инструмент, и посмотрим, что там с параметром sname

Рис.7 Содержание параметра sname при использовании параметра --no-preauth в Impacket
Рис.7 Содержание параметра sname при использовании параметра --no-preauth в Impacket
Рис.8 Содержание параметра sname при использовании параметра --no-preauth в Impacket
Рис.8 Содержание параметра sname при использовании параметра --no-preauth в Impacket
Рис.9 Содержание параметра 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 без знания пароля – реальность. Нам это надо принять, простить и лишний раз напоминать всем(в первую очередь - себе), что оставлять такие дыры в своей инфраструктуре – верный путь к публикации Вашей конфиденциальной информации в даркнете!

Хочу выразить огромную благодарность своим коллегам – Михаилу Л. И Никите Р., без них данная статья просто не была бы написана!

Всем спасибо, и до скорых встреч!

Комментарии (5)


  1. detukov-sergey
    19.04.2024 13:45

    А откуда вы возьмете список пользователей, в таком случае? Перебором на каком-нибудь exhange? Или просто подставляя рандомный список?


    1. Velvealex Автор
      19.04.2024 13:45

      Ну, способов хватает, начиная от банальных мисконфигов (тот же exchange, rpc), и заканчивая осинтом.


      1. detukov-sergey
        19.04.2024 13:45

        Ну просто вероятность выловить таким образом учетку, от имени которой запустили сервис мелковата... Обычно это всё-таки сервисные учетные записи, которые вряд ли в каком-то осинте всплывут... И за время поиска, скорее всего, найдется учетка с минимальными правами, чтобы выполнить по классическому пути..


  1. MichelleVermishelle
    19.04.2024 13:45

    Прекрасная статья! Спасибо, что вы разобрались в этой интересной теме. Я бы еще отметил, что возможно извлекать хеши из дампа сетевого трафика (раз статья про Kerberoasting без аутентификации в домене) и про релей на этап TGS-REQ (тулзы RITM от Tw1sm и RoastInTheMiddle от 0xe7)


  1. VeeZy_VeeZy
    19.04.2024 13:45

    Отличная статья!
    В дополнение скажу что, если не изменяет память, этой атаке уже больше 1,5 лет. О чем упоминала в отличном видео на ютубе Академия Яндекса(Windows & AD). Также, есть крутая статья от Charlie Clark(New Attack Paths? AS Requested Service Tickets),где он описывает что манипуляция с полем sname в пакете TGS-REQ невозможна из-за проверки его контрольной суммы. А в пакете AS-REQ все req-body не защищено, в том числе и поле sname