Ошибка в Windows Registry: как получить права администратора домена

Ошибка в Windows Registry: как получить права администратора домена

Пошаговый разбор процесса исследования и эксплуатации уязвимости в клиенте WinReg. Раскрываем механизм работы RPC, методы обнаружения уязвимых систем и способы защиты.

image

Исследователь Akamai Стив Купчик обнаружил новую уязвимость повышения привилегий (Elevation of Privilege, EoP) в клиенте Remote Registry от Microsoft CVE-2024-43532 (оценка CVSS: 8.8). Ошибка эксплуатирует механизм резервного режима в клиенте WinReg, который небезопасно использует устаревшие транспортные протоколы, если SMB недоступен.

Эксплуатируя уязвимость, злоумышленник может передать учетные данные NTLM клиента службе Active Directory Certificate Services (ADCS) и запросить пользовательский сертификат, который затем может использоваться для дальнейшей аутентификации в домене. Akamai представила доказательство концепции в репозитории на GitHub.

Уязвимость была раскрыта Microsoft Security Resource Center в феврале 2024 года и была исправлена в рамках октябрьского Patch Tuesday 2024. Недостаток затрагивает все неисправленные версии Windows.

Введение

MS-RPC — это реализация Microsoft протокола удаленного вызова процедур (RPC). RPC — это механизм межпроцессного взаимодействия, позволяющий процессам открывать функциональные возможности, к которым могут обращаться другие процессы. RPC является основным компонентом Windows, и многие службы зависят от него, включая диспетчер служб и функции выключения в wininit.

Akamai провела много исследований MS-RPC — как наступательных, в рамках которых обнаружили крупный вектор атак в форме атак кэширования, так и защитных, в которых анализировали механизмы безопасности.

В данном случае Akamai показывает RPC с другой стороны. Любой протокол, который обеспечивает взаимодействие и выполнение операций между разными компьютерами, должен поддерживать аутентификацию пользователей, и RPC действительно поддерживает передачу учетных данных и аутентификацию в рамках своего процесса привязки. Однако наличие аутентификации также влечет за собой возможность перехвата учетных данных, и специалисты начали искать такие уязвимости.

RPC, аутентификация и промежуточные моменты

Сессии RPC обрабатываются через привязки. Клиентское приложение подключается к серверному приложению, связывается с нужным интерфейсом RPC и запрашивает выполнение конкретной функции.

Базовый процесс вызова RPC

Запрос привязки и ответ могут передавать несколько полей данных, необходимых для соединения. Обычно, если аутентификация не требуется, привязка RPC просто используется для выбора синтаксиса передачи, который будет использоваться для инкапсуляции параметров функций в последующих вызовах.

Чего не хватает во взаимодействии? Аутентификации! Как сервер может узнать личность клиента и проверить его право на выполнение запрошенного действия? Ответ таков: он не сможет этого сделать, если клиент не добавит контекст безопасности (аутентификацию) к запросу привязки. По умолчанию все соединения RPC не аутентифицированы, и не все серверы RPC требуют аутентификации.

Чтобы аутентифицироваться (или, как это называется в RPC, «добавить контекст безопасности»), клиент должен добавить дополнительные данные к запросу привязки, согласовать протокол аутентификации (например, NTLM или Kerberos) и вставить дополнительные метаданные, необходимые протоколом аутентификации (например, имя пользователя, домен и т.д.).

Метаданные аутентификации, добавленные в запрос привязки RPC

Поиск целей исследования

Первый шаг — понять, как должна выглядеть аутентификация с точки зрения API. Это достигается вызовом одной из функций RpcBindingSetAuthInfo* от клиента после создания дескриптора привязки. В документации по этим функциям можно заметить поле AuthenticationLevel, которое указывает уровень безопасности аутентификации.

Безопасность с аутентификацией предполагает не только проверку существования и авторизации пользователя, но также защиту от подделки. Уровни аутентификации варьируются от простой проверки успешности соединения (RPC_C_AUTHN_LEVEL_CONNECT) до полной шифровки и подписи всего трафика для предотвращения подделок (RPC_C_AUTHN_LEVEL_PKT_PRIVACY). Конечно, злоумышленники интересуются первым уровнем, так как он не защищает трафик от подделок.

Однако всё не так просто. Атаки с ретрансляцией RPC уже давно известны, и многие клиенты и серверы RPC в Windows были обновлены до использования высокого уровня аутентификации, что препятствует успешности ретрансляции. Поэтому необходимо искать более старый код, который по каким-то причинам остаётся небезопасным.

Запуск скрипта IDAPython в папке system32 сервера Windows для поиска случаев небезопасной аутентификации RPC (скрипт можно найти в репозитории Akamai)

WinReg — перспективный кандидат

Как и предполагалось, список потенциальных целей включал менее 5% от общего числа серверов и клиентов RPC; большинство из них больше не используют небезопасную аутентификацию. Однако в библиотеке advapi32.dll мы нашли интересного кандидата.

advapi32.dll — это основной компонент Windows API, который реализует множество функций, таких как ведение журналов событий, шифрование, WMI и другие.

Мы обнаружили, что функция BaseBindToMachine иногда вызывает RpcBindingSetAuthInfoA с уровнем аутентификации RPC_C_AUTHN_LEVEL_CONNECT, что нам и нужно. BaseBindToMachine вызывается функцией RegConnectRegistryExW, если в качестве имени машины передается путь UNC.

Документация Rust для RegConnectRegistryExW, так как она не документирована в MSDN

Просмотрев BaseBindToMachine, можно заметить, что она использует как RpcBindingSetAuthInfoW (безопасный уровень RPC_C_AUTHN_LEVEL_PKT_PRIVACY), так и RpcBindingSetAuthInfoA (с уровнем RPC_C_AUTHN_LEVEL_CONNECT, который позволяет ретрансляцию, так как не проверяет подлинность и целостность соединения).

Два вызова для установки информации аутентификации

Нам просто нужно понять, почему имеются два конфликтующих вызова. При изучении логики функции мы обнаружили, что в ней используется переменная-указатель на функцию и массив функций. Эти функции задают информацию привязки RPC для использования конкретного транспорта RPC; по умолчанию используется SMB и именованные каналы, но, если это не удаётся, происходит попытка привязки через SPX, TCP/IP и другие.

Почему используются два конфликтующих вызова? При изучении логики функции было обнаружено, что в ней имеется переменная-указатель на функцию и массив функций.

Указатели функций и массив функций внутри BaseBindToMachine

Откат на TCP/IP — удачная находка

Откат на TCP/IP выглядит многообещающе, так как это позволяет использовать небезопасный метод аутентификации для ретрансляции трафика через атаку посредника, не привлекая внимания клиента. Хотя подобное возможно и с другими транспортными протоколами, они достаточно устарели, и их использование в современной сети может вызвать подозрения. Протокол TCP/IP гораздо чаще применяется в качестве транспорта RPC, и его можно безопасно использовать даже в условиях красной команды.

Важно знать, что как BaseBindToMachine, так и RegConnectRegistryExW принимают в качестве аргумента флаг, предотвращающий резервное переключение, но базовая функция RegConnectRegistryW вызывает RegConnectRegistryExW без этого флага.

Процесс ретрансляции

Ретрансляция NTLM является распространённой техникой, и основная логика уже реализована в ntlmrelayx от Impacket, который мы будем использовать в основном.

Создание сервера ретрансляции RPC

ntlmrelayx не включает сервер RPC для TCP/IP, а только сервер SMB. Поэтому нам потребуется создать собственный сервер ретрансляции, который будет отклонять подключение через именованный канал winreg, чтобы вызвать резервное подключение к TCP/IP.

Для этого необходимо реализовать три ключевых момента:

  1. Сопоставитель конечных точек RPC
  2. Запрос привязки RPC с NTLM
  3. NTLM-вызов

Сопоставитель конечных точек RPC отвечает за преобразование UUID интерфейсов RPC в соответствующие конечные точки, которые в случае TCP/IP-транспорта представляют собой номера портов. В отличие от SMB, где конечные точки представляют собой именованные каналы с предсказуемыми именами, конечные точки TCP/IP используют временные порты, и поэтому требуется дополнительный слой преобразования.

Ключевой момент связан с NTLM. В процессе привязки RPC с NTLM сначала отправляется сообщение о начале NTLM-переговоров, затем сервер возвращает NTLM-вызов в ответ на запрос привязки. Наконец, клиент отправляет ещё одно сообщение, называемое AUTH3, с ответом на вызов.

Аутентификация NTLM через привязку RPC

Чтобы выполнить ретрансляцию, достаточно перехватить соответствующие сообщения на нашем RPC-сервере. Как только мы видим сообщение о согласовании NTLM в сообщении привязки, мы открываем собственное подключение к серверу аутентификации и также запрашиваем аутентификацию через NTLM. Затем мы просто захватываем вызов, отправленный сервером, передаём его жертве и обратно на сервер, чтобы получить нашу собственную аутентифицированную сессию.

Первой мыслью было бы передать данные другому RPC-серверу на другой машине, например, диспетчеру служб или планировщику задач, чтобы выполнить удалённый код. Однако обе эти службы требуют уровня аутентификации RPC_C_AUTHN_LEVEL_PKT_PRIVACY, который шифрует весь трафик с использованием NTLMv2-хеша клиента, к которому у нас нет доступа даже с ретрансляцией.

Ретрансляция RPC к ADCS

Ретрансляция NTLM на ADCS реализована в Impacket по умолчанию, поэтому нам остаётся лишь передать нашу аутентифицированную сессию модулю HTTPAttack и позволить процессу автоматизированно завершить атаку.

HTTP-сервер ADCS не требует особой безопасности и уязвим к ретрансляционным атакам. Используя это, после аутентификации мы можем запросить пользовательский сертификат, который можно затем использовать для аутентификации без повторной ретрансляции.

Запрос и получение сертификата от ADCS после атаки NTLM relay attack

С помощью этого сертификата мы аутентифицировались на службе LDAP на контроллере домена и создали постоянную учётную запись администратора домена в скомпрометированном домене.

Создание нового администратора домена с использованием оболочки LDAP

Функция в advapi сама по себе не представляет интереса, если только её не использует что-то ещё. Быстрый поиск по импортам RegConnectRegistryExW или RegConnectRegistryExA ничего не показал на актуальном контроллере домена, однако поиск RegConnectRegistryW выявил несколько возможных кандидатов, таких как certutil и certsrv (AD CS), EFS, DFS и другие.

Обнаружение

Служба Remote Registry по умолчанию не включена на всех устройствах Windows. Статус её активности можно определить с помощью следующего запроса osquery:

SELECT display_name, status, start_type, pid FROM services WHERE name='RemoteRegistry'

Однако это не защищает от CVE-2024-43532, так как это проблема клиента. Результаты запроса помогут выявить реальные случаи использования Remote Registry в организации, которые могут понадобиться учесть при усилении защиты.

Для обнаружения клиентов, использующих уязвимые функции WinAPI, можно применить следующее правило YARA:

 import "pe"

rule winreg_client_import {
    meta:
        description =  "Detect binaries that rely on RegConnectRegistry"
        author = "Стив Купчик из Akamai Technologies"

    condition:
        pe.is_pe and (
            pe.imports(pe.IMPORT_ANY, "advapi32.dll", "RegConnectRegistryA")
            or pe.imports(pe.IMPORT_ANY, "advapi32.dll", "RegConnectRegistryW")
            or pe.imports(pe.IMPORT_ANY, "advapi32.dll", "RegConnectRegistryExA")
            or pe.imports(pe.IMPORT_ANY, "advapi32.dll", "RegConnectRegistryExW")
        )
}

Пользователи Akamai Guardicore Segmentation могут также создавать правила политики для трафика, направленного к службе RemoteRegistry.

Правило политики сегментации для оповещения о трафике в службу RemoteRegistry

Также можно использовать Event Tracing for Windows (ETW) для мониторинга трафика RPC на стороне клиента и сервера.

Заключение

Хотя протокол RPC и MS-RPC разрабатывались с учетом безопасности, анализ различных реализаций интерфейсов RPC демонстрирует эволюцию принципов безопасности с течением времени. Несмотря на то, что большинство серверов и клиентов RPC сейчас защищены, время от времени всё же можно обнаружить реликты небезопасной реализации в той или иной степени.

В данном случае нам удалось выполнить атаку ретрансляции NTLM, что является классом атак, которые должны были бы остаться в прошлом. Это показывает, что защита сети должна быть как можно более всесторонней, так как невозможно предсказать, какой древний интерфейс ещё может быть открыт или использоваться.

Реальные атаки. Эффективные решения. Практический опыт.

Standoff Defend* — это онлайн-полигон, где ты сможешь испытать себя. Попробуй себя в расследовании инцидентов и поборись за победу в конкурсе

*Защищать. Реклама. АО «Позитив Текнолоджиз», ИНН 7718668887