
«Ennyn Durin Aran Moria: pedo mellon a minno» — «Врата Дурина, Владыки Мории. Скажи „друг“ и войди».
Самый известный пароль в литературе — эльфийское mellon, «друг» — открывал Западные врата Мории любому, кто удосужился прочитать надпись прямо над ними. Удобно для своих. И, к сожалению, для чужих тоже.
В корпоративных доменах часто встречаются пароли из словарей — в некоторых случаях это равносильно паролю, написанному на воротах. Смотрите сами.
Администратор правильно настроил политику паролей в домене: минимум 12 символов, три класса символов, история, блокировки. Но проверка показывает, что пароли учётных записей сотрудников есть в публичных дампах и словарях. «Сложные» пароли вроде Zima2025!, P@ssw0rd и Qwerty123! формально соответствуют политике, но злоумышленнику понадобится не так много попыток, чтобы подобрать такие пароли.
Проблема в том, что доменная политика проверяет пароль на соответствие правилам, но ничего не знает про его значение. Она не в курсе, что P@ssw0rd — самый заезженный «сложный» пароль на планете, а пароль из названия компании и года подбирается с трёх попыток.
Почему пароли — всё ещё слабое звено №1
Мы в InfoWatch защищаем данные компаний от утечек, и во многих инцидентах видна закономерность: чаще всего всё начинается не с хитрой уязвимости нулевого дня, а с учётной записи, к которой подобрали пароль или чей пароль утёк из-за переиспользования на публичном сервисе.
А что стоит между учётной записью и злоумышленником? В большинстве инфраструктур — всё ещё только пароль: не аппаратный ключ, не биометрия и не второй фактор на каждом сервисе, а строка, которую сотрудник придумал сам и, будем честны, придумал так себе. Можно сколько угодно внедрять MFA, PAM и Zero Trust — пароль в AD остаётся фундаментом, на который всё это опирается. Скомпрометированная доменная учётная запись открывает вход злоумышленнику. В итоге — компрометация всего домена и громкая история: простой производства, отмены рейсов, утечки персональных данных…
И это не абстрактная страшилка, а то, что происходит в реальности. По данным Verizon DBIR за 2025 год, украденные учётные данные — вектор первичного доступа №1: в атаках на веб-приложения они участвуют в 88% случаев, а базовым требованиям сложности отвечали лишь 3% скомпрометированных паролей. IBM Cost of a Data Breach 2024 ставит компрометацию учётных данных на первое место среди причин утечек (16% инцидентов), причём такие взломы дольше всего остаются незамеченными — в среднем 292 дня на обнаружение и локализацию, а средняя цена утечки дошла до 4,9 млн долларов. В России тренд тот же: по данным Positive Technologies, в первой половине 2024 года кража учётных данных фигурировала в 21% успешных атак на организации — на 9 процентных пунктов больше, чем годом ранее.
Сложные алгоритмы и ИИ не дают 100% защиты от скомпрометированного пароля, а зачастую либо ловят аномалию с большим опозданием, либо вовсе не реагируют. Реклама SIEM и поведенческих систем обещает ML-модели и выявление аномалий — но вход с валидным, пусть и украденным, паролем выглядит для них как обычный логин легитимного пользователя, придраться не к чему. Атакующие осваивают всё более изощрённые техники обхода, а базовый приём остаётся прежним: зайти в службу каталогов под настоящим паролем, который оказался не только у владельца. Поэтому пароли разумнее проверять заранее, а не рассчитывать, что аномалию поймают уже по ходу атаки.
Что будем делать
Здесь и появляется аудит паролей: проверяем, что реально стоит у пользователей прямо сейчас. Защита данных начинается с защиты учётных записей — и тут мы можем помочь: показать слабые и утёкшие пароли раньше, чем их найдёт кто-то снаружи.
В этой статье я хочу рассказать, как регулярно проверять пароли пользователей. Для этого разверну лабораторный домен на Windows Server 2025, соберу словарь из базы Have I Been Pwned и собственного списка паролей организации, а потом с помощью PowerShell-модуля DSInternals проверю, у кого из пользователей пароль угадывается по словарю, — не зная и не подбирая сам пароль. Начнём с короткой теории (без неё половина метода выглядит магией), дальше — сплошная практика с командами и скриншотами.
Немного теории: почему хеш одного и того же пароля везде одинаковый
Это ключевой момент — именно поэтому метод проверки и работает. Разберёмся, что на самом деле лежит в базе AD.
NT-хеш: MD4 без соли
Когда пользователь задаёт пароль, Active Directory не хранит его в открытом виде (если только явно не включена обратимо шифруемая история, но об этом ниже). Хранится NT-хеш (он же NTLM-хеш, он же unicodePwd), который вычисляется предельно просто:
NT-хеш = MD4( UTF-16LE( пароль ) )
То есть пароль переводится в кодировку UTF-16 Little Endian и один раз прогоняется через MD4. И всё. Здесь нет соли, нет итераций, нет привязки к имени пользователя, домену или машине.
Следствие, которое и делает возможным наш аудит: один и тот же пароль всегда даёт один и тот же NT-хеш — в вашем домене, в соседнем домене и в дампе десятилетней давности. Пароль Qwerty123! превращается в один и тот же NT-хеш 44BF0244F032CA8BAADDDA0FA9328BF8 — ровно эти 32 hex-символа — у кого угодно.
Именно поэтому существуют и радужные таблицы, и база Have I Been Pwned: можно один раз посчитать NT-хеши всех утёкших паролей и потом просто искать совпадения. Нам не нужно знать пароль пользователя — достаточно сравнить его NT-хеш с заранее посчитанным списком. Сравнение хеш-в-хеш, никакого перебора.
LM-хеш: legacy, который иногда всё ещё жив
Исторический предшественник — LM-хеш (LAN Manager). Он ещё хуже: пароль приводится к верхнему регистру, обрезается до 14 символов, режется на два блока по 7 символов и шифруется DES. Из-за этого он ломается за минуты. Начиная с Windows Server 2008 LM-хеши по умолчанию не хранятся, но в доменах с долгой историей и старыми настройками (NoLMHash) они иногда остаются. Аудит стоит того, чтобы это проверить — DSInternals покажет учётные записи, у которых LM-хеш всё ещё присутствует.
Kerberos-ключи: а вот здесь соль появляется
Может, тогда выручает Kerberos? Отчасти.
Ключ RC4-HMAC (тип шифрования 23) в Kerberos — это буквально тот же самый NT-хеш. То есть RC4 наследует ту же проблему: ключ без соли, детерминированный, одинаковый везде. Отсюда, кстати, растёт Kerberoasting.
Ключи AES128/AES256 (типы 17 и 18) считаются иначе — через функцию string-to-key (PBKDF2) с солью. Соль формируется из имени realm (в верхнем регистре) и имени пользователя, например
LAB.LOCALj.ivanov. Поэтому AES-ключ разный у разных учётных записей даже при одинаковом пароле, и готовым списком его так просто не проверишь.
Пока в домене живут NT-хеш и RC4, одинаковость хеша повсюду — просто факт. Атакующий обернёт его против вас; мы развернём в свою сторону.
Как это лежит внутри ntds.dit
«Но ведь база ntds.dit зашифрована!» — да, но это шифрование хранилища, а не пароля. Внутри NT-хеши дополнительно зашифрованы ключом PEK (Password Encryption Key), а сам PEK зашифрован BootKey (SYSKEY), который хранится в ветке реестра SYSTEM. Это защита данных на диске, а не соль: как только у вас есть права снять реплику или прочитать ntds.dit вместе с BootKey, вы получаете те же самые детерминированные NT-хеши. Ровно это DSInternals и делает за нас — расшифровывает слой хранилища и отдаёт «чистые» NT-хеши для сравнения.
Обратимо шифруемые пароли (reversible encryption)
Отдельная находка, которую полезно искать: атрибут «Store password using reversible encryption». Если он включён, пароль хранится не в виде хеша, а шифруется ключом, производным от SYSKEY, — то есть его можно вернуть в открытый вид. DSInternals покажет такие учётные записи со свойством ClearTextPassword. По умолчанию опция выключена, но её иногда включают ради старых протоколов (например, CHAP) и забывают. Это прямой риск.
Сравнить с утечками или ломать в лоб?
У аудита паролей есть два принципиально разных пути, и их часто путают.
Первый — взлом хешей (offline cracking): выгрузить NT-хеши и натравить на них hashcat со словарями, правилами и масками, восстанавливая пароли в открытом виде. Так можно узнать даже нетривиальный пароль, которого нет ни в одной утечке. Но этот способ достаточно ресурсоёмкий (нужны GPU и время).
Второй — сравнение хешей со словарём и базой утечек, о котором эта статья. Он не восстанавливает пароль, а отвечает на один вопрос: есть ли такой хеш в списке заведомо плохих. Отсюда плюсы — быстро (бинарный поиск, минуты вместо часов), без GPU, и вы не касаетесь открытых паролей. Минус — метод видит только то, что уже попало в словарь или утечку: уникально слабый, но не «засвеченный» пароль он пропустит.
На практике это не «или-или». Сравнение с HIBP и собственным словарём — быстрый первый проход, который снимает основную массу проблем; брутфорс hashcat подключают точечно и по согласованию, когда нужно копать глубже. Здесь мы идём быстрым и безопасным путём — сравнением.
Инструменты
DSInternals — открытый PowerShell-модуль Михаэля Графнеттера (Michael Grafnetter) для низкоуровневой работы с Active Directory. Нас интересуют два командлета:
Get-ADReplAccount— забирает учётные записи вместе с секретами (NT-хеши и прочее) прямо с контроллера домена по сети, штатным механизмом репликации между контроллерами (тот самый DCSync). Онлайн-режим, ничего останавливать не нужно.Test-PasswordQuality— берёт выгруженные учётные записи и проверяет их по словарям: сравнивает NT-хеши с базой утёкших, ищет пустые/повторяющиеся/обратимо шифруемые пароли и другие проблемы.
Have I Been Pwned — Pwned Passwords — база из сотен миллионов паролей из реальных утечек. Нам нужна её выгрузка в формате NTLM, ordered by hash (отсортированная по хешу — для быстрого бинарного поиска).
Собственный словарь — то, чего в HIBP по определению нет: пароли, характерные именно для вашей организации.
Разворачиваем стенд
Чтобы никого не подставить, всё проверяем на изолированном стенде. Минимальная конфигурация:
виртуальная машина с Windows Server 2025 в роли контроллера домена (
DC01);новый лес/домен, например
lab.local(NetBIOSLAB);несколько тестовых пользователей с заведомо слабыми паролями, чтобы было что находить.
Наполнять домен руками скучно и долго. Чтобы быстро получить реалистичный «бардак» — десятки учётных записей со слабыми и стандартными паролями, цели для Kerberoasting, типичные ошибки в правах и настройках, — удобно взять готовый проект VulnerableAD (safebuffer/vulnerable-AD). Склонируйте репозиторий, подключите модуль по инструкции из README и одной командой наполните домен типовыми уязвимостями:
git clone https://github.com/safebuffer/vulnerable-ADInvoke-VulnAD -UsersLimit 100 -DomainName 'lab.local'
Он создаёт сотню пользователей с предсказуемыми паролями (вроде Changeme123!), прячет пароли в описаниях объектов и настраивает классические огрехи — как раз то, что должен подсветить наш аудит.
Для наглядности примеров ниже я вдобавок завёл несколько именованных учётных записей с говорящими паролями — на контроллере домена, под администратором домена (в рабочей среде так, разумеется, не делают):
Import-Module ActiveDirectory$pw = @{ 'j.ivanov' = 'Qwerty123!' 'a.petrov' = 'Zima2025!' 'svc_backup' = 'P@ssw0rd' 's.orlova' = 'Infowatch2025' 'd.kuznetsov' = 'Qwerty123!'}foreach ($u in $pw.Keys) { New-ADUser -Name $u -SamAccountName $u -AccountPassword (ConvertTo-SecureString $pw[$u] -AsPlainText -Force) -Enabled $true}
Два пользователя (
j.ivanovиd.kuznetsov) получили один и тот же пароль намеренно — чтобы позже увидеть, как DSInternals ловит повторяющиеся пароли черезDuplicatePasswordGroups.

Шаг 1. Ставим DSInternals
Модуль есть в PowerShell Gallery (на старых системах перед установкой включаем TLS 1.2):
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12Install-Module DSInternals -ForceImport-Module DSInternalsGet-Module DSInternals

Если сервер без доступа в интернет — забираем модуль на машине с доступом через Save-Module DSInternals -Path .\ и переносим папку в C:\Program Files\WindowsPowerShell\Modules\.
EDR/антивирус может ругаться на DSInternals как на «hacktool» — это ожидаемо для инструмента двойного назначения. На стенде добавляем исключение, в рабочей среде — согласуем запуск с ИБ заранее.
Шаг 2. Готовим базу Have I Been Pwned (NTLM)
Актуальный официальный способ — утилита-загрузчик haveibeenpwned-downloader (dotnet-тул; нужен .NET SDK, иначе берём готовый бинарник из GitHub Releases проекта). Она скачивает все диапазоны хешей и собирает офлайн-файл без обращения к API в момент проверки, а флаг -n переключает базу с SHA-1 на NTLM:
dotnet tool install --global haveibeenpwned-downloaderhaveibeenpwned-downloader -n pwnedpasswords_ntlm
На выходе — файл pwnedpasswords_ntlm.txt в формате NT-ХЕШ:счётчик, отсортированный по хешу. Именно такой формат нужен параметру -WeakPasswordHashesSortedFile: по нему DSInternals делает бинарный поиск.

Учтите: база NTLM весит десятки гигабайт, так что загрузка не мгновенная.
Важно не перепутать сортировку: для
-WeakPasswordHashesSortedFileнужен файл ordered by hash. Вариант «ordered by count» отсортирован по популярности и для бинарного поиска не годится.
Шаг 3. Собираем собственный словарь организации
HIBP ловит то, что уже утекло у всех. Но пароль Infowatch2025 в публичные утечки мог и не попасть, а подбирается за пару попыток. Такие пароли добавляем сами. Что обычно кладут в собственный список:
название компании и продуктов во всех вариантах (
InfoWatch,infowatch,iw,TrafficMonitor…);город, адрес, индекс, телефонные коды;
сезоны и месяцы + текущий и прошлый год (
Zima2025,Autumn2025,Leto2024);«клавиатурные» и вечная классика (
Qwerty,Password,Admin,123456);имена внутренних систем, проектов, релизов.
Дальше на эти базовые слова добавляем типовые пользовательские вариации — регистр, leet-замены (a→@, o→0, i→1, s→$) и суффиксы (123, !, 2025, @):
$base = 'infowatch','company','password','qwerty','admin','zima','leto','vesna','osen'$suffixes = '','1','12','123','!','@','2024','2025','123!','@2025'$words = foreach ($w in $base) { $cap = (Get-Culture).TextInfo.ToTitleCase($w) foreach ($s in $suffixes) { $w + $s $cap + $s ($w -replace 'a','@' -replace 'o','0' -replace 'i','1' -replace 's','$') + $s }}$words | Sort-Object -Unique | Set-Content -Encoding UTF8 .\company-weak.txt
Формат простой: один пароль в строке, в открытом виде. Test-PasswordQuality сам посчитает NT-хеши и сравнит.

Шаг 4. Забираем хеши с контроллера домена (DCSync)
Теперь получаем секреты учётных записей. В онлайн-режиме DSInternals реплицирует их с DC тем же способом, что и штатный контроллер домена:
$accounts = Get-ADReplAccount -All -Server DC01 -NamingContext 'DC=lab,DC=local'

Для этой операции учётной записи нужны права репликации каталога — Replicating Directory Changes и Replicating Directory Changes All на разделе домена. У Domain Admins они есть по умолчанию; в рабочей среде для разового аудита лучше завести отдельную учётную запись, выдать ей ровно эти два права, а после аудита — отозвать.
С этого момента в переменной
$accountsу вас в памяти лежат NT-хеши всего домена. Это дамп секретов. Не выгружайте его на общие диски, не оставляйте в истории PowerShell, по возможности работайте прямо на DC или на защищённой станции администратора.
А если прав репликации не хватает — команда честно об этом скажет:

Шаг 5. Запускаем проверку
Передаём выгруженные учётные записи в Test-PasswordQuality, добавив обе базы — утёкшие хеши и наш собственный словарь:
$report = $accounts | Test-PasswordQuality ` -WeakPasswordHashesSortedFile .\pwnedpasswords_ntlm.txt ` -WeakPasswordsFile .\company-weak.txt ` -IncludeDisabledAccounts$report
-IncludeDisabledAccounts добавит в проверку отключённые учётные записи — их часто забывают, а пароли у них живут годами.
Полный отчёт приходит уже разложенным по типам находок:

Шаг 6. Читаем отчёт
Test-PasswordQuality возвращает объект с готовыми списками. Самое важное:
WeakPassword— учётные записи, чей пароль нашёлся в HIBP или в вашем словаре. Главный результат.DuplicatePasswordGroups— группы учётных записей с одинаковым паролем (нашиj.ivanovиd.kuznetsovдолжны оказаться здесь).ClearTextPassword— включено обратимое шифрование, пароль хранится восстановимо.LMHash— присутствует устаревший LM-хеш.PasswordNeverExpires,PasswordNotRequired— организационные слабости учётных записей.AESKeysMissing,PreAuthNotRequired(AS-REP roasting),SmartCardUsersWithPassword— дополнительные находки по гигиене.
Смотрим точечно и делаем короткий отчёт:
"Слабые/утёкшие пароли:"; $report.WeakPassword"Повторяющиеся пароли:"; $report.DuplicatePasswordGroups"Обратимое шифрование:"; $report.ClearTextPassword$report.WeakPassword | ForEach-Object { [pscustomobject]@{ SamAccountName = $_ } } | Export-Csv .\weak-accounts.csv -NoTypeInformation -Encoding UTF8


На нашем стенде в WeakPassword ожидаемо попадают все пятеро: три пароля совпали с базой HIBP, Zima2025! и Infowatch2025 — с нашим словарём. А DuplicatePasswordGroups показывает пару с одинаковым паролем. Метод работает, причём мы ни разу не «подбирали» пароль — только сравнивали хеши.
Только не обольщайтесь: конкретные пароли (Zima2025! и прочие) мы знаем лишь потому, что сами завели их на стенде. В рабочем домене Test-PasswordQuality скажет только, что пароль учётной записи есть в словаре или утечке, но сам пароль не покажет. Исключение — учётные записи с обратимым шифрованием: для них пароль приходит в ClearTextPassword открытым текстом.

Что пойдёт не так (грабли, которые я собрал за вас)
На бумаге всё гладко, но подводных камней хватает. Что стоит предусмотреть заранее:
Нет прав репликации.
Get-ADReplAccountупадёт с ошибкой доступа, если у учётной записи нет Replicating Directory Changes (All). Что делать: запускать под учётной записью с этими правами или на DC под администратором; в рабочей среде — выдать права временно и отозвать после.Неправильный формат базы HIBP. Файл «ordered by count» не подходит для
-WeakPasswordHashesSortedFile. Что делать: берём строго ordered by hash; если пользуетесь новым каталожным форматом HIBP (папка файлов по префиксу хеша), используйте параметр-WeakPasswordHashesSortedFilePath.Не хватило места на диске. База NTLM весит десятки гигабайт. Что делать: заранее убедиться, что столько свободного места на диске есть.
Нагрузка DCSync на большом домене. Репликация десятков тысяч учётных записей нагружает DC и сеть. Что делать: запускать в непиковые часы или уйти в офлайн-режим: снять
ntds.ditчерезntdsutil(IFM-снапшот) и разобратьGet-ADDBAccount— тогда рабочий DC вообще не трогаем.EDR блокирует DSInternals. Инструмент двойного назначения часто в сигнатурах. Что делать: исключение на стенде, согласование с ИБ в рабочей среде.
Ложное чувство безопасности. DSInternals не перебирает все пароли — он сравнивает со словарём и утечками. Пароль может быть слабым, но отсутствовать в списках. Что делать: расширяем собственный словарь под вашу специфику; аудит дополняет, а не заменяет строгую политику и MFA.
Сами результаты — чувствительные данные. CSV со списком учётных записей со слабыми паролями — это карта для атакующего. Что делать: храним в защищённом месте, передаём владельцам систем по защищённому каналу, удаляем дампы и переменную
$accounts(Remove-Variable accounts) после работы.
Что делать с находками
Найти — половина дела. Дальше:
принудительная смена пароля у всех из
WeakPassword(Set-ADUser ... -ChangePasswordAtLogon $true), в первую очередь у привилегированных и сервисных учётных записей;разбор
DuplicatePasswordGroups— одинаковые пароли часто означают общий «шаблон» при заведении;выключить reversible encryption там, где оно всплыло, и разобраться, зачем его включали;
сделать аудит регулярным — завести Scheduled Task, скажем, раз в месяц, и следить за динамикой.
Если командная строка не по душе
Всё выше — сценарный путь через PowerShell: гибко, бесплатно и воспроизводимо. Но если такие проверки должны идти по расписанию и с отчётами для нетехнических коллег, удобнее графические инструменты. На рынке есть готовые решения, которые делают ту же сверку хешей паролей домена с базой утечек через привычный интерфейс — с наглядными отчётами и постоянным мониторингом. Логика под капотом та же, что мы разобрали руками; меняется только упаковка.
Выводы
Парольная политика проверяет пароль на соответствие правилам, но не его значение. А раз NT-хеш вычисляется без соли и всегда одинаков, эту особенность можно повернуть в любую сторону: атакующий сверит ваши хеши с утечками — а вы сделаете то же самое, только первыми. DSInternals превращает теорию в десятиминутную практику: забрали хеши, сравнили со словарём HIBP и собственным списком, получили поимённый список тех, кому пора менять пароль. Без перебора, одним сравнением.
И относиться к нему стоит не как к разовому «взлому ради галочки», а как к регулярной гигиене. Слабые пароли копятся тихо, по одному, вместе с новыми учётными записями и «временными» решениями. Найти их самому всегда дешевле, чем прочитать о них в чужом отчёте о компрометации.
Западные врата Мории открывались любому, кто знал одно простое слово, заботливо написанное над входом. Проверьте, не открывается ли ваш домен так же — пока это не проверил кто-то снаружи.
Легальные и этические оговорки
Всё описанное — инструмент двойного назначения. Запускать Get-ADReplAccount и извлекать хеши из чужого домена без письменного разрешения — это неправомерный доступ, а не «аудит». Проверяйте только свою инфраструктуру и только с явной авторизацией (в идеале — с зафиксированным согласованием у владельца системы и ИБ). Хеши, дампы и отчёты — чувствительные данные: защищайте их при хранении и удаляйте после работы.
Список литературы и ссылки
Документация Microsoft
Store passwords using reversible encryption — learn.microsoft.com
Network security: Configure encryption types allowed for Kerberos — learn.microsoft.com
Detect and remediate RC4 usage in Kerberos (почему RC4-ключ равен NT-хешу и чем это опасно) — learn.microsoft.com
Спецификации протоколов: [MS-KILE] (расширения Kerberos) и [MS-DRSR] (репликация каталога, лежит в основе DCSync) — Microsoft Open Specifications.
Инструменты
DSInternals — репозиторий на GitHub, документация
Test-PasswordQuality, статья «Auditing AD Password Quality».Have I Been Pwned — Pwned Passwords и загрузчик PwnedPasswordsDownloader.
VulnerableAD — быстрое наполнение стенда уязвимостями: safebuffer/vulnerable-AD.
Стандарты и криптография
RFC 4757 — тип шифрования RC4-HMAC для Kerberos: rfc-editor.org.
RFC 3961 и RFC 3962 — функция string-to-key и AES для Kerberos: 3961, 3962.
Практические разборы
Auditing Active Directory passwords against HaveIBeenPwned — adainese.it.
Detecting weak passwords in Active Directory — michaelwaterman.nl.
Исследования и статистика
Verizon Data Breach Investigations Report (DBIR) 2025 — verizon.com.
IBM Cost of a Data Breach Report 2024 — ibm.com.
Positive Technologies, актуальные киберугрозы (первое полугодие 2024) — ptsecurity.com.
Терминология ИБ (РФ)
ГОСТ Р 50922-2006 и ГОСТ Р 53114-2008 (основные термины защиты информации), Банк данных угроз ФСТЭК России (bdu.fstec.ru).

