Detection rules › Kusto
Rename System Utilities
Attackers often use LOLBINs that are renamed to avoid detection rules that are based on filenames. This rule detects renamed LOLBINs by first searching for all the known SHA1 hashes of the LOLBINs in your DeviceProcessEvents. This list is then used as reference to find other files executed which have a name that doesn't match the original filename. This query is really heavy on resources. Use it with care.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Microsoft Defender for Endpoint | DeviceProcessEvents action any: Process activity |
Rule body
id: 335ddff8-b615-42cd-b593-86e419b45d78
name: Rename System Utilities
description: |
Attackers often use LOLBINs that are renamed to avoid detection rules that are based on filenames.
This rule detects renamed LOLBINs by first searching for all the known SHA1 hashes of the LOLBINs in your DeviceProcessEvents. This list is then used as reference to find other files executed which have a name that doesn't match the original filename.
This query is really heavy on resources. Use it with care.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceProcessEvents
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- DefenseEvasion
relevantTechniques:
- T1036.003
query: |
// Removed update.exe as LOLBIN. It's a way too generic name and causes a lot of noise.
let lolbin = dynamic(["At.exe", "Atbroker.exe", "Bash.exe", "Bitsadmin.exe", "CertReq.exe", "Certutil.exe", "Cmd.exe", "Cmdkey.exe", "Cmstp.exe", "Control.exe", "Csc.exe", "Cscript.exe", "Desktopimgdownldr.exe", "Dfsvc.exe", "Diantz.exe", "Diskshadow.exe", "Dnscmd.exe", "Esentutl.exe", "Eventvwr.exe", "Expand.exe", "Extexport.exe", "Extrac32.exe", "Findstr.exe", "Forfiles.exe", "Ftp.exe", "GfxDownloadWrapper.exe", "Gpscript.exe", "Hh.exe", "Ie4uinit.exe", "Ieexec.exe", "Ilasm.exe", "Infdefaultinstall.exe", "Installutil.exe", "Jsc.exe", "Makecab.exe", "Mavinject.exe", "Microsoft.Workflow.Compiler.exe", "Mmc.exe", "MpCmdRun.exe", "Msbuild.exe", "Msconfig.exe", "Msdt.exe", "Mshta.exe", "Msiexec.exe", "Netsh.exe", "Odbcconf.exe", "Pcalua.exe", "Pcwrun.exe", "Pktmon.exe", "Presentationhost.exe", "Print.exe", "Psr.exe", "Rasautou.exe", "Reg.exe", "Regasm.exe", "Regedit.exe", "Regini.exe", "Register-cimprovider.exe", "Regsvcs.exe", "Regsvr32.exe", "Replace.exe", "Rpcping.exe", "Rundll32.exe", "Runonce.exe", "Runscripthelper.exe", "Sc.exe", "Schtasks.exe", "Scriptrunner.exe", "SyncAppvPublishingServer.exe", "Ttdinject.exe", "Tttracer.exe", "vbc.exe", "Verclsid.exe", "Wab.exe", "Wmic.exe", "Wscript.exe", "Wsreset.exe", "Xwizard.exe", "AgentExecutor.exe", "Appvlp.exe", "Bginfo.exe", "Cdb.exe", "csi.exe", "Devtoolslauncher.exe", "dnx.exe", "Dotnet.exe", "Dxcap.exe", "Excel.exe", "Mftrace.exe", "Msdeploy.exe", "msxsl.exe", "ntdsutil.exe", "Powerpnt.exe", "rcsi.exe", "Sqldumper.exe", "Sqlps.exe", "SQLToolsPS.exe", "Squirrel.exe", "te.exe", "Tracker.exe", "vsjitdebugger.exe", "Winword.exe", "Wsl.exe"]);
let allHashesLolbin = materialize(
DeviceProcessEvents
| where FileName in~ (lolbin) and not(isempty(SHA1))
| extend OriginalFilename = tolower(FileName)
| summarize by SHA1, OriginalFilename);
allHashesLolbin
| join kind=inner hint.strategy = broadcast DeviceProcessEvents on SHA1
| where FileName !~ OriginalFilename
| where not(OriginalFilename =~ "bash.exe" and FileName =~ "sh.exe")
| extend message=strcat("Usage of ", OriginalFilename, ". Renamed as ", FileName)
| project-reorder message
entityMappings:
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: DeviceName
- entityType: Account
fieldMappings:
- identifier: Sid
columnName: AccountSid
- identifier: Name
columnName: AccountName
- identifier: NTDomain
columnName: AccountDomain
- entityType: Process
fieldMappings:
- identifier: CommandLine
columnName: ProcessCommandLine
version: 1.0.0
kind: Scheduled
Stages and Predicates
let allHashesLolbin is inlined into the numbered stages below.
Let binding: lolbin
let lolbin = dynamic(["At.exe", "Atbroker.exe", "Bash.exe", "Bitsadmin.exe", "CertReq.exe", "Certutil.exe", "Cmd.exe", "Cmdkey.exe", "Cmstp.exe", "Control.exe", "Csc.exe", "Cscript.exe", "Desktopimgdownldr.exe", "Dfsvc.exe", "Diantz.exe", "Diskshadow.exe", "Dnscmd.exe", "Esentutl.exe", "Eventvwr.exe", "Expand.exe", "Extexport.exe", "Extrac32.exe", "Findstr.exe", "Forfiles.exe", "Ftp.exe", "GfxDownloadWrapper.exe", "Gpscript.exe", "Hh.exe", "Ie4uinit.exe", "Ieexec.exe", "Ilasm.exe", "Infdefaultinstall.exe", "Installutil.exe", "Jsc.exe", "Makecab.exe", "Mavinject.exe", "Microsoft.Workflow.Compiler.exe", "Mmc.exe", "MpCmdRun.exe", "Msbuild.exe", "Msconfig.exe", "Msdt.exe", "Mshta.exe", "Msiexec.exe", "Netsh.exe", "Odbcconf.exe", "Pcalua.exe", "Pcwrun.exe", "Pktmon.exe", "Presentationhost.exe", "Print.exe", "Psr.exe", "Rasautou.exe", "Reg.exe", "Regasm.exe", "Regedit.exe", "Regini.exe", "Register-cimprovider.exe", "Regsvcs.exe", "Regsvr32.exe", "Replace.exe", "Rpcping.exe", "Rundll32.exe", "Runonce.exe", "Runscripthelper.exe", "Sc.exe", "Schtasks.exe", "Scriptrunner.exe", "SyncAppvPublishingServer.exe", "Ttdinject.exe", "Tttracer.exe", "vbc.exe", "Verclsid.exe", "Wab.exe", "Wmic.exe", "Wscript.exe", "Wsreset.exe", "Xwizard.exe", "AgentExecutor.exe", "Appvlp.exe", "Bginfo.exe", "Cdb.exe", "csi.exe", "Devtoolslauncher.exe", "dnx.exe", "Dotnet.exe", "Dxcap.exe", "Excel.exe", "Mftrace.exe", "Msdeploy.exe", "msxsl.exe", "ntdsutil.exe", "Powerpnt.exe", "rcsi.exe", "Sqldumper.exe", "Sqlps.exe", "SQLToolsPS.exe", "Squirrel.exe", "te.exe", "Tracker.exe", "vsjitdebugger.exe", "Winword.exe", "Wsl.exe"]);
Stage 1: source
let allHashesLolbin
Stage 2: source
DeviceProcessEvents
Stage 3: where
where not (isempty(SHA1)) and FileName in~ ("AgentExecutor.exe", "Appvlp.exe", "At.exe", "Atbroker.exe", "Bash.exe", "Bginfo.exe", "Bitsadmin.exe", "Cdb.exe", "CertReq.exe", "Certutil.exe", "Cmd.exe", "Cmdkey.exe", "Cmstp.exe", "Control.exe", "Csc.exe", "Cscript.exe", "Desktopimgdownldr.exe", "Devtoolslauncher.exe", "Dfsvc.exe", "Diantz.exe", "Diskshadow.exe", "Dnscmd.exe", "Dotnet.exe", "Dxcap.exe", "Esentutl.exe", "Eventvwr.exe", "Excel.exe", "Expand.exe", "Extexport.exe", "Extrac32.exe", "Findstr.exe", "Forfiles.exe", "Ftp.exe", "GfxDownloadWrapper.exe", "Gpscript.exe", "Hh.exe", "Ie4uinit.exe", "Ieexec.exe", "Ilasm.exe", "Infdefaultinstall.exe", "Installutil.exe", "Jsc.exe", "Makecab.exe", "Mavinject.exe", "Mftrace.exe", "Microsoft.Workflow.Compiler.exe", "Mmc.exe", "MpCmdRun.exe", "Msbuild.exe", "Msconfig.exe", "Msdeploy.exe", "Msdt.exe", "Mshta.exe", "Msiexec.exe", "Netsh.exe", "Odbcconf.exe", "Pcalua.exe", "Pcwrun.exe", "Pktmon.exe", "Powerpnt.exe", "Presentationhost.exe", "Print.exe", "Psr.exe", "Rasautou.exe", "Reg.exe", "Regasm.exe", "Regedit.exe", "Regini.exe", "Register-cimprovider.exe", "Regsvcs.exe", "Regsvr32.exe", "Replace.exe", "Rpcping.exe", "Rundll32.exe", "Runonce.exe", "Runscripthelper.exe", "SQLToolsPS.exe", "Sc.exe", "Schtasks.exe", "Scriptrunner.exe", "Sqldumper.exe", "Sqlps.exe", "Squirrel.exe", "SyncAppvPublishingServer.exe", "Tracker.exe", "Ttdinject.exe", "Tttracer.exe", "Verclsid.exe", "Wab.exe", "Winword.exe", "Wmic.exe", "Wscript.exe", "Wsl.exe", "Wsreset.exe", "Xwizard.exe", "csi.exe", "dnx.exe", "msxsl.exe", "ntdsutil.exe", "rcsi.exe", "te.exe", "vbc.exe", "vsjitdebugger.exe")
Stage 4: extend
extend OriginalFilename
Stage 5: summarize
summarize by SHA1, OriginalFilename
Stage 6: join
join kind=inner (DeviceProcessEvents) on SHA1
Stage 7: where
where FileName != OriginalFilename
Stage 8: where
where not ((FileName =~ "sh.exe" and OriginalFilename =~ "bash.exe"))
Stage 9: extend
extend message
Stage 10: project-reorder
project-reorder
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
SHA1 | is_null | excludes:SHA1 | |
FileName | eq | sh.exe | excludes:FileName field:"FileName" value:"sh.exe" |
OriginalFilename | eq | bash.exe | excludes:OriginalFilename field:"OriginalFilename" value:"bash.exe" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
FileName | cross_field_compare |
| field:"file_name" kind:cross_field_compare value:"OriginalFilename" |
FileName | in |
| field:"file_name" kind:in |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
OriginalFilename | summarize |
SHA1 | summarize |
message | extend |