Сложность пароля пользователя в домене Active Directory — это важный элемент безопасности как данных пользователя, так и домена целиком. Несмотря на рекомендации не использовать в качестве паролей личные данные, словарные слова и простые комбинации, многие пользователи продолжают использовать простые и легко запоминаемые пароли. В этой статье мы покажем, как выполнить аудит используемых паролей пользователей Active Directory, найти слабые и простые пароли с помощью PowerShell.
P@ssw0rd
или
Pa$$w0rd
Установка PowerShell модуля DSInternals (Directory Services Internals)
Чтобы сравнить хэши паролей пользователей, хранящихся в базе Active Directory (файл ntds.dit) со словарем простых и распространённых паролей можно использовать сторонний PowerShell модуль — DSInternals. Этот модуль содержит ряд командлетов, которые позволяет выполнять различные операции с базой данных AD в онлайн или офлайн режиме (непосредственно с файлом ntds.dit). В частности, нас интересует командлет Test-PasswordQuality, позволяющий найти пользователей со слабыми, одинаковыми, стандартными, пустыми паролями (Password Not Required), пароли которых никогда не истекают (Password Never Expires).
В PowerShell версии 5 (и выше) вы можете установить модуль DSInternals онлайн из официальной галереи скриптов PowerShell так:
Install-Module DSInternals
Для предыдущих версий PowerShell и на изолированных системах придется скачать zip архив с последней версией модуля с GitHub (https://github.com/MichaelGrafnetter/DSInternals/releases). На момент написания статьи последний релиз — DSInternals v4.4.1. Распакуйте содержимое архива в один из каталогов с модулями PowerShell:
- C:\Windows\system32\WindowsPowerShell\v1.0\Modules\DSInternals
- C:\Users\%username%\Documents\WindowsPowerShell\Modules\DSInternals
Или можно импортировать модуль DSInternals командой:
Import-Module C:\distr\PS\DSInternals\DSInternals.psd1
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass –Force
Список доступных командлетов модуля можно получить так:
Get-Command -Module DSInternals
Поиск слабых паролей в AD с помощью командлета Test-PasswordQuality
Далее необходимо создать словарь паролей. Это будет простой тестовый файл со списком распространениях используемых, слабых и других плохих паролей. Вы можете скачать словарь паролей из Интернета или создать его самостоятельно. Модуль DSInternal позволит сравнить хэши паролей ваших пользователей в Active Directory с хэшами слов из этого файла. Сохраните пароли в текстовый файл PasswordDict.txt.
Теперь создайте небольшой PowerShell скрипт. В следующих переменных укажите путь к файлу с паролями, имя домена и контроллера домена.
$DictFile = "C:\PS\PasswordDict.txt"
$DC = "msk-dc01"
$Domain = "DC=winitpro,DC=ru"
Далее с помощью командлета Get-ADReplAccount можно получить список пользователей в AD (по аналогии с Get-ADUser). Дополнительно данный командлет возвращает значения их NT, LM хешей, а также историю хешей.
Затем для каждого пользователя будет проведено сравнение соответствия хеша его пароля с хешами из файла-словаря (проверка выполняется также и для отключенных аккаунтов):
Get-ADReplAccount -All -Server $DC -NamingContext $Domain | Test-PasswordQuality -WeakPasswordsFile $DictFile -IncludeDisabledAccounts
Результат выполнения скрипта может выглядеть так:
Active Directory Password Quality Report --------------------------------------- Passwords of these accounts are stored using reversible encryption: LM hashes of passwords of these accounts are present: These accounts have no password set: WINITPRO\DefaultAccount WINITPRO\Guest Passwords of these accounts have been found in the dictionary: WINITPRO\aivanov WINITPRO\bpetrov WINITPRO\vsidorov These groups of accounts have the same passwords: Group 1: WINITPRO\anovak WINITPRO\Administrator WINITPRO\gpetrov WINITPRO\dkarpov Group 2: WINITPRO\bpetrov WINITPRO\vsidorov WINITPRO\aivanov These computer accounts have default passwords: Kerberos AES keys are missing from these accounts: Kerberos pre-authentication is not required for these accounts: Only DES encryption is allowed to be used with these accounts: These administrative accounts are allowed to be delegated to a service: WINITPRO\Administrator WINITPRO\krbtgt Passwords of these accounts will never expire: WINITPRO\Administrator WINITPRO\DefaultAccount WINITPRO\Guest WINITPRO\krbtgt WINITPRO\web These accounts are not required to have a password: These accounts that require smart card authentication have a password:
Install-Module -Name DSInternals -RequiredVersion 2.23
Поиск по хэшам выполняется в том числе по истории паролей пользователей, хранящейся в AD. Как вы видите, были успешно найдены пользователи AD с простыми паролями (пароли совпадают со словарем). Также найдены несколько пользователей с одинаковыми паролями. Этот сценарий поможет вам найти аккаунты с простыми паролями, для которых действуют кастомные парольные политики Fine-Grained Password Policies.
Также вы можете выполнить офлайн сканирование файла базы данных Active Directory (ntds.dit). Вы можете получить копию файла ntds.dit из теневой копии или резервной копии контроллера домена.
Для офлайн проверки хэшей в файле ntds.dit воспользуйтесь такими командами:
$keyb= Get-BootKey -SystemHiveFilePath 'C:\ADBackup\registry\SYSTEM'
Get-ADDBAccount -All -DatabasePath 'C:\ADBackup\ntds.dit -BootKey $keyb| Test-PasswordQuality -WeakPasswordsFile $DictFile
Также можно выгрузить список всех хэшей в текстовый файл:
Get-ADDBAccount -All -DBPath 'C:\ADBackup\ntds.dit' -Bootkey $keyb | Format-Custom -View HashcatNT | Out-File c:\ps\adhashes.txt -Encoding ASCII
Итак, мы рассмотрели, как выполнить анализ качества паролей пользователей AD, их устойчивости перед брутфорсом по словарю, оценить используемую политику сложности паролей в домене, ну и сделать организационные выводы :). Такой аудит администраторы Active Directory могут (и даже должны) выполнять регулярно.
Ошибка, не работает:
Get-ADReplAccount : Method not found: ‘IntPtr System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(!!0)’.
Ошибка, не работает!!!
Какая версий ОС, Powershell и .NET Framework?
PowerShell:
Major Minor Build Revision
—— —— —— ———
5 0 10586 117
NET Framework:4,5
OC: windows7
Я запускал скрипт на Windows 2012 R2. Похоже в Windows Management Framework (WMF) 5.0 для Windows 7 чего-то не хватает (кстати говоря уже не первый раз сталкиваюсь с проблемами запуска некоторых командлетов Powsh 5 на Win 7).
Работает На 2012R2. Спасибо
Подскажите а что значит раздел
These administrative accounts are allowed to be delegated to a service:
Эти учетки могут использоваться для запуска служб на неких серверах/станциях домена.
Добрый день! А есть ли возможность использования фильтра по определенному OU? Для теста хотелось бы проверить в конкретном контейнере, а то домен большой очень и пользователей 100к+. Хотелось бы что-то типа: -SearchBase ‘…’
К сожалению, я тоже не придумал как ограничить область поиска, в стандартной поставке такого параметра нет.
Удалось ограничить область поиска посредством цикла:
Import-Module C:\DSInternals\DSInternals.psd1
$Server= «…»
$Passes= «C:\pass\passwords.txt»
$Passesfile= Get-Content $Passes | ConvertTo-NTHashDictionary
$Users= Get-Aduser -Filter «*» -SearchBase ‘OU=Admins,DC=…,DC=…,DC=…,DC=…’-Server $Server
ForEach($user in $Users )
{
$User.DistinguishedName
Get-ADReplAccount -DistinguishedName $User.DistinguishedName -Server $Server |
Test-PasswordQuality -WeakPasswordHashes $Passesfile -ShowPlainTextPasswords
}
Поясню:Получаем список пользователей командой Get-Aduser по определенному OU и записываем в переменную $Users.
Далее уже идет цикл,в котором работаем со списком пользователей из определенной OU.
Но тут возникла проблема: Поскольку выполняется цикл, то у каждого пользователя свой отчет, а не как у вас в результате выполнения скрипта в примере.
Есть идеи как сделать единый отчет по всем у.з., а не по каждой в отдельности?)
Ограничить область поиска можно так:
$Users= Get-Aduser -Filter «*» -SearchBase ‘OU=Admins,DC=…,DC=…,DC=…,DC=…’-Server $Server
ForEach($user in $Users )
{
$User.DistinguishedName
Get-ADReplAccount -DistinguishedName $User.DistinguishedName -Server $Server |
Test-PasswordQuality -WeakPasswordHashes $Passesfile -ShowPlainTextPasswords
Но поскольку тут используется цикл, то в результате получается не один отчет как у вас в примере, а на каждую у.з. свой отчет,что в принципе не устраивает. Есть идеи как можно все это дело запихнуть в один отчет?
Отлично! Но судя по всему будет и работать и конструкция с DN именем OU поиска в качестве параметра атрибута DistinguishedName.
ЗЫ. Модуль качать и ставить некогда, поэтому сам проверить не могу.
PS C:\Windows\system32> $DictFile = «C:\DSInternals\PasswordDict.txt»
$DC = «ll.loc»
$Domain = «CN=mall-s-dc5,DC=ll,DC=loc»
$Dict = Get-Content $DictFile | ConvertTo-NTHashDictionary
Get-ADReplAccount -All -Server $DC -NamingContext $Domain | Test-PasswordQuality -WeakPasswordHashes $Dict -ShowPlainTextPasswords -IncludeDisabledAccounts
Get-ADReplAccount : Для этой операции репликации указан недопустимый контекст именования
строка:5 знак:1
+ Get-ADReplAccount -All -Server $DC -NamingContext $Domain | Test-PasswordQuality …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ADReplAccount], Win32Exception
+ FullyQualifiedErrorId : System.ComponentModel.Win32Exception,DSInternals.PowerShell.Commands.GetADReplAccountCommand
Делаю на win server 2012r2
PS C:\Windows\system32> $psversiontable
Name Value
—- ——
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.42000
BuildVersion 6.3.9600.17400
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
Framework версии v4.0.30319
В перемонной $DC нужно указывать имя ближайшего DC, а не имя домена.
Ошибка:
Get-ADReplAccount: Method not found: …
Пробую на Win7 (x32) +PS 5.1
Добрый день!!
А есть ли похожий скрипт для аудита пароля локального админа?
Добрый день! Скачал и установил последнюю версию DSInternals
Редактирую скрипт под свой домен
И в строке $Dict = Get-Content $DictFile | ConvertTo-NTHashDictionary
Не могу написать параметр ConvertTo-NTHashDictionary
Табом у мена находит только ConvertTo-NTHash
Я чего то не доустановил? Спасибо!
Возможно модуль DSInternals не загружен или в новой версии они убрали командлет ConvertTo-NTHashDictionary.
PS. Пока писал ответ, и вправду увидел, что с осени 2018 в модуле DSInternals 3.0 нет командлета ConvertTo-NtHashDictionary. Вместо него рекомендуется использовать командлет Test-PasswordQuality
Но командлет Test-PasswordQuality уже используется в 5 строке
$DictFile = «C:\PasswordDict1.txt»
$DC = «ll-dc5.ll.local»
$Domain = «DC=ll, DC=local»
$Dict = Get-Content $DictFile
Get-ADReplAccount -All -Server $DC -NamingContext $Domain | Test-PasswordQuality -WeakPasswordHashes $Dict -IncludeDisabledAccounts
$EWB.Saveas(‘C:\password.txt’)
Если командлет ConvertTo-NTHashDictionary убрать, появляется ошибка
$EWB.Saveas(‘C:\password.txt’)
Get-Content : Выдано исключение типа «System.OutOfMemoryException».
строка:4 знак:9
+ $Dict = Get-Content $DictFile
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Content], OutOfMemoryException
+ FullyQualifiedErrorId : System.OutOfMemoryException,Microsoft.PowerShell.Commands.GetContentCommand
Test-PasswordQuality : Не удается проверить аргумент для параметра «WeakPasswordHashesFile». Аргумент пустой или имеет значение NULL. Укажите непустой аргумент, не имеющ
ий значение NULL, после чего повторите выполнение команды.
строка:5 знак:102
+ … PasswordHashes $Dict -IncludeDisabledAccounts
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Test-PasswordQuality], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,DSInternals.PowerShell.Commands.TestPasswordQualityCommand
Как я понял, теперь вам не нужно получать хэши паролей для вашего словаря. Функционал ConvertTo-NTHashDictionary уже заложен в Test-PasswordQuality. Т.е. на вход командлету Test-PasswordQuality подается текстовый файл с паролями сразу, без получения хэшей. Как-то так (не тестировал):
$Dict = Get-Content $DictFile
Get-ADReplAccount -All -Server $DC -NamingContext $Domain |
Test-PasswordQuality -WeakPasswords $Dict -ShowPlainTextPasswords -IncludeDisabledAccounts
Или сразу подать на вход файл:
Get-ADReplAccount -All -Server $DC -NamingContext $Domain |
Test-PasswordQuality -WeakPasswordsFile "C:\distr\PS\DSInternals\PasswordDict.txt" -ShowPlainTextPasswords -IncludeDisabledAccounts
Получилось так:
Get-ADReplAccount -All -Server $DC -NamingContext $Domain |
Test-PasswordQuality -WeakPasswordsFile "C:\distr\PS\DSInternals\PasswordDict.txt" -IncludeDisabledAccounts
Параметр -ShowPlainText удалён на версии 3.0
Имеется 2 КД — один на WS2012R2, другой на WS2016 — на обоих КД отстутствует командлет ConvertTo-NTHashDictionary, есть только просто ConvertTo-NTHash
Данный командлет пропал в 3-ей версии DSInternals — решил проблему установкой 2-ой версии данного модуля:
Install-Module -Name DSInternals -RequiredVersion 2.23
Все верно, в 3 версии DSInternals для проверки пароля нужно использовать командлет Test-PasswordQuality (см. мои комментарии выше). Командлет ConvertTo-NTHashDictionary не поддерживается.
А как в 3 версии включить отображение найденных паролей (-ShowPlainTextPasswords выпилили)?
Всем привет! Удалось запустить вот так:
Get-ADReplAccount -All -Server $DC -NamingContext $Domain |
Test-PasswordQuality -WeakPasswordsFile «C:\Users\module\PasswordDict.txt» -IncludeDisabledAccounts
Подскажите пожалуйста, смог кто нибудь вывести найденные пароли, как на скриншоте в статье? Ранее за вывод видимо отвечала команда -ShowPlainTextPasswords, сейчас её нет.
Параметр ShowPlainTextPasswords убрали в версии модуля 3.0.
Test-PasswordQuality не может получить сам пароль, только его хеш и сравнить с хэшем словарного пароля. Если перебирать словарь по одному паролю и при совпадении с хешем выводить учетку и пароль из словаря на экран, получится почти тоже самое.
А как в версии 2.23 указать файл с паролями? на WeakPasswordsFile говорит, что не знает такого параметра
В старой версии DSInternals файл паролей нужно загружать немного по-другому:
$Dict = Get-Content $DictFile | ConvertTo-NTHashDictionary
Get-ADReplAccount -All -Server $DC -NamingContext $Domain |
Test-PasswordQuality -WeakPasswordHashes $Dict -ShowPlainTextPasswords -IncludeDisabledAccounts
Здраствуйте.
А а как реализовать офлайн проверку?
Дабы работать на отдельной машинке з самим ntds.dit и не разрешать powershell на DC
Как-то так можно оффлайн проанализировать файл ntds.dit, на сначала нужно получить ключ шифрования:
$keyb= Get-BootKey -SystemHiveFilePath 'C:\ADBackup\registry\SYSTEM'
Get-ADDBAccount -All `
-DatabasePath 'C:\ADBackup\ntds.dit' `
-BootKey $keyb|
Test-PasswordQuality -WeakPasswords 'Pa$$w0rd','Password123' `
-WeakPasswordsFile '.\passwords.txt'
Здраствуйте!
Имеется ли возможность использовать подстановочные знаки для генерации словаря паролей? Например, [a-с]ook — записать в словарь: aook, book, cook; 12? — записать в словарь все комбинации из 3-х символов и т.д.
Тут похоже больше на простую задачку для любого программиста. Тут и на powershell можно сделать.
За отправную точку воььмите _https://stackoverflow.com/questions/37256154/powershell-password-generator-how-to-always-include-number-in-string
Добрый день! А пароль для учетной записи krbtgt безопасно менять? Ведь он напрямую связан с Kerberos.
Пароль krbtgt менять надо. Гдето видел по рекомендацию про каждые 180 дней. Пароль меняется дважды для удаления из истории паролей. При сбросе пароля krbtgt всем клиентам и сервисам придется переаутентфицироваться в ad. В остальном — все безопасно.