Query Details

UAC Weakening And Persistence Mechanism Detection

Query

// Detect all three UAC settings being disabled by the same process on one device.
let Lookback = 7d;
let CorrelationWindow = 15m;
let UACWrites = materialize(
	DeviceRegistryEvents
	| where Timestamp >= ago(Lookback)
	| where ActionType == "RegistryValueSet"
	| where RegistryKey endswith @"\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
	| where RegistryValueName in~ (
		"ConsentPromptBehaviorAdmin",
		"PromptOnSecureDesktop",
		"EnableLUA"
	)
	| where tostring(RegistryValueData) in~ ("0", "0x0", "0x00000000", "00000000")
	| where isnotnull(InitiatingProcessId)
	| project
		DeviceId,
		DeviceName,
		Timestamp,
		RegistryValueName,
		InitiatingProcessId,
		InitiatingProcessFileName,
		InitiatingProcessFolderPath,
		InitiatingProcessCommandLine,
		InitiatingProcessSHA1,
		InitiatingProcessAccountName
);
let WindowsServiceHostRunWrites = materialize(
	DeviceRegistryEvents
	| where Timestamp >= ago(Lookback)
	| where ActionType == "RegistryValueSet"
	| where RegistryKey contains @"\Software\Microsoft\Windows\CurrentVersion\Run"
	| where RegistryValueName =~ "Windows Service Host"
	| where RegistryValueData contains "WindowsServiceHost.exe"
	| project
		DeviceId,
		PersistenceTime = Timestamp,
		PersistenceRegistryKey = RegistryKey,
		PersistenceData = RegistryValueData
);
let FirstWrite =
	UACWrites
	| project
		DeviceId,
		DeviceName,
		InitiatingProcessId,
		InitiatingProcessFileName,
		InitiatingProcessFolderPath,
		InitiatingProcessCommandLine,
		InitiatingProcessSHA1,
		InitiatingProcessAccountName,
		FirstTime = Timestamp,
		FirstValue = RegistryValueName;
let SecondWrite =
	UACWrites
	| project
		DeviceId,
		InitiatingProcessId,
		SecondTime = Timestamp,
		SecondValue = RegistryValueName;
let ThirdWrite =
	UACWrites
	| project
		DeviceId,
		InitiatingProcessId,
		ThirdTime = Timestamp,
		ThirdValue = RegistryValueName;
FirstWrite
| join kind=inner (SecondWrite) on DeviceId, InitiatingProcessId
| where SecondTime between (FirstTime .. FirstTime + CorrelationWindow)
| where FirstValue != SecondValue
| join kind=inner (ThirdWrite) on DeviceId, InitiatingProcessId
| where ThirdTime between (FirstTime .. FirstTime + CorrelationWindow)
| where ThirdValue != FirstValue and ThirdValue != SecondValue
| join kind=leftouter (WindowsServiceHostRunWrites) on DeviceId
| summarize
	FirstSeen = min(FirstTime),
	LastSecondWrite = max(SecondTime),
	LastThirdWrite = max(ThirdTime),
	HasWindowsServiceHostRunKey = countif(
		isnotnull(PersistenceTime)
		and PersistenceTime >= FirstTime - 1h
		and PersistenceTime <= FirstTime + CorrelationWindow + 1h
	) > 0,
	RunKeyRegistryPaths = make_set_if(
		PersistenceRegistryKey,
		isnotnull(PersistenceTime)
		and PersistenceTime >= FirstTime - 1h
		and PersistenceTime <= FirstTime + CorrelationWindow + 1h
	),
	RunKeyData = make_set_if(
		PersistenceData,
		isnotnull(PersistenceTime)
		and PersistenceTime >= FirstTime - 1h
		and PersistenceTime <= FirstTime + CorrelationWindow + 1h
	)
	by
		DeviceId,
		DeviceName,
		InitiatingProcessId,
		InitiatingProcessFileName,
		InitiatingProcessFolderPath,
		InitiatingProcessCommandLine,
		InitiatingProcessSHA1,
		InitiatingProcessAccountName
	| extend LastSeen = iif(LastSecondWrite > LastThirdWrite, LastSecondWrite, LastThirdWrite)
| extend Triage = iff(
	HasWindowsServiceHostRunKey,
	"Higher confidence: UAC weakening plus Windows Service Host Run-key persistence",
	"Investigate: correlated UAC weakening; validate against approved deployment activity"
)
| project
	FirstSeen,
	LastSeen,
	DeviceName,
	DeviceId,
	Triage,
	HasWindowsServiceHostRunKey,
	RunKeyRegistryPaths,
	RunKeyData,
	InitiatingProcessFileName,
	InitiatingProcessFolderPath,
	InitiatingProcessCommandLine,
	InitiatingProcessId,
	InitiatingProcessSHA1,
	InitiatingProcessAccountName
| order by FirstSeen desc

About this query

Explanation

This query is designed to detect potential security threats related to User Account Control (UAC) settings being weakened on a Windows device. It specifically looks for the following:

  1. UAC Settings Disabled: The query identifies when three critical UAC registry settings (ConsentPromptBehaviorAdmin, PromptOnSecureDesktop, and EnableLUA) are disabled by the same process on a device within a short time frame (15 minutes). Disabling these settings can allow unauthorized actions to be executed without user consent, which is a common tactic for privilege escalation.

  2. Persistence Mechanism: The query also checks if a registry run key named "Windows Service Host" is created. This is a known technique for maintaining persistence on a system, allowing malicious software to run automatically when the system starts.

  3. Correlation and Risk Assessment: The query correlates the disabling of UAC settings with the creation of the "Windows Service Host" run key. If both actions are detected, it suggests a higher confidence of malicious activity. The results are categorized into two levels of concern:

    • Higher Confidence: Both UAC weakening and the run key creation are observed, indicating a likely security threat.
    • Investigate: Only UAC weakening is observed, which warrants further investigation to rule out legitimate administrative actions.
  4. Output: The query outputs details such as the device name, process information, and timestamps of the detected activities. It also provides a "Triage" field to help prioritize the investigation based on the presence of the run key.

Overall, this query helps security teams identify and respond to potential attempts to bypass security controls and establish persistence on Windows devices.