Detection rules › Kusto
Process Creation with Suspicious CommandLine Arguments
This analytic rule detects process creation events with base64 encoded command line arguments. This could be an indication of a malicious process being executed.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Execution | T1059 Command and Scripting Interpreter |
| Stealth | T1027 Obfuscated Files or Information |
Event coverage
| Provider | Event | Title |
|---|---|---|
| Sysmon | Event ID 1 | Process creation |
| Sysmon | Event ID 5 | Process terminated |
| Security-Auditing | Event ID 4688 | A new process has been created. |
| Security-Auditing | Event ID 4689 | A process has exited. |
Rule body kusto
id: fdbcc0eb-44fb-467e-a51d-a91df0780a81
name: Process Creation with Suspicious CommandLine Arguments
description: |
This analytic rule detects process creation events with base64 encoded command line arguments. This could be an indication of a malicious process being executed.
severity: Medium
status: Available
tags:
- Schema: _ASim_ProcessEvent
SchemaVersion: 0.1.4
requiredDataConnectors:
- connectorId: CrowdStrikeFalconEndpointProtection
dataTypes:
- CommonSecurityLog
- connectorId: MicrosoftThreatProtection
dataTypes:
- SecurityAlert
- connectorId: SentinelOne
dataTypes:
- SentinelOne_CL
- connectorId: VMwareCarbonBlack
dataTypes:
- CarbonBlackEvents_CL
- connectorId: CiscoSecureEndpoint
dataTypes:
- CiscoSecureEndpoint_CL
- connectorId: TrendMicroApexOne
dataTypes:
- TMApexOneEvent
- connectorId: TrendMicroApexOneAma
dataTypes:
- TMApexOneEvent
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- Execution
- DefenseEvasion
relevantTechniques:
- T1059
- T1027
query: |
_ASim_ProcessEvent
| where EventType == 'ProcessCreated'
| extend CommandLineArgs = strcat_array(array_slice(split(CommandLine, " "), 1, -1), " ")
| where strlen(CommandLineArgs) > 0
| where CommandLineArgs contains "base64"
| project
TimeGenerated,
DvcHostname,
DvcIpAddr,
DvcDomain,
TargetUsername,
TargetUsernameType,
TargetProcessName,
TargetProcessId,
CommandLine
| extend Username = iff(tostring(TargetUsernameType) == 'Windows', tostring(split(TargetUsername, '\\')[1]), TargetUsername)
| extend NTDomain = iff(tostring(TargetUsernameType) == 'Windows', tostring(split(TargetUsername, '\\')[0]), TargetUsername)
| extend Username = iff(tostring(TargetUsernameType) == 'UPN', tostring(split(TargetUsername, '@')[0]), Username)
| extend UPNSuffix = iff(tostring(TargetUsernameType) == 'UPN', tostring(split(TargetUsername, '@')[1]), '')
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: DvcHostname
- identifier: DnsDomain
columnName: DvcDomain
- identifier: NTDomain
columnName: NTDomain
- entityType: IP
fieldMappings:
- identifier: Address
columnName: DvcIpAddr
- entityType: Account
fieldMappings:
- identifier: Name
columnName: Username
- identifier: UPNSuffix
columnName: UPNSuffix
- identifier: NTDomain
columnName: NTDomain
- entityType: Process
fieldMappings:
- identifier: ProcessId
columnName: TargetProcessId
- identifier: CommandLine
columnName: CommandLine
eventGroupingSettings:
aggregationKind: AlertPerResult
alertDetailsOverride:
alertDisplayNameFormat: "Process with suspicious command line arguments was created on {{DvcHostname}} ({{DvcIpAddr}}) by ({{TargetUsername}})"
alertDescriptionFormat: "Process '{{TargetProcessName}}' ProcessId: '{{TargetProcessId}}' with commandline {{CommandLine}} was created."
version: 1.0.1
kind: Scheduled
Stages and Predicates
Stage 1: source
_ASim_ProcessEvent
Stage 2: where
| where EventType == 'ProcessCreated'
Stage 3: extend
| extend CommandLineArgs = strcat_array(array_slice(split(CommandLine, " "), 1, -1), " ")
Stage 4: where
| where strlen(CommandLineArgs) > 0
Stage 5: where
| where CommandLineArgs contains "base64"
Stage 6: project
| project
TimeGenerated,
DvcHostname,
DvcIpAddr,
DvcDomain,
TargetUsername,
TargetUsernameType,
TargetProcessName,
TargetProcessId,
CommandLine
Stage 7: extend (4 consecutive steps)
| extend Username = iff(tostring(TargetUsernameType) == 'Windows', tostring(split(TargetUsername, '\\')[1]), TargetUsername)
| extend NTDomain = iff(tostring(TargetUsernameType) == 'Windows', tostring(split(TargetUsername, '\\')[0]), TargetUsername)
| extend Username = iff(tostring(TargetUsernameType) == 'UPN', tostring(split(TargetUsername, '@')[0]), Username)
| extend UPNSuffix = iff(tostring(TargetUsernameType) == 'UPN', tostring(split(TargetUsername, '@')[1]), '')
Username =TargetUsernameType == "Windows"tostring(split(TargetUsername, '\\')[1])TargetUsernameIndicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
CommandLineArgs | contains |
|
CommandLineArgs | is_not_null | |
EventType | eq |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
CommandLine | project |
DvcDomain | project |
DvcHostname | project |
DvcIpAddr | project |
TargetProcessId | project |
TargetProcessName | project |
TargetUsername | project |
TargetUsernameType | project |
TimeGenerated | project |
Username | extend |
NTDomain | extend |
UPNSuffix | extend |