Detection rules › Kusto
Potential Kerberos Relaying Activity - MDE
The below query detects potential Kerberos relaying event chain generated by KrbRelay.
References
Event coverage
| Provider | Event/ActionType | Title |
|---|---|---|
| Sysmon | Event ID 1 | Process creation |
| Security-Auditing | Event ID 4688 | A new process has been created. |
| Security-Auditing | Event ID 5156 | The Windows Filtering Platform has permitted a connection. |
| Defender-DeviceProcessEvents | ProcessCreated | Process created |
Rule body kusto
// Author : Cyb3rMonk(https://twitter.com/Cyb3rMonk, https://mergene.medium.com)
//
// Link to original post:
// https://posts.bluraven.io/detecting-kerberos-relaying-e6be66fa647c
//
// Description: This query detects potential Kerberos relaying event chain generated by KrbRelay(https://github.com/cube0x0/KrbRelay).
//
// Query parameters:
//
union DeviceProcessEvents, DeviceEvents, DeviceNetworkEvents
| where Timestamp > ago(60m)
| extend PipeName_ = tostring(todynamic(AdditionalFields).PipeName)
| extend Action = case(
(ActionType=="ConnectionSuccess" and RemotePort in (389, 636)), 'ConnectToDC',
(ActionType=="ListeningConnectionCreated"), 'ListeningConnectionCreated',
(ActionType=="NamedPipeEvent" and PipeName_ has @"Winsock2\CatalogChangeListener"), 'NamedPipeEvent',
(ActionType=="ProcessCreated" and InitiatingProcessCommandLine == "svchost.exe -k DcomLaunch -p"), 'DcomProcessCreated',
(ActionType=="ConnectionSuccess" and LocalIP==RemoteIP and InitiatingProcessParentFileName=="svchost.exe"), 'DcomProcessConnecToSelf', 'Other'
)
| summarize Actions = make_set_if(Action, Action <> "Other") by DeviceId, DeviceName, bin(Timestamp,20s)
| where array_length(Actions)==5
| project-rename ActivityTimestamp = Timestamp
| join kind=inner (
DeviceProcessEvents
| where Timestamp > ago(60m)
| where ActionType=="ProcessCreated" and InitiatingProcessCommandLine == "svchost.exe -k DcomLaunch -p"
) on DeviceId
| where abs(datetime_diff('second', Timestamp, ActivityTimestamp)) <=20
union DeviceProcessEvents, DeviceEvents, DeviceNetworkEvents
| where Timestamp > ago(60m)
| extend PipeName_ = tostring(todynamic(AdditionalFields).PipeName)
| where
(ActionType=="ConnectionSuccess" and RemotePort in (389, 636)) or
(ActionType=="ListeningConnectionCreated") or
(ActionType=="NamedPipeEvent" and PipeName_ has @"Winsock2\CatalogChangeListener") or
(ActionType=="ProcessCreated" and InitiatingProcessCommandLine == "svchost.exe -k DcomLaunch -p") or
(ActionType=="ConnectionSuccess" and LocalIP==RemoteIP and InitiatingProcessParentFileName=="svchost.exe")
| sort by Timestamp desc
Stages and Predicates
Stage 1: union
union
Stage 2: source
DeviceProcessEvents
Stage 3: source
DeviceEvents
Stage 4: source
DeviceNetworkEvents
Stage 5: where time_window=3600s
| where Timestamp > ago(60m)
Stage 6: extend
| extend PipeName_ = tostring(todynamic(AdditionalFields).PipeName)
Stage 7: extend
| extend Action = case(
(ActionType=="ConnectionSuccess" and RemotePort in (389, 636)), 'ConnectToDC',
(ActionType=="ListeningConnectionCreated"), 'ListeningConnectionCreated',
(ActionType=="NamedPipeEvent" and PipeName_ has @"Winsock2\CatalogChangeListener"), 'NamedPipeEvent',
(ActionType=="ProcessCreated" and InitiatingProcessCommandLine == "svchost.exe -k DcomLaunch -p"), 'DcomProcessCreated',
(ActionType=="ConnectionSuccess" and LocalIP==RemoteIP and InitiatingProcessParentFileName=="svchost.exe"), 'DcomProcessConnecToSelf', 'Other'
)
Stage 8: summarize time_window=20s
| summarize Actions = make_set_if(Action, Action <> "Other") by DeviceId, DeviceName, bin(Timestamp,20s)
Stage 9: where
| where array_length(Actions)==5
Stage 10: project-rename
| project-rename ActivityTimestamp = Timestamp
Stage 11: join
| join kind=inner (
DeviceProcessEvents
| where Timestamp > ago(60m)
| where ActionType=="ProcessCreated" and InitiatingProcessCommandLine == "svchost.exe -k DcomLaunch -p"
) on DeviceId
Stage 12: where
| where abs(datetime_diff('second', Timestamp, ActivityTimestamp)) <=20
Indicators
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 |
|---|---|---|
ActionType | eq |
|
Actions | eq |
|
InitiatingProcessCommandLine | 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 |
|---|---|
Actions | summarize |
DeviceId | summarize |
DeviceName | summarize |
ActivityTimestamp | project-rename |