Adversaries may exploit accessibility features to execute malicious code and maintain persistence by triggering automated actions. SOC teams should proactively hunt for this behavior in Azure Sentinel to detect and mitigate potential privilege escalation and persistence tactics.
KQL Query
let ImagesList = dynamic (["sethc.exe","utilman.exe","osk.exe","Magnify.exe","Narrator.exe","DisplaySwitch.exe","AtBroker.exe"]);
let OriginalFileNameList = dynamic (["sethc.exe","utilman.exe","osk.exe","Magnify.exe","Narrator.exe","DisplaySwitch.exe","AtBroker.exe","SR.exe","utilman2.exe","ScreenMagnifier.exe"]);
Event
| where EventLog == "Microsoft-Windows-Sysmon/Operational" and EventID==1
| parse EventData with * 'ProcessId">' ProcessId "<" * 'Image">' Image "<" * 'OriginalFileName">' OriginalFileName "<" *
| where Image has_any (ImagesList) and not (OriginalFileName has_any (OriginalFileNameList))
| parse EventData with * 'ProcessGuid">' ProcessGuid "<" * 'Description">' Description "<" * 'CommandLine">' CommandLine "<" * 'CurrentDirectory">' CurrentDirectory "<" * 'User">' User "<" * 'LogonGuid">' LogonGuid "<" * 'Hashes">' Hashes "<" * 'ParentProcessGuid">' ParentProcessGuid "<" * 'ParentImage">' ParentImage "<" * 'ParentCommandLine">' ParentCommandLine "<" * 'ParentUser">' ParentUser "<" *
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by EventID, Computer, User, ParentImage, ParentProcessGuid, ParentCommandLine, ParentUser, Image, ProcessId, ProcessGuid, CommandLine, Description, OriginalFileName, CurrentDirectory, Hashes
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| extend AccountName = tostring(split(User, "\\")[1]), AccountNTDomain = tostring(split(User, "\\")[0])
| extend ImageFileName = tostring(split(Image, "\\")[-1])
| extend ImageDirectory = replace_string(Image, ImageFileName, "")
| project-away DomainIndex
id: d714ef62-1a56-4779-804f-91c4158e528d
name: Modification of Accessibility Features
description: |
'Adversaries may establish persistence and/or elevate privileges by executing malicious content triggered by accessibility features. Windows contains accessibility features that may be launched with a key combination before a user has logged in (ex: when the user is on the Windows logon screen). An adversary can modify the way these programs are launched to get a command prompt or backdoor without logging in to the system.
Two common accessibility programs are C:\Windows\System32\sethc.exe, launched when the shift key is pressed five times and C:\Windows\System32\utilman.exe, launched when the Windows + U key combination is pressed. The sethc.exe program is often referred to as "sticky keys", and has been used by adversaries for unauthenticated access through a remote desktop login screen. [1]
Ref: https://attack.mitre.org/techniques/T1546/008/'
severity: Medium
requiredDataConnectors:
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- Persistence
relevantTechniques:
- T1546.008
query: |
let ImagesList = dynamic (["sethc.exe","utilman.exe","osk.exe","Magnify.exe","Narrator.exe","DisplaySwitch.exe","AtBroker.exe"]);
let OriginalFileNameList = dynamic (["sethc.exe","utilman.exe","osk.exe","Magnify.exe","Narrator.exe","DisplaySwitch.exe","AtBroker.exe","SR.exe","utilman2.exe","ScreenMagnifier.exe"]);
Event
| where EventLog == "Microsoft-Windows-Sysmon/Operational" and EventID==1
| parse EventData with * 'ProcessId">' ProcessId "<" * 'Image">' Image "<" * 'OriginalFileName">' OriginalFileName "<" *
| where Image has_any (ImagesList) and not (OriginalFileName has_any (OriginalFileNameList))
| parse EventData with * 'ProcessGuid">' ProcessGuid "<" * 'Description">' Description "<" * 'CommandLine">' CommandLine "<" * 'CurrentDirectory">' CurrentDirectory "<" * 'User">' User "<" * 'LogonGuid">' LogonGuid "<" * 'Hashes">' Hashes "<" * 'ParentProcessGuid">' ParentProcessGuid "<" * 'ParentImage">' ParentImage "<" * 'ParentCommandLine">' ParentCommandLine "<" * 'ParentUser">' ParentUser "<" *
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by EventID, Computer, User, ParentImage, ParentProcessGuid, ParentCommandLine, ParentUser, Image, ProcessId, ProcessGuid, CommandLine, Description, OriginalFileName, CurrentDirectory, Hashes
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| extend AccountName = tostring(split(User, "\\")[1]), AccountNTDomain = tostring(split(User, "\\")[0])
| extend ImageFileName = tostring(split(Image, "\\")[-1])
| extend ImageDirectory = replace_string(Image, ImageFileName, "")
| project-away DomainIndex
entityMappings:
- ent
Scenario: Legitimate Accessibility Feature Configuration via Group Policy
Description: An administrator configures accessibility settings (e.g., Narrator, Magnifier) through Group Policy to assist users with disabilities.
Filter/Exclusion: process.parent_process_name == "gpedit.msc" OR process.parent_process_name == "mmc.exe" AND process.parent_process_name_contains("Group Policy")
Scenario: Scheduled Task for Accessibility Tool Maintenance
Description: A scheduled task runs a legitimate accessibility tool (e.g., Microsoft Accessibility Checker) to update or maintain accessibility settings.
Filter/Exclusion: process.name == "AccessibilityChecker.exe" AND process.parent_process_name == "schtasks.exe"
Scenario: User-Initiated Accessibility Feature Activation
Description: A user manually enables an accessibility feature (e.g., Sticky Keys) through the Control Panel or Settings.
Filter/Exclusion: process.name == "control.exe" OR process.name == "ms-settings.exe" AND process.command_line_contains("Accessibility")
Scenario: System-Wide Accessibility Settings Update via PowerShell
Description: An admin uses PowerShell to update accessibility settings across the domain (e.g., using Set-WindowsAccessibility).
Filter/Exclusion: process.name == "powershell.exe" AND process.command_line_contains("Set-WindowsAccessibility")
Scenario: Accessibility Tool Used for Accessibility Testing
Description: A QA team uses a third-party accessibility testing tool (e.g., WAVE, axe) to audit web content for compliance.
Filter/Exclusion: process.name == "wave.exe" OR process.name == "axe.exe" AND process.parent_process_name == "explorer.exe" OR process.parent_process_name == "chrome.exe"