Detection rules › Kusto

Unsigned Windows System Binary

Group by
DeviceId, FolderPath, SHA1
Author
FalconForce
Source
github.com/FalconForceTeam/FalconFriday

This query searches for invocations of a number of commonly used and signed Windows binaries. It then finds invocations of these binaries where they are not properly signed.

Known false positives

  • In case a legitimate software package uses a file name that is the same as that of a known system binary, this rule may trigger.

MITRE ATT&CK coverage

References

Telemetry coverage

Rule body

let timeframe = 2*1h;
let default_global_prevalence = 0;
let signedSystemFiles = dynamic(["aitstatic.exe", "ApplicationFrameHost.exe", "ApplyTrustOffline.exe", "AppVClient.exe", "AppVDllSurrogate.exe", "AppVNice.exe", "AppVShNotify.exe", "audiodg.exe", "AuthHost.exe", "backgroundTaskHost.exe", "bcdedit.exe", "bdeunlock.exe", "BioIso.exe", "bootsect.exe", "browser_broker.exe", "CameraSettingsUIHost.exe", "CastSrv.exe", "CExecSvc.exe", "changepk.exe", "ClipRenew.exe", "ClipUp.exe", "CloudExperienceHostBroker.exe", "CloudNotifications.exe", "cmdiag.exe", "CompatTelRunner.exe", "consent.exe", "convertvhd.exe", "CredentialEnrollmentManager.exe", "CredentialUIBroker.exe", "csrss.exe", "DataExchangeHost.exe", "DeviceCensus.exe", "Dism.exe", "DisplaySwitch.exe", "dllhost.exe", "DTUHandler.exe", "easinvoker.exe", "ErgonomicKBNotificationService.exe", "fontdrvhost.exe", "FsIso.exe", "fsutil.exe", "GenValObj.exe", "hcsdiag.exe", "hvax64.exe", "hvc.exe", "hvix64.exe", "hvsievaluator.exe", "hvsimgr.exe", "hvsirdpclient.exe", "hvsirpcd.exe", "HvsiSettingsWorker.exe", "iotstartup.exe", "LicensingUI.exe", "LockAppHost.exe", "LockScreenContentServer.exe", "LsaIso.exe", "lsass.exe", "mavinject.exe", "mfpmp.exe", "MRT.exe", "MusNotifyIcon.exe", "NDKPing.exe", "NgcIso.exe", "nmbind.exe", "nmscrub.exe", "ntoskrnl.exe", "nvspinfo.exe", "OpenWith.exe", "PasswordOnWakeSettingFlyout.exe", "phoneactivate.exe", "PickerHost.exe", "PktMon.exe", "ProximityUxHost.exe", "prproc.exe", "ResetEngine.exe", "RuntimeBroker.exe", "ScriptRunner.exe", "securekernel.exe", "SecurityHealthHost.exe", "SecurityHealthService.exe", "services.exe", "sessionmsg.exe", "SettingSyncHost.exe", "SgrmBroker.exe", "SgrmLpac.exe", "SIHClient.exe", "SlideToShutDown.exe", "smss.exe", "SndVol.exe", "spaceman.exe", "sppsvc.exe", "svchost.exe", "SyncAppvPublishingServer.exe", "SysResetErr.exe", "systemreset.exe", "SystemSettingsAdminFlows.exe", "SystemSettingsBroker.exe", "SystemSettingsRemoveDevice.exe", "taskhostw.exe", "Taskmgr.exe", "tcblaunch.exe", "ttdinject.exe", "tttracer.exe", "ucsvc.exe", "upfc.exe", "UserAccountBroker.exe", "verifier.exe", "vmcompute.exe", "VmComputeAgent.exe", "vmms.exe", "vmplatformca.exe", "vmsp.exe", "vmwp.exe", "wcsetupagent.exe", "WerFault.exe", "WerFaultSecure.exe", "wermgr.exe", "wifitask.exe", "wimserv.exe", "wininit.exe", "winload.exe", "winresume.exe", "wkspbroker.exe", "wlrmdr.exe", "WpcMon.exe", "wuauclt.exe", "WUDFCompanionHost.exe", "WWAHost.exe", "AdtAgent.exe", "appverif.exe", "iaStorAfsNative.exe", "iaStorAfsService.exe", "MCU.exe", "microsoft.windows.softwarelogo.showdesktop.exe", "MpSigStub.exe", "RtkAudUService64.exe", "TsWpfWrp.exe"]);
let uniqueHashes = materialize(
    DeviceProcessEvents
    | where ingestion_time() >= ago(timeframe)
    | where ActionType =~ "ProcessCreated"
    | where FileName in~ (signedSystemFiles) and not(isempty(SHA1))
    // Begin environment-specific filter.
    // End environment-specific filter.
    // FileProfile is case sensistive and works on lower-case hashes
    | extend SHA1=tolower(SHA1)
    | summarize  MachineCount=dcount(DeviceId) by SHA1
);
let unsignedHashes = materialize(
    uniqueHashes
    // Take 1000 of the most unique hashes as files with high prevelance are very likely to be signed in a legit manner.
    | top 1000 by MachineCount asc
    // FileProfile is case-sensitive and works on lower-case hashes.
    | extend SHA1=tolower(SHA1)
    | invoke FileProfile(SHA1, 1000)
    | where not(ProfileAvailability =~ "Error")
    | where IsCertificateValid != 1 or (IsRootSignerMicrosoft != 1 and coalesce(GlobalPrevalence,default_global_prevalence) < 200)
    | where not(SignatureState =~ "Unknown" and coalesce(GlobalPrevalence,default_global_prevalence) > 30000) // Workaround for a bug in MDE that reports some valid MS signed files as 'Unknown'.
);
DeviceProcessEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType =~ "ProcessCreated"
| where SHA1 in~ ((unsignedHashes | project SHA1)) // This is for performance improvement.
| join kind=inner unsignedHashes on SHA1
| summarize arg_min(Timestamp, *) by DeviceId, FolderPath // Show only the first invocation per device.

Stages and Predicates

Parameters

let timeframe = 2*1h;
let default_global_prevalence = 0;

Let binding: signedSystemFiles

let signedSystemFiles = dynamic(["aitstatic.exe", "ApplicationFrameHost.exe", "ApplyTrustOffline.exe", "AppVClient.exe", "AppVDllSurrogate.exe", "AppVNice.exe", "AppVShNotify.exe", "audiodg.exe", "AuthHost.exe", "backgroundTaskHost.exe", "bcdedit.exe", "bdeunlock.exe", "BioIso.exe", "bootsect.exe", "browser_broker.exe", "CameraSettingsUIHost.exe", "CastSrv.exe", "CExecSvc.exe", "changepk.exe", "ClipRenew.exe", "ClipUp.exe", "CloudExperienceHostBroker.exe", "CloudNotifications.exe", "cmdiag.exe", "CompatTelRunner.exe", "consent.exe", "convertvhd.exe", "CredentialEnrollmentManager.exe", "CredentialUIBroker.exe", "csrss.exe", "DataExchangeHost.exe", "DeviceCensus.exe", "Dism.exe", "DisplaySwitch.exe", "dllhost.exe", "DTUHandler.exe", "easinvoker.exe", "ErgonomicKBNotificationService.exe", "fontdrvhost.exe", "FsIso.exe", "fsutil.exe", "GenValObj.exe", "hcsdiag.exe", "hvax64.exe", "hvc.exe", "hvix64.exe", "hvsievaluator.exe", "hvsimgr.exe", "hvsirdpclient.exe", "hvsirpcd.exe", "HvsiSettingsWorker.exe", "iotstartup.exe", "LicensingUI.exe", "LockAppHost.exe", "LockScreenContentServer.exe", "LsaIso.exe", "lsass.exe", "mavinject.exe", "mfpmp.exe", "MRT.exe", "MusNotifyIcon.exe", "NDKPing.exe", "NgcIso.exe", "nmbind.exe", "nmscrub.exe", "ntoskrnl.exe", "nvspinfo.exe", "OpenWith.exe", "PasswordOnWakeSettingFlyout.exe", "phoneactivate.exe", "PickerHost.exe", "PktMon.exe", "ProximityUxHost.exe", "prproc.exe", "ResetEngine.exe", "RuntimeBroker.exe", "ScriptRunner.exe", "securekernel.exe", "SecurityHealthHost.exe", "SecurityHealthService.exe", "services.exe", "sessionmsg.exe", "SettingSyncHost.exe", "SgrmBroker.exe", "SgrmLpac.exe", "SIHClient.exe", "SlideToShutDown.exe", "smss.exe", "SndVol.exe", "spaceman.exe", "sppsvc.exe", "svchost.exe", "SyncAppvPublishingServer.exe", "SysResetErr.exe", "systemreset.exe", "SystemSettingsAdminFlows.exe", "SystemSettingsBroker.exe", "SystemSettingsRemoveDevice.exe", "taskhostw.exe", "Taskmgr.exe", "tcblaunch.exe", "ttdinject.exe", "tttracer.exe", "ucsvc.exe", "upfc.exe", "UserAccountBroker.exe", "verifier.exe", "vmcompute.exe", "VmComputeAgent.exe", "vmms.exe", "vmplatformca.exe", "vmsp.exe", "vmwp.exe", "wcsetupagent.exe", "WerFault.exe", "WerFaultSecure.exe", "wermgr.exe", "wifitask.exe", "wimserv.exe", "wininit.exe", "winload.exe", "winresume.exe", "wkspbroker.exe", "wlrmdr.exe", "WpcMon.exe", "wuauclt.exe", "WUDFCompanionHost.exe", "WWAHost.exe", "AdtAgent.exe", "appverif.exe", "iaStorAfsNative.exe", "iaStorAfsService.exe", "MCU.exe", "microsoft.windows.softwarelogo.showdesktop.exe", "MpSigStub.exe", "RtkAudUService64.exe", "TsWpfWrp.exe"]);

Let binding: uniqueHashes used in Stage 1

let uniqueHashes = materialize(
    DeviceProcessEvents
    | where ingestion_time() >= ago(timeframe)
    | where ActionType =~ "ProcessCreated"
    | where FileName in~ (signedSystemFiles) and not(isempty(SHA1))
    | extend SHA1=tolower(SHA1)
    | summarize  MachineCount=dcount(DeviceId) by SHA1
);

Let binding: unsignedHashes used in Stages 2, 7

let unsignedHashes = materialize(
    uniqueHashes
    | top 1000 by MachineCount asc
    | extend SHA1=tolower(SHA1)
    | invoke FileProfile(SHA1, 1000)
    | where not(ProfileAvailability =~ "Error")
    | where IsCertificateValid != 1 or (IsRootSignerMicrosoft != 1 and coalesce(GlobalPrevalence,default_global_prevalence) < 200)
    | where not(SignatureState =~ "Unknown" and coalesce(GlobalPrevalence,default_global_prevalence) > 30000)
);

Stage 1: source

let uniqueHashes

Stage 2: source

let unsignedHashes

Stage 3: source

DeviceProcessEvents

Stage 4: where

where ...

Stage 5: where

where ActionType =~ "ProcessCreated"

Stage 6: where

where /* macro: (SHA1 in~ <NestedQuery>) */

Stage 7: join

join kind=inner (unsignedHashes) on SHA1

Stage 8: summarize

summarize by DeviceId, FolderPath

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
GlobalPrevalencegt30000excludes:GlobalPrevalence field:"GlobalPrevalence" value:"30000"
SignatureStateeqUnknownexcludes:SignatureState field:"SignatureState" value:"Unknown"
ProfileAvailabilityeqErrorexcludes:ProfileAvailability field:"ProfileAvailability" value:"Error"
SHA1is_null(no value, null check)excludes:SHA1

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
ActionTypeeq
  • ProcessCreated
field:"ActionType" kind:eq value:"ProcessCreated"
FileNamein
  • AdtAgent.exe
  • AppVClient.exe
  • AppVDllSurrogate.exe
  • AppVNice.exe
  • AppVShNotify.exe
  • ApplicationFrameHost.exe
  • ApplyTrustOffline.exe
  • AuthHost.exe
  • BioIso.exe
  • CExecSvc.exe
  • CameraSettingsUIHost.exe
  • CastSrv.exe
  • ClipRenew.exe
  • ClipUp.exe
  • CloudExperienceHostBroker.exe
  • CloudNotifications.exe
  • CompatTelRunner.exe
  • CredentialEnrollmentManager.exe
  • CredentialUIBroker.exe
  • DTUHandler.exe
  • DataExchangeHost.exe
  • DeviceCensus.exe
  • Dism.exe
  • DisplaySwitch.exe
  • ErgonomicKBNotificationService.exe
  • FsIso.exe
  • GenValObj.exe
  • HvsiSettingsWorker.exe
  • LicensingUI.exe
  • LockAppHost.exe
  • LockScreenContentServer.exe
  • LsaIso.exe
  • MCU.exe
  • MRT.exe
  • MpSigStub.exe
  • MusNotifyIcon.exe
  • NDKPing.exe
  • NgcIso.exe
  • OpenWith.exe
  • PasswordOnWakeSettingFlyout.exe
  • +97 more values (see full rule source)
field:"file_name" kind:in
GlobalPrevalencelt
  • 200 transforms: coalesce_default:0
field:"GlobalPrevalence" kind:lt value:"200"
IsCertificateValidne
  • 1
field:"IsCertificateValid" kind:ne value:"1"
IsRootSignerMicrosoftne
  • 1
field:"IsRootSignerMicrosoft" kind:ne value:"1"

Output fields

These fields are emitted when the rule matches.

FieldSource
DeviceIdsummarize
FolderPathsummarize