Прикольный вопрос с собеса или как релеить Kerberos (принцип работы KrbRelay / KrbRelayUP)

Прикольный вопрос с собеса или как релеить Kerberos (принцип работы KrbRelay / KrbRelayUP)

Михаил Жмайло

Прикольный вопрос с собеса или как релеить Kerberos (принцип работы KrbRelay / KrbRelayUP)

не смог найти оригинал фоточки :-(

Конечно, самый простой вариант — пожать плечами и перейти к следующему вопросу, но это не путь самурая. А если начинать читать Google Project Zero, то собеседник точно догадается, что мы списываем :) Поэтому нужен более простой формат и более понятное объяснение.


Итак, чтобы ответить на такой сложный сеньорский вопрос требуется разобраться с тем, как вообще работают Coerce методы, RPC и DCOM?

COM

Начнём наш уникальный экскурс. Сам по себе COM — набор классов. Прям обычных классов с какой-либо функциональностью. Чтобы классами могли пользоваться сторонние программы (например, мы) нужно передавать исходный код этого самого класса (иначе как компилятор скомпилит???).

Конечно, MS такого себе позволить не может, поэтому используются интерфейсы. Интерфейсы позволяют указать определенный набор доступных для вызова методов. Образно, есть метод DWORD PWN(LPSTR TARGET), который отдает значение DWORD, принимает LPSTR. Реализация логики класса где-то на стороне :) Это позволяет разработчикам обращаться к конкретному функционалу COM-класса, не имея возможности просмотра исходного кода этого класса. Ну и сам компилятор понимает что тут как передавать, что тут как принимается.

В контексте DCOM, классы могут быть представлены где-то на стороне, вообще на другой машине. Чтобы подключиться и инстанцировать экземпляр подобного класса используется механизм RPC (то есть, DCOM это как COM, просто с поддержкой работы на удаленных машинах. Поддержка осуществляется через RPC). Каждый экспортируемый (представленный на удаленной машине для инстанцирования) объект уникально идентифицируется с помощью OXID (Object Exporter Identifier), это обычное числовое значение.

Теперь представьте. Вот вы накалякали программку, вот вы указали OXID, вот вы запустили ее. А откуда винда поймет, что это за OXID? К какому серверу обращаться, на каком сервере будет создан объект? Для решения этой проблемы используется механизм, подобный обычному человеческому DNS. Называется он OXID Resolve.

На каждой тачке, имеющей DCOM-функционал, представлены OXID Resolverы. Они принимают в качестве входных данных OXID (Аналог DNS: доменное имя), а возвращают специальную строку, называемую RPC String Binding (строка подключения RPC. Аналог DNS: IP-адрес сайта).

В дальнейшем, эта строка используется виндой для подключения к удаленному серверу и инстанцированию целевого объекта.


Базовая теория про COM/DCOM/RPC закончилась.


Теперь как работают Coerce-методы. Я бы их разделил на два подвида:

- Method Based - основываются на злоупотреблении определенными методами, которые заставляют удаленную тачку сходить куда-то. Пример тому — метод ElfrOpenBELW() из MS-EVEN. Хоть POC (https://github.com/evilashz/CheeseOunce) и не работающий (не от лица нужного пользователя служба работает), но это самый простой пример.

То есть, инстанцируется конкретный DCOM-объект. А затем у этого DCOM-объекта вызывается этот метод. Принцип действия этого метода заключается в том, что винда берет, поднимается и идет по конкретному UNC Path. Что и приводит к NTLM ауф.


- OXID Proxy Based - чуть более сложная логика, но намного универсальнее. Представьте, что в целевом COM-классе нет методов, которые позволили бы заставлять винду куда-то ходить? Казалось бы, дело — дрянь. Но не тут-то было.

Помните про OXID и OXID Resolverы? Так вот, мы можем поднять собственный OXID Resolver и вернуть винде левый RPC String Binding, который, например, указывает на эндпоинт тачку Kali с поднятым ntlmrelayx. Это приведет к тому, что винда в процессе резолва OXIDа получит этот RPC String Binding и обратится к нужной нам машине.


Здесь есть некоторая особенность. Винда соглашается использовать только те резолверы, которые работают на 135/TCP порту. Иные отвергает. Впрочем, для этого можно использовать небольшой хак. Представьте, IP kali 10.10.10.10, ip винды 10.10.10.20. Мы на винде на порту 9999 поднимаем фейковый OXID Resolver, затем винде говорим, мол, обратись на 10.10.10.10:135 для резолва OXID. Винда идет по этому адресу, приходит на Kali, а на Kali на 135 порту мы настраиваем редирект через socat на 10.10.10.20:9999. Что приводит к обращению на наш фейковый OXID Resolver.


В свою очередь, OXID Resolver может отдать RPC String Binding обратно на Kali, винда вновь придет на нее и на этот раз отдаст свои креды :)


С RPC-частью закончили.


Где тут керберос?


При подключении по RPC вполне нормальной ситуацией является отправка учетных данных, ведь DCOM-объекты это самые обычные объекты винды, которые также имеют DACL. И далеко не каждый юзер может инстанцировать конкретный DCOM-объект. В связи с этим, требуется прохождение аутентификации. В случае NetNTLM все понятно, челлендж, респонс и тп. Но как быть с керберосом?


И здесь в игру вступает прикольный хак, который основывается на том, что поднимается фейковый DCOM-сервер, который возвращает SPN, по которому требуется пройти аутентификацию (на который следует запросить TGS-билет). Это приводит к тому, что винда, обращаясь по нашему фейковому RPC String Binding, попадает на Rogue DCOM Server, который просит ее получить тикет на определенную службу. И винда с радостью это делает :)


В свою очередь, имея TGS тикет на руках, можно начинать ходить на какие-нибудь прикольные службы.


А вот графическое объяснение этого механизма

  1. Мы инстанцируем какой-то COM-объект, который работает в хост-процессе, например, от лица системы
  2. Инстанцируем по OXID, поэтому идет резолв OXID
  3. Резолв OXID происходит через наш фейковый OXID Resolver
  4. OXID Resolver отдает RPC String Binding на наш Rogue DCOM Server
  5. Мы отдаем левый SPN и просим пройти аутентификацию
  6. Success :)


Кстати, помните прикольный хак (https://t.me/RedTeambro/273) с TGSThief? Скорее всего он сработает и тут :D

Указываем в качестве SPN krbtgt/cringe.lab


Report Page