Active Directory 도메인에서 사용자 암호의 복잡도는 사용자 데이터뿐만 아니라 전체 도메인 인프라의 보안을 좌우하는 핵심 요소입니다. 많은 사용자가 개인 정보, 사전에 등장하는 단어, 단순한 문자 조합을 암호로 사용하지 말라는 권고에도 불구하고, 기억하기 쉬운 단순한 암호를 선호하는 경향이 있습니다.
이 글에서는 PowerShell을 활용해 Active Directory 사용자 암호를 감사하고, 취약하거나 단순한 암호를 찾아내는 방법을 소개합니다.
도메인 암호 정책이 아무리 강력하더라도, 사용자는 기술적으로 Pa$$w0rd나 P@ssw0rd 같은 약하거나 기본적인 암호를 설정할 수 있다는 점에 유의해야 합니다.
DSInternals(Directory Services Internals) PowerShell 모듈 설치 방법
Active Directory 데이터베이스(ntds.dit 파일)에 저장된 사용자 암호 해시를 단순·범용 암호 사전과 비교하려면 서드파티 PowerShell 모듈인 DSInternals를 사용할 수 있습니다. 이 모듈은 AD 데이터베이스를 온라인 또는 오프라인(ntds.dit 직접 접근) 모드로 다룰 수 있는 다양한 cmdlet을 제공합니다.
특히 주목할 것은 Test-PasswordQuality cmdlet입니다. 이 cmdlet을 사용하면 약한 암호, 유사한 암호, 기본 암호, 빈 암호(암호 불필요), 만료되지 않는 암호를 사용하는 사용자를 탐지할 수 있습니다.
참고: 당연히 사용자 암호를 AD 데이터베이스에서 평문으로 추출할 수는 없습니다. Active Directory에 저장된 암호는 해시 형태로 보관됩니다. 하지만 AD 사용자의 암호 해시를 사전 파일에 있는 단어들의 해시와 비교하여 약한 암호를 식별할 수는 있습니다.
PowerShell 5 이상 버전에서는 공식 PowerShell 갤러리에서 DSInternals 모듈을 온라인으로 설치할 수 있습니다:
Install-Module DSInternals
이전 버전의 PowerShell이나 네트워크가 분리된 환경에서는 GitHub(https://github.com/MichaelGrafnetter/DSInternals/releases)에서 최신 모듈 버전의 .zip 아카이브를 다운로드해야 합니다. 이 글을 작성하는 시점의 최신 릴리스는 DSInternals v4.4.1입니다. 다운로드한 아카이브를 PowerShell 모듈 디렉터리 중 하나에 압축 해제하세요:
- C:\Windows\system32\WindowsPowerShell\v1.0\Modules\DSInternals
- C:\Users\%username%\Documents\WindowsPowerShell\Modules\DSInternals
또는 다음 명령으로 현재 PowerShell 세션에 DSInternals 모듈을 직접 가져올 수 있습니다:
Import-Module C:\distr\PS\DSInternals\DSInternals.psd1
모듈을 가져올 때 "cannot be loaded because running scripts is disabled on this system" 오류가 발생하면, PowerShell 실행 정책을 변경하여 최소한 현재 세션에서 외부 스크립트 실행을 허용해야 합니다:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass –Force
모듈에서 사용 가능한 cmdlet 목록은 다음 명령으로 확인할 수 있습니다:
Get-Command -Module DSInternals

Test-PasswordQuality Cmdlet으로 취약한 Active Directory 암호 찾기
다음으로 암호 사전 파일을 준비해야 합니다. 이것은 자주 사용되는 약한 암호와 잘못된 암호들을 나열한 간단한 텍스트 파일입니다. 인터넷에서 암호 사전 파일을 다운로드하거나 직접 만들 수 있습니다. DSInternals 모듈을 사용하면 Active Directory에 저장된 사용자 암호 해시를 이 파일의 단어 해시와 비교할 수 있습니다. 암호 목록을 PasswordDict.txt 텍스트 파일로 저장하세요.

이제 간단한 PowerShell 스크립트를 작성합니다. 아래 변수에 암호 파일 경로, 도메인 이름, 도메인 컨트롤러 이름을 지정하세요:
$DictFile = "C:\distr\PS\DSInternals\PasswordDict.txt"
$DC = "lon-dc01"
$Domain = "DC=woshub,DC=loc"
그런 다음 Get-ADReplAccount cmdlet을 사용하여 AD 사용자 목록을 가져옵니다(Get-ADUser와 유사). 이 cmdlet은 추가로 각 사용자의 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: TEST\DefaultAccount TEST\Guest Passwords of these accounts have been found in the dictionary: TEST\a.adams TEST\jbrion TEST\jsanti These groups of accounts have the same passwords: Group 1: TEST\a.novak TEST\Administrator TEST\amuller TEST\k.brown Group 2: TEST\a.adams TEST\jbrion TEST\jsanti 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: TEST\a.adams TEST\a.novak TEST\Administrator TEST\jbrion TEST\jsanti TEST\k.brown TEST\krbtgt Passwords of these accounts will never expire: TEST\a.adams TEST\Administrator TEST\DefaultAccount TEST\Guest TEST\k.brown TEST\krbtgt TEST\web These accounts are not required to have a password: TEST\ADFS1$ TEST\DefaultAccount TEST\Guest These accounts that require smart card authentication have a password:

이전 버전의 DSInternals 모듈에서는 사전에서 해시가 발견된 경우 사용자 암호를 평문으로 표시하는 ShowPlainText 매개변수가 제공되었습니다. 현재 릴리스의 Test-PasswordQuality에는 이 매개변수가 존재하지 않습니다. 구버전의 DSInternals 모듈을 사용하려면 다음 명령으로 설치하세요:
Install-Module -Name DSInternals -RequiredVersion 2.23
해시 검색은 AD에 저장된 사용자 암호 기록(password history)까지 포함하여 수행됩니다. 실행 결과를 보면 단순한 암호를 사용하는 AD 사용자들이 성공적으로 탐지되었으며(암호가 사전과 일치), 동일한 암호를 공유하는 여러 사용자 그룹도 발견되었습니다. 이 스크립트는 사용자 지정 FGPP(Fine-Grained Password Policy, 세분화된 암호 정책) 대상 계정 중 단순 암호를 사용하는 계정을 찾는 데도 유용합니다.
약한 암호를 사용하는 사용자에게는 강력한 무작위 암호를 생성하고, PowerShell을 통해 AD에서 암호 변경을 강제할 수 있습니다.
ntds.dit 파일 오프라인 검사
Active Directory 데이터베이스 파일(ntds.dit)에 대해 오프라인 스캔을 수행할 수도 있습니다. ntds.dit 파일의 사본은 섀도 복사본(shadow copy)이나 도메인 컨트롤러 백업에서 확보할 수 있습니다.
ntds.dit 파일의 사용자 해시를 오프라인으로 검사하려면 다음 명령을 사용하세요:
$keyboot= Get-BootKey -SystemHiveFilePath 'C:\ADBackup\registry\SYSTEM'
Get-ADDBAccount -All -DatabasePath 'C:\ADBackup\ntds.dit -BootKey $keyboot | Test-PasswordQuality -WeakPasswordsFile $DictFile
전체 해시 목록을 텍스트 파일로 내보낼 수도 있습니다:
Get-ADDBAccount -All -DBPath 'C:\ADBackup\ntds.dit' -Bootkey $keyboot | Format-Custom -View HashcatNT | Out-File c:\ps\ad_hashes.txt -Encoding ASCII
마무리: 암호 보호 정책과 정기적인 감사
Active Directory Domain Services에는 잘못된 암호 목록을 설정하는 내장 도구가 없습니다. 다만 Azure AD 암호 보호(Password Protection)를 활용하면 온프레미스 Active Directory에서도 특정 암호를 차단(블랙리스트)할 수 있습니다.
이 시나리오를 활용하면 AD 사용자 암호의 품질과 무차별 대입(brute force) 공격에 대한 저항성을 손쉽게 분석하고, 현재 도메인 암호 정책의 실효성을 평가하여 필요한 조치를 도출할 수 있습니다. Active Directory 관리자는 이러한 암호 감사를 정기적으로 수행해야 합니다.