70 строки
3.3 KiB
YAML
70 строки
3.3 KiB
YAML
id: af02987c-949d-47d5-b0ae-64d8e1b674e2
|
|
name: Rare processes run by Service accounts
|
|
description: |
|
|
'Service accounts normally are supposed to perform a limited set of tasks in a stable environment.
|
|
The query collects a list of service account and then joins them with rare processes in an environment to detect anomalous behaviours.'
|
|
requiredDataConnectors:
|
|
- connectorId: SecurityEvents
|
|
dataTypes:
|
|
- SecurityEvent
|
|
tactics:
|
|
- Execution
|
|
query: |
|
|
|
|
let timeframe = 1d;
|
|
let excludeList = dynamic ( ["NT AUTHORITY","Local System", "Local Service", "Network Service"] );
|
|
let List1 = datatable(AccountName:string)["MSSQLSERVER", "ReportServer", "MSDTSServer100", "IUSR"];
|
|
// Provide a list of service account/ built-in accounts in an environment.
|
|
let List2 = SecurityEvent
|
|
// Self generating a list of Service account using event Id :4624
|
|
| where TimeGenerated >= ago(timeframe)
|
|
| where EventID == 4624
|
|
| where LogonType == "5"
|
|
| where not(Account has_any (excludeList))
|
|
| extend AccountName = Account
|
|
| distinct AccountName;
|
|
let Accounts = List1 | union (List2 | distinct AccountName);
|
|
let ProcessCreationEvents=() {
|
|
let processEvents=SecurityEvent
|
|
| where TimeGenerated >= ago(timeframe)
|
|
| where EventID==4688
|
|
// filter out common randomly named files related to MSI installers and browsers
|
|
| where not(NewProcessName matches regex @"\\TRA[0-9A-Fa-f]{3}\.tmp")
|
|
| where not(NewProcessName matches regex @"\\TRA[0-9A-Fa-f]{4}\.tmp")
|
|
| where not(NewProcessName matches regex @"Installer\\MSI[0-9A-Fa-f]{3}\.tmp")
|
|
| where not(NewProcessName matches regex @"Installer\\MSI[0-9A-Fa-f]{4}\.tmp")
|
|
| project TimeGenerated,
|
|
ComputerName=Computer,
|
|
AccountName=SubjectUserName,
|
|
AccountDomain=SubjectDomainName,
|
|
FileName=tostring(split(NewProcessName, '\\')[-1]),
|
|
ProcessCommandLine = CommandLine,
|
|
InitiatingProcessFileName=ParentProcessName,
|
|
InitiatingProcessCommandLine="",
|
|
InitiatingProcessParentFileName="";
|
|
processEvents;
|
|
};
|
|
let normalizedProcesses = ProcessCreationEvents
|
|
// normalize guids
|
|
| project TimeGenerated, AccountName, FileName = replace("[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}", "<guid>", FileName)
|
|
// normalize digits away
|
|
| project TimeGenerated, AccountName, FileName=replace(@'\d', 'n', FileName);
|
|
let freqs = normalizedProcesses
|
|
| summarize frequency = count() by FileName
|
|
| join kind= leftouter (
|
|
normalizedProcesses
|
|
| summarize Since=min(TimeGenerated), LastSeen=max(TimeGenerated) by FileName, AccountName
|
|
) on FileName;
|
|
let Finalfreqs = freqs
|
|
| where frequency <= toscalar( freqs | serialize | project frequency | summarize percentiles(frequency, 10))
|
|
| order by frequency asc
|
|
| project FileName, frequency, Since, LastSeen , AccountName
|
|
// restrict results to unusual processes seen in last day
|
|
| where LastSeen >= ago(timeframe);
|
|
Accounts
|
|
| join kind= inner (
|
|
Finalfreqs
|
|
) on AccountName
|
|
| where frequency < 10
|
|
| project-away AccountName1
|
|
| extend AccountCustomEntity = AccountName |