Query Details

Security Event Security Service Registry ACL Modification

Query

let query_frequency = 1h;
let file_names = dynamic(["subinacl.exe","SetACL.exe"]);
let registry_paths = dynamic([
    @"Services\HealthService",
    @"Services\Sense",
    @"Services\WinDefend",
    @"Services\MsSecFlt",
    @"Services\DiagTrack",
    @"Services\SgrmBroker",
    @"Services\SgrmAgent",
    @"Services\AATPSensorUpdater",
    @"Services\AATPSensor",
    @"Services\mpssvc"
]);
let parameters = dynamic([
    @"/deny=SYSTEM",
    @"/deny=S-1-5-18",
    @"/grant=SYSTEM=r",
    @"/grant=S-1-5-18=r",
    @"n:SYSTEM;p:READ",
    @"n1:SYSTEM;ta:remtrst;w:dacl"
]);
union
    (SecurityEvent
    | where TimeGenerated > ago(query_frequency)
    | where EventID == 4688
    | where Process has_any (file_names) and CommandLine has_any (registry_paths) and CommandLine has_any (parameters)
    | project TimeGenerated, Computer, Account, AccountType, SubjectLogonId, TargetAccount, Activity, NewProcessName, CommandLine
),
    (SecurityEvent
    | where TimeGenerated > ago(query_frequency)
    | where EventID == 4670
    | where ObjectType == "Key"
    | mv-apply Auxiliar = parse_xml(EventData)["EventData"]["Data"] on (
        summarize BagToUnpack = make_bag(bag_pack(tostring(Auxiliar["@Name"]), tostring(Auxiliar["#text"])))
        )
    | evaluate bag_unpack(BagToUnpack, columnsConflict="keep_source"): (TimeGenerated: datetime, Computer: string, Account: string, AccountType: string, SubjectLogonId: string, Activity: string, ProcessName: string, ObjectType: string, ObjectName: string, EventData: string, OldSd: string, NewSd: string)
    // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/f4296d69-1c0f-491f-9587-a960b292d070?redirectedfrom=MSDN
    | extend EntryType = substring(OldSd, 0, 1)
    //| where EntryType == "D"
    | extend
        RemovedSd = iff(EntryType in ("O", "G"), split(OldSd, ":", 1), extract_all(@"\(([^\)]+)\)", OldSd)),
        AddedSd = iff(EntryType in ("O", "G"), split(NewSd, ":", 1), extract_all(@"\(([^\)]+)\)", NewSd))
    | extend
        RemovedSd = iff(EntryType in ("O", "G"), RemovedSd, set_difference(RemovedSd, AddedSd)),
        AddedSd = iff(EntryType in ("O", "G"), AddedSd, set_difference(AddedSd, RemovedSd))
    | mv-expand RemovedSd to typeof(string)
    | where RemovedSd endswith "SY"
    | mv-expand AddedSd = iff(array_length(AddedSd) == 0, dynamic([""]), AddedSd) to typeof(string)
    | where isempty(AddedSd) or AddedSd endswith "SY"
    | where case(
            isempty(AddedSd), true, // Local System access was removed
            RemovedSd startswith "A" and AddedSd startswith "D", true, // Local System was denied
            RemovedSd contains "KA" and not(AddedSd contains "KA"), true, // Local System Key All Access was removed
            false
        )
    | project TimeGenerated, Computer, Account, AccountType, SubjectLogonId, Activity, ProcessName, ObjectType, ObjectName, EntryType, OldSd, NewSd, RemovedSd, AddedSd, EventData
)

Explanation

This query is designed to monitor security events in a system. It runs every hour and checks for two specific types of security events (EventID 4688 and 4670).

For EventID 4688, it looks for instances where certain executable files (subinacl.exe, SetACL.exe) have been run, and checks if they have been used to modify certain registry paths. It also checks if certain parameters have been used in the command line. If these conditions are met, it records the time, computer, account, account type, logon ID, target account, activity, new process name, and command line.

For EventID 4670, it checks for changes to key objects. It unpacks the event data and checks if the security descriptor (which defines who can access an object) has been modified. It specifically looks for instances where access by the Local System account has been removed or denied, or where the Local System's full access to a key has been removed. If these conditions are met, it records the time, computer, account, account type, logon ID, activity, process name, object type, object name, entry type, old and new security descriptors, and event data.

In summary, this query is used to monitor for potentially suspicious changes to system access permissions.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: January 25, 2023

Tables

SecurityEvent

Keywords

QueryFrequency,FileNames,RegistryPaths,Parameters,SecurityEvent,TimeGenerated,EventID,Process,CommandLine,Computer,Account,AccountType,SubjectLogonId,TargetAccount,Activity,NewProcessName,ObjectType,Auxiliar,EventData,BagToUnpack,OldSd,NewSd,EntryType,RemovedSd,AddedSd

Operators

| unionwhereprojectmv-applyparse_xmlsummarizemake_bagbag_packtostringevaluatebag_unpackextendsubstringiffsplitextract_allset_differencemv-expandendswitharray_lengthisemptystartswithcontainscase

Actions