Detection rules › Kusto

Modification of Accessibility Features

Severity
medium
Time window
1h
Group by
CommandLine, Computer, CurrentDirectory, Description, EventID, Hashes, Image, OriginalFileName, ParentCommandLine, ParentImage, ParentProcessGuid, ParentUser, ProcessGuid, ProcessId, User
Author
Vasileios Paschalidis
Source
github.com/Azure/Azure-Sentinel

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/

MITRE ATT&CK coverage

Telemetry coverage

ProviderRecord / event type
SysmonEvent ID 1: Process creation

Rule body

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:
  - entityType: Process
    fieldMappings:
      - identifier: CommandLine
        columnName: CommandLine
      - identifier: ProcessId
        columnName: ProcessId
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: HostNameDomain
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: User
      - identifier: Name
        columnName: AccountName
      - identifier: NTDomain
        columnName: AccountNTDomain
  - entityType: File
    fieldMappings:
      - identifier: Name
        columnName: ImageFileName
      - identifier: Directory
        columnName: ImageDirectory
version: 1.0.4
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Vasileios Paschalidis
    support:
        tier: Community
    categories:
        domains: [ "Security - Others" ]

Stages and Predicates

Parameters

let ImagesList = dynamic (["sethc.exe","utilman.exe","osk.exe","Magnify.exe","Narrator.exe","DisplaySwitch.exe","AtBroker.exe"]);

Let binding: OriginalFileNameList used in Stage 4

let OriginalFileNameList = dynamic (["sethc.exe","utilman.exe","osk.exe","Magnify.exe","Narrator.exe","DisplaySwitch.exe","AtBroker.exe","SR.exe","utilman2.exe","ScreenMagnifier.exe"]);

Stage 1: source

Event

Stage 2: where

| where EventLog == "Microsoft-Windows-Sysmon/Operational" and EventID==1

Stage 3: parse

| parse EventData with * 'ProcessId">' ProcessId "<" * 'Image">' Image "<" * 'OriginalFileName">' OriginalFileName "<" *

Stage 4: where

| where Image has_any (ImagesList) and not (OriginalFileName has_any (OriginalFileNameList))

Stage 5: parse

| 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 "<" *

Stage 6: summarize

| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by EventID, Computer, User, ParentImage, ParentProcessGuid, ParentCommandLine, ParentUser, Image, ProcessId, ProcessGuid, CommandLine, Description, OriginalFileName, CurrentDirectory, Hashes

Stage 7: extend (5 consecutive steps)

| 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, "")

Stage 8: project-away

| project-away DomainIndex

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
OriginalFileNamematchsethc.exe, utilman.exe, osk.exe, Magnify.exe, Narrator.exe, DisplaySwitch.exe, AtBroker.exe, SR.exe, utilman2.exe, ScreenMagnifier.exeexcludes:OriginalFileName

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventIDeq
  • 1 corpus 241 (splunk 225, kusto 15, elastic 1)
field:"EventID" kind:eq value:"1"
EventLogeq
  • Microsoft-Windows-Sysmon/Operational corpus 3 (kusto 3)
field:"EventLog" kind:eq value:"Microsoft-Windows-Sysmon/Operational"
Imagematch
  • AtBroker.exe transforms: term
  • DisplaySwitch.exe transforms: term
  • Magnify.exe transforms: term
  • Narrator.exe transforms: term
  • osk.exe transforms: term
  • sethc.exe transforms: term
  • utilman.exe transforms: term
field:"Image" kind:match

Output fields

These fields are emitted when the rule matches.

FieldSource
CommandLinesummarize
Computersummarize
CurrentDirectorysummarize
Descriptionsummarize
EndTimesummarize
EventIDsummarize
Hashessummarize
Imagesummarize
OriginalFileNamesummarize
ParentCommandLinesummarize
ParentImagesummarize
ParentProcessGuidsummarize
ParentUsersummarize
ProcessGuidsummarize
ProcessIdsummarize
StartTimesummarize
Usersummarize
HostNameextend
HostNameDomainextend
AccountNTDomainextend
AccountNameextend
ImageFileNameextend
ImageDirectoryextend