Всем, привет! Меня зовут Диана, я аналитик-исследователь киберугроз в компании R-Vision. Сегодня я хочу рассказать вам о весьма простой, но в то же время достаточной популярной атаке DCSync (T1003.006). Она не является новой, но по-прежнему активно используется злоумышленниками. Все потому, что выполнение DCSync позволяет провести ряд последующих атак: например, запросив хеш пароля сервисной учетной записи krbtgt можно провести атаку Golden Ticket, которую, кстати, мы разбирали в блоге ранее.

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

Для того, чтобы разобраться какие маркеры мы можем использовать в качестве основы для построения возможной логики детектирования, нам также потребуется: рассмотреть пример легитимной активности в домене и изучить какие события в журналах Windows мы можем зафиксировать в результате запуска утилит.
Предлагаю начинать и сперва ознакомимся с самим механизмом работы DCSync.

Что такое DCSync и почему эта атака возможна

DCSync атака, позволяющая злоумышленнику выдавать себя за контроллер домена (DC, domain controller) с целью получения учетных данных пользователей для последующего горизонтального перемещения в сети и/или доступа к конфиденциальной информации.
В основе атаки лежит механизм, предусмотренный для выполнения репликации данных между контроллерами домена (DC).

Механизм репликации данных архитектурно заложен в операционной системе Windows. Службы Active Directory и протокол MS-DRSR отвечают за взаимодействие между контроллерами домена и осуществляют репликацию. Сама компания Microsoft рекомендует изначально устанавливать как минимум два и более контроллера для одного домена в корпоративной сети, чтобы обеспечить избыточность и, как следствие, повысить отказоустойчивость доменной инфраструктуры. В процессе репликации данных между контроллерами помимо обычных атрибутов об объекте (имя, отчество, списка групп и так далее) передается и чувствительная информация, например, хеши паролей пользователей, поскольку каждый контроллер выступает как точка для аутентификации и авторизации в домене.

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

Изучив, что лежит в основе DCSync, давайте посмотрим какие права доступа нужны для использования механизма репликации.

Права доступа для выполнения репликации

Для выполнения репликации данных между несколькими контроллерами домена учетная запись должна обладать определенными расширенными правами доступа (extended rights). Многие источники в сети, описывающие атаку DCSync, выделяют следующие права:

Наименование

CN

Rights-GUID

Replicating Directory Changes

DRS-Replication-Get-Changes

1131f6aa-9c07–11d1-f79f-00c04fc2dcd2

Replicating Directory Changes All

DRS-Replication-Get-Changes-All

1131f6ad-9c07–11d1-f79f-00c04fc2dcd2

Replicating Directory Changes In Filtered Set

DRS-Replication-Get-Changes-In-Filtered-Set

89e95b76-444d-4c62-991a-0facbeda640c

При этом на практике права доступа Replicating Directory Changes и Replicating Directory Changes All являются обязательными для выполнения этой атаки, тогда как отсутствие Replicating Directory Changes In Filtered Set не оказывает какого-либо влияние на ее проведение.
Как это проверить, а также как получить необходимые права доступа можно посмотреть под спойлерами.

Проверка минимальных прав доступа для выполнения атаки

Очевидно, что при отсутствии каких-либо прав у учетной записи, мы вряд ли что-то сможем получить, кроме ошибки. Но на всякий случай давайте рассмотрим такой вариант и проверим, это утверждение, воспользовавшись довольно популярным фреймворком от Gentle Kiwi, mimikatz.
Для этого выполняем заветную команду. И да, как и предполагалось, мы получаем ошибку RPC 8439 (0x000020F7).

Рисунок 1 - Ошибка 8439 при отсутствии необходимых прав доступа
Рисунок 1 - Ошибка 8439 при отсутствии необходимых прав доступа

Обратившись к документации Microsoft, мы увидим следующую расшифровку ERROR_DS_DRA_BAD_DN, а также некоторые пояснения "The DN specified for this replication operation is invalid", в которых не упоминается об отсутствии прав у пользователя.

Аналогичная ситуация возникает, если:

  • Назначена только Replicating Directory Changes All

  • Назначена только Replicating Directory Changes In Filtered Set

  • Есть Replicating Directory Changes All и Replicating Directory Changes In Filtered Set

В свою очередь, ошибка RPC 8453 (0x00002105) регистрируется в следующих случаях:

Рисунок 2 - Ошибка 8453 при отсутствии необходимых прав доступа
Рисунок 2 - Ошибка 8453 при отсутствии необходимых прав доступа
  • Если назначена только Replicating Directory Changes

  • А также, если назначены Replicating Directory Changes и Replicating Directory Changes In Filtered Set

Снова обратившись к документации Microsoft, заметим, что ERROR_DS_DRA_ACCESS_DENIED может расшифровываться как AD DS Connector Account is missing the following extended permissions on AD:

Replicating Directory Changes
Replicating Directory Changes All

В табличном представлении без двух крайних вариантов (когда все права доступа либо отсутствуют, либо они выданы) это выглядит следующим образом:

#

Replicating Directory Changes

Replicating Directory Changes All

Replicating Directory Changes In Filtered Set

Replicating Directory Changes

RPC Error 8453

Успешная репликация

RPC Error 8453

Replicating Directory Changes All

---

RPC Error 8439

RPC Error 8439

Replicating Directory Changes In Filtered Set

---

---

RPC Error 8439

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

Выдача прав доступа

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

  • Domain Admins

  • Enterprise Admins

  • Domain Controllers

Предоставить необходимые права доступа можно доступа напрямую, открыв свойства (Properties) у нашего домена и кликнув во вкладку Безопасность (Security). Таким образом мы можем выдать права как пользователю, так и нужной нам группе.

Рисунок 3 - Предоставление прав на репликацию через оснастку AD Users & Computers
Рисунок 3 - Предоставление прав на репликацию через оснастку AD Users & Computers

Для того чтобы отследить у каких пользователей и/или групп уже имеются требуемые права доступа воспользуемся командлетом Get-Acl :

(Get-Acl "ad:\dc=<DOMAIN>").Access | ? {(.ObjectType -eq "1131f6aa-9c07–11d1-f79f-00c04fc2dcd2")}
Рисунок 4 - Получение списка групп и учетных записей, обладающих правами на репликацию
Рисунок 4 - Получение списка групп и учетных записей, обладающих правами на репликацию

Еще одним вариантом предоставления расширенных прав является набор функций PowerView во фреймворке PowerSploit. Данная команда добавляет учетной записи сразу все необходимые права доступа на выполнение репликации.

Add-ObjectACL -PrincipalSamAccountName <user> -Rights DCSync

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

Get-ObjectAcl "Domain Controllers" | ?{(_.ObjectType -eq "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2")}
Get-ObjectAcl -DistinguishedName "dc=<domain>" | ?{(_.ObjectType -eq "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2")}
Рисунок 5 - Получение прав доступа с помощью PowerSploit
Рисунок 5 - Получение прав доступа с помощью PowerSploit

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

Легитимная репликация данных

Как уже было сказано ранее, Microsoft реализовала удаленный протокол службы репликации каталогов (MS-DRSR) — RPC протокол, состоящий из двух интерфейсов RPC с именами drsuapi и dsaop. Взглянув на трафик между двумя КД, мы видим вызов двух RPC методов (функций) из интерфейса drsuapi - DRSReplicaSync и DRSGetNCChanges.

Рисунок 6 - Трафик при легитимной репликации
Рисунок 6 - Трафик при легитимной репликации

При вызванной вручную репликации с помощью команды repadmin /syncall dc01 dc=<domain> добавляется вызов DRSBind и DRSUnbind. Более детальная информация о вызовах указана в таблице под спойлером.

Рисунок 7 - Трафик при легитимной репликации, запущенной вручную
Рисунок 7 - Трафик при легитимной репликации, запущенной вручную
Описание функций DRSUAPI

RPC-интерфейс DRSUAPI

OpNum / ProcNum

Описание

DRSBind

0

Запускает сеанс удаленного вызова процедур из интерфейса DRSUAPI с определенным контроллером домена.

DRSUnbind

1

Уничтожает сеанс удаленного вызова процедур из интерфейса DRSUAPI c определенным КД.

DRSReplicaSync

2

Запускает репликацию с другого КД. Если КД получает запрос DRSReplicaSync, то он начинает репликацию с КД, указанными в структуре RepsFrom, где он ведет себя уже как клиент и отправляет запросы DRSGetNCChanges. Таким образом, функция реализует механизм распространения изменений.

DRSGetNCChanges

3

Непосредственно проводит саму репликацию. Клиентский КД отправляет серверу запрос, когда хочет получить обновления объектов AD. Ответ содержит набор обновлений, которые клиент применит у себя. Если набор обновлений слишком большой, то делается несколько таких запросов.

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

Разобравшись, что происходит в трафике при легитимном взаимодействии между КД, рассмотрим примеры утилит, которые наиболее часто используются для выполнения атаки, а также какие между ними есть отличия.

В качестве утилит будем использовать популярный mimikatz, фигурировавший в статье ранее, а также утилиты Impacket SecretDump, DSInternal. Для каждой утилиты мы проанализируем сетевой трафик, код и события, чтобы понять как была реализована атака.

Mimikatz

Первой рассмотренной нами утилитой является mimikatz. Пример выполнения атаки с ее помощью выглядит следующим образом:

# Отправляет запрос контроллеру домена на синхронизацию всей базы объектов AD.
lsadump::dcsync /all

# Отправляет запрос контроллеру домена на синхронизацию данных по одной конкретной учетной записи.
lsadump::dcsync /user:<user>

А теперь давайте проанализируем, что же мы получим в результате выполнения данных команд.

Анализ вывода mimikatz

На рисунке 8 представлен пример вывода команды утилиты mimikatz. Разберем поподробней какой полезной информацией он обладает:

  • Свойствами учетной записи (UserAccountControl);

  • SID учетной записи;

  • Историей NTLM-хешей пароля учетной записи, используемый, например, в атаке Pass-The-Hash;

  • Историей LM-хешей пароля учетной записи;

  • Историей хешей пароля для kerberos аутентификации, которые могут пригодится для последующей атаки Golden Ticket;

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

Рисунок 8 - Вывод mimikatz после выполнения DCSync
Рисунок 8 - Вывод mimikatz после выполнения DCSync

Также отмечу, что у пользователя в AD есть такой атрибут как Store password using reversible encryption. По умолчанию флаг у данного атрибута находится в выключенном состоянии, но для некоторых приложений, может потребоваться его активация. Если провести атаку на пользователя с таким атрибутом, то мы сможем получить пароль в открытом виде.

Условия для получения пароля в открытом виде
Рисунок 9 - Выставление флага ReversibleEncryptionEnabled через Active Directory Users and Computers
Рисунок 9 - Выставление флага ReversibleEncryptionEnabled через Active Directory Users and Computers

На рисунке 10 видно, что утилита mimikatz добавляет в самом конце вывода еще один разделPrimary:CLEARTEXT, содержащий пароль в открытом виде.

Рисунок 10 - Пароль в открытом виде в результате DCSync с помощью mimikatz
Рисунок 10 - Пароль в открытом виде в результате DCSync с помощью mimikatz

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

Set-ADAccountControl -Identity <USERNAME> -AllowReversiblePasswordEncryption $true

В свою очередь, получить список пользователей в домене, у которых выставлен данный атрибут возможно с помощью следующей команды:

Get-ADUser -Filter 'userAccountControl -band 128' -Properties userAccountControl

А сейчас предлагаю взглянуть, что же происходило в локальной сети во время выполнения атаки.

Разбор сетевого трафика mimikatz

На рисунке 11 показан трафик, где помимо уже знакомого нам метода DRSGetNCChanges, мы увидим DRSGetDomainControllerInfo и DRSCrackNames, а также заметим и отсутствие метода DRSReplicaSync. При получении всей базы AD может быть несколько подряд идущих DRSGetNCChanges, но в остальном вызов функций не изменяется.

Рисунок 11 - Трафик при DCSync с помощью mimikatz
Рисунок 11 - Трафик при DCSync с помощью mimikatz

Более детальное описание новых методов указано в таблице ниже.

Детальное описание функций DRSUAPI

RPC-интерфейс DRSUAPI

OpNum

Описание

DRSCrackNames

12

Находит объект в каталоге и возвращает его вызывающей стороне в запрошенном формате. Например, возвращает GUID пользователя, пароль которого нужно запросить с КД. Этот GUID будет передан в функцию DsGetNCChanges.

DRSDomainControllerInfo

16

Получает информацию о КД (DNS, GUID, NetBIOSName и т.п.) в заданном домене.

Далее посмотрим на особенности реализации утилиты mimikatz, разобрав кодовую базу. Возможно в ней мы как раз и найдем ответ на вопрос: почему происходит вызов дополнительных функций?

Разбор кодовой базы mimikatz

Давайте взглянем как реализована атака DCSync в mimikatz. Вся последовательность действий заложена в функции kuhl_m_lsadump_dcsync, а выполнение запросов DRSR находится в файле kull_m_rpc_drsr.c. Примечательно то, что функция DRSBind вызывается два раза. Первый раз - при вызове функции kull_m_rpc_drsr_getDomainAndUserInfos для получения идентификаторов GUID пользователя и домена. При этом закрытие этого дескриптора не происходит, видимо автор утилиты забыл про очистку. Второй раз вызов происходит непосредственно в kuhl_m_lsadump_dcsync. В данном случае закрытие именно этого дескриптора происходит в конце. Если в последующих версиях утилиты не будет исправлен вызов двух DRSBind, то данный факт можно использовать в качестве отличительной особенности mimikatz от других утилит, рассмотренных далее.

Набор возвращаемых атрибутов, существующих КД в заданном домене с помощью функции DRSDomainControllerInfo, зависит от параметра InfoLevel. В данной реализации InfoLevel в запросе равен 2, что в целом довольно логично, так как нам не нужна информация о RODC, полученная при указании уровня 3, а уровень 1 ограничен в качестве возвращаемой информации.

В функции DRSCrackNames за формат входных данных (User или SID) отвечает параметр formatOffered, который может принимать следующие значения:

DS_NT4_ACCOUNT_NAME
DS_FQDN_1779_NAME
DS_USER_PRINCIPAL_NAME
DS_NT4_ACCOUNT_NAME_SANS_DOMAIN
DS_SID_OR_SID_HISTORY_NAME
Рисунок 12 - Вывод mimikatz после выполнения DCSync, где в качестве входных данных указан GUID krbtgt
Рисунок 12 - Вывод mimikatz после выполнения DCSync, где в качестве входных данных указан GUID krbtgt

В качестве получаемого на выходе формата (параметр formatDesired) указан DS_UNIQUE_ID_NAME=6, что означает получение строки GUID в фигурных скобках. Если изначально данные были указаны в GUID формате, то вызов метода DRSCrackNames не происходит. Все рассмотренные входные параметры подпадают под случай, рассмотренный выше, кроме GUID, так что давайте проверим на практике, как меняется трафик в данном случае.

Как мы видим из рисунка 13, вызов метода DRSCrackNames действительно не происходит.

Рисунок 13 - Трафик при DCSync с помощью mimikatz, где в качестве входных данных указан GUID krbtgt
Рисунок 13 - Трафик при DCSync с помощью mimikatz, где в качестве входных данных указан GUID krbtgt

Для большей наглядности ниже представлено сравнение вызова методов в виде таблицы.

Легитимное поведение

Сравнение

Атака DCSync (на входе задаем GUID)

Атака DCSync (остальные случаи)

-

<>

DRSGetDomainControllerInfo

DRSGetDomainControllerInfo

DRSReplicaSync

<>

-

DRSCrackNames

DRSGetNCChanges

=

DRSGetNCChanges

DRSGetNCChanges

Как ранее говорилось, DRSGetNCChanges вызывается всегда, как при легитимной синхронизации, так и при проведении атаки, так как именно она отвечает за репликацию данных. Вызов же остальных методов отличается.

Перейдем к следующей утилите.

Impacket-secretsdump

Второй рассмотренной нами утилитой является secretsdump.py от Impacket.Примеры выполнения атаки с ее помощью представлены ниже:

# Выгружаем информацию по всем учетным записям в AD
python3 secretsdump.py <domain>/<user>:<password>@<ip dc> -just-dc

# Выгружаем информацию только по одной конкретной учетной записи
python3 secretsdump.py <domain>/<user>:<password>@<ip dc> -just-dc-user <USERNAME>

Разберем детальней, что мы получим в результате выполнения данных команд.

Анализ вывода Impacket-secretsdump.py

На рисунке ниже представлен пример вывода утилиты. Проанализируем, какая полезная информация в нем содержится.

Рисунок 14 - Вывод Impacket-secretsdump после выполнения DCSync и пароль в открытом виде
Рисунок 14 - Вывод Impacket-secretsdump после выполнения DCSync и пароль в открытом виде

В отличии от mimikatz информации Impacket-secretsdump предоставляет заметно меньше, но есть данные, потенциально нам интересные, например:

  • RID (Relative Identifier) учетной записи, грубо говоря это порядковый номер учетной записи;

  • NTLM-хеш пароля;

  • Хеш пароля для kerberos аутентификации (разные алгоритмы шифрования);

  • Если включен флаг обратимого шифрования, то в конце добавляется строка с паролем в открытом виде.

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

Разбор сетевого трафика Impacket-secretsdump.py

В данном случае для выгрузки данных используются те же функции, как и в предыдущем примере: DRSGetDomainControllerInfo, DRSCrackNames и DRSGetNCChanges. Также в противовес легитимной активности здесь мы можем наблюдать отсутствие функции DRSReplicaSync. В отличие от mimikatz в трафике на рисунке 15 отображается большое количество запросов DRSCrackNames и DRSGetNCChanges при репликации всех учетных записей AD.

Рисунок 15 - Трафик при DCSync с помощью Impacket-secretsdump (выставлен флаг -just-dc)
Рисунок 15 - Трафик при DCSync с помощью Impacket-secretsdump (выставлен флаг -just-dc)



Если проанализировать исходный код, то становится понятным, что вызов этих функций происходит для каждой выгружаемой учетной записи отдельно. Все запросы DRSCrackNames, кроме первого, отправляются параллельно DRSGetNCChanges.

Рисунок 16 - Трафик при DCSync с помощью Impacket-secretsdump (выставлен флаг -just-dc-user)
Рисунок 16 - Трафик при DCSync с помощью Impacket-secretsdump (выставлен флаг -just-dc-user)

При получении информации по одной конкретной учетной записи вызов этих функций происходит единожды (рисунок 16), что логично. Примечательно, что в обоих ситуациях отсутствует вызов функции DRSUnbind.

Для наглядности ниже представлено сравнение вызываемых функций в виде таблицы. Здесь также при атаке не происходит вызова DRSReplicaSync и метод DRSGetNCChanges является обязательным.

Легитимное поведение

Сравнение

Атака DCSync

-

<>

DRSGetDomainControllerInfo

DRSReplicaSync

<>

DRSCrackNames

DRSGetNCChanges

=

DRSGetNCChanges

Дальше постараемся узнать существуют ли какие-либо принципиальные отличия в реализации утилит mimikatz и Impacket-secretsdump, разобрав особенности реализации последней.

Разбор кодовой базы Impacket-secretsdump.py

Как и в mimikatz, при выполнении атаки DCSync в Impacket-secretsdump набор возвращаемых атрибутов о КД с помощью функции DRSDomainControllerInfo соответствует InfoLevel равному 2.

Функция DRSCrackNames в качестве входных данных параметра formatOffered может принимать DS_NT4_ACCOUNT_NAME, DS_NT4_ACCOUNT_NAME_SANS_DOMAIN и DS_SID_OR_SID_HISTORY_NAME. На выходе данные преобразуются в формат DS_UNIQUE_ID_NAME. Примечательно, что в Impacket-secretsdump нет какого-либо параметра, который позволял бы на входе задавать требуемую учетную запись в формате SID, поэтому мы смеем предположить, что формат DS_SID_OR_SID_HISTORY_NAME используется при репликации всех объектов из AD. Отмечу, что данная утилита с открытым исходным кодом, поэтому любой желающий может доработать этот момент.

Рассмотрим последнюю утилиту DSInternals.

DSInternals

Посмотрим на пример выполнения атаки с помощью DSInternals.

#Выгружаем информацию по всем учетным записям,
Get-ADReplAccount -All -Server <dc>

#Выгружаем данные по одной конкретной учетной записи
Get-ADReplAccount -SamAccountName <user> -Server <dc>

И разберем детальнее, что произойдет в результате выполнения данных команд.

Анализ вывода DSInternals

Рисунок 17 - Вывод DSInternals после выполнения DCSync и пароль в открытом виде
Рисунок 17 - Вывод DSInternals после выполнения DCSync и пароль в открытом виде

На рисунке 17 представлен пример вывода утилиты DSInternals. Он гораздо больше, чем строки, отображенные на картинке, но все получаемые параметры, представляющие интерес.

Вывод DSInternals очень похож на вывод mimikatz. Из интересного, что мы получаем после вывода:

  • Наименование учетной записи в различных форматах (DistinguishedName, SID, GUID, Sam, PrincipalName);

  • Свойства учетной записи (UserAccountControl);

  • Историю NTLM-хешей пароля учетной записи;

  • Историю LM-хешей пароля учетной записи;

  • Историю хешей пароля для kerberos аутентификации;

  • Если включен флаг обратимого шифрования, то добавляется строка с паролем в открытом виде;

  • Предварительно вычисленные хэш-формы, используемые в протоколах дайджест-аутентификации.

Далее изучим, что происходит в сети при выполнении атаки.

Разбор сетевого трафика DSInternals

Рисунок 18 - Трафик при DCSync с помощью DSInternals
Рисунок 18 - Трафик при DCSync с помощью DSInternals

При анализе трафика, мы видим, что в данной утилите в самом конце для репликации используется DRSGetNCChanges (рисунок 18). Также дополнительно происходит несколько раз вызов DRSCrackNames и аналогично предыдущим утилитам отсутствует DRSReplicaSync.
Для наглядности ниже представлено сравнение в виде таблицы.

Легитимное поведение

Сравнение

Атака DCSync

DRSReplicaSync

<>

DRSCrackNames

DRSGetNCChanges

=

DRSGetNCChanges

Теперь посмотрим есть ли какие-то отличия в реализации DSInternals по сравнению с другими рассмотренными нами утилитами.

Разбор кодовой базы DSInternals

Изучив исходный код данной утилиты, становится понятным, что реализация запросов DRSUAPI находится в файле DrsConnection.cpp. Атаку можно запустить как для всех учетных записей в домене сразу, так и для какой-то одной конкретной учетной записи. От этого зависит какие значения, может принимать параметр formatOffered в функции DRSCrackNames.
При запуске для всех учетных записей в домене параметр принимает значение DS_FQDN_1779_NAME, а на выходе параметр formatDesired равен DS_NT4_ACCOUNT_NAME. При запуске атаки для одной учетной записи formatOffered может быть равен DS_USER_PRINCIPAL_NAME, DS_NT4_ACCOUNT_NAME, DS_SID_OR_SID_HISTORY_NAME, в зависимости от формата входных данных и все они на выходе преобразовываются в DS_UNIQUE_ID_NAME.

Рисунок 19 - Вывод DSInternals после выполнения DCSync, где в качестве входных данных указан SID krbtgt
Рисунок 19 - Вывод DSInternals после выполнения DCSync, где в качестве входных данных указан SID krbtgt

В отличии от предыдущих утилит, при выполнении репликации с помощью функции DRSGetNCChanges входная версия сообщения запроса используется и выбирается в зависимости от версии домена/леса.

Кроме этого, поддерживаются следующие форматы при отправке:

  • Windows 2000 RPC replication (версия 5);

  • Windows Server 2003 RPC replication (версия 8);

  • Windows Server 2008 R2 operating system RPC replication (версия 10).

А при получении ответа в 6 версии (Windows Server 2003 operating system) в формате REPLVALINF_V1, идет преобразование к REPLVALINF_V3. Также поддерживаются более новые форматы, но преобразования не происходит. В mimikatz и secretsdump используются только версии сообщения запроса/ответа, соответсвующие RPC запросу Windows Server 2003, но как мы можем заметить данные утилиты продолжают работать с новыми версиями Windows. Происходит это из-за того, что более ранние версии совместимы с поздними, но не наоборот. То есть, если бы использовался только новый формат сообщений, то на старых версиях домена утилиты бы не работали.

Что в результате?

Ранее мы обратили внимание на то, что утилиты secretsdumpmimikatzDSInternal очень схожи между собой. Они используют одни и те же методы из DRSUAPI для репликации. Отличие только в порядке их вызова, который может быть ключевым моментом для определения конкретной утилиты по трафику. Но так ли это важно?

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

У нас также есть возможность проследить разницу между легитимной репликацией и выполнением атаки DCSync. Первое на что стоит обратить внимание, так это на то, что появляются вызовы новых функций DRSGetDomainControllerInfo и DRSCrackNames. Эти функции можно не вызывать, а напрямую указать данные о пользователях и КД, которые могут быть собраны другими способами. В качестве таких способов, например, выступают LDAP запросы. Поскольку кодовая база рассмотренных утилит открыта, то реальный атакующий имеет возможность скорректировать ее под свои нужды. Нам также удалось выяснить, что функция DRSGetNCChanges должна вызываться всегда, поскольку именно она проводит репликацию.

При проведении атаки нетрудно заметить отсутствие вызова функции DRSReplicaSync. Возникает сразу вопрос: а может ли атакующий для большей схожести с легитимной репликацией вызвать эту функцию? Может, но никаких данных и паролей в результате вызова функции он не получит. Согласно документации функция DRSReplicaSync начинает цикл репликацией с КД, расположенных в атрибуте RepsFrom корневого объекта домена.

Изучение содержимого атрибута RepsFrom.

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

Для просмотра через GUI в оснастке Active Directory Users and Computers, нам нужно включить Advanced Features, и после этого открыть в Properties вкладку Attribute Editor. А затем уже в ней найти атрибут RepsFrom, где хранится запись контроллера домена.

Рисунок 20 - просмотр содержимого RepsFrom через оснастку Active Directory Users and Computers
Рисунок 20 - просмотр содержимого RepsFrom через оснастку Active Directory Users and Computers

Для получения аналогичной информации можно использовать LDAP запрос. Информация предоставляется в формате base64, если её декодировать, то также получим запись.

Рисунок 21 - просмотр содержимого RespFrom c помощью командной строки
Рисунок 21 - просмотр содержимого RespFrom c помощью командной строки

На рисунке 21 видно, что контроллер домена DC01 в RepsFrom содержит запись на DC02 и наоборот, что сходится с документацией. Таким образом, контроллеры домена DC01 и DC02 реплицируются между собой. Вследствие этого, атакующему нет смысла выполнять вызов функции DRSReplicaSync, так как реплика будет совершаться не с подконтрольной ему машиной, а это может служить одним из индикаторов атаки.

Дополнительно выделим момент с источником репликации: легитимная деятельность подразумевает вызов DRSReplicaSync клиента к серверу, после чего уже сервер вызывает DRSGetNCChanges к клиенту. Тогда как в случае атаки все запросы выполняются строго клиентом к серверу. Однако отсутствие наличия вызова DRSReplicaSync мягко говоря является более простым для реализации индикатором атаки.

Итак, мы разобрали, что собой представляет атака DCSync и изучили несколько популярных утилит для ее проведения. Утилиты имеют свои особенности, но у всех прослеживается один и тот же принцип проведения атаки, а также во всех присутствует ключевой фактор - отсутствие вызова DRSReplicaSync. Данный фактор можно использовать для выявления атаки.
В следующей части мною будет рассмотрены несколько примеров того, каким образом мы можем детектировать данную атаку с помощью журналов Windows, а также на уровне сети.

Спасибо всем за внимание! Пишите, комментарии и задавайте вопросы!

Автор: Кожушок Диана (@wildresearcher), аналитик-исследователь киберугроз в компании R-Vision

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