↳ GitHub sourceAnalytics ruleMedium

Gain Code Execution on ADFS Server via SMB + Remote Service or Scheduled Task

Description

'This query detects instances where an attacker has gained the ability to execute code on an ADFS Server through SMB and Remote Service or Scheduled Task.'
Rule type
Scheduled
Version
1.2.1
Declared status
Available
Query frequency
1d
Query period
7d
Trigger
gt 0

Declared MITRE coverage

Declared sources

Metadata from the source file. No dependencies inferred from KQL.

Connectors

Data types

KQL query

Original query, unchanged.

let timeframe = 1d;
// Adjust for a longer timeframe for identifying ADFS Servers
let lookback = 6d;
// Identify ADFS Servers
let ADFS_Servers = (
SecurityEvent
| where TimeGenerated > ago(timeframe+lookback)
| where EventID == 4688 and SubjectLogonId != "0x3e4"
| where NewProcessName has "Microsoft.IdentityServer.ServiceHost.exe"
| distinct Computer
);
SecurityEvent
| where TimeGenerated > ago(timeframe)
| where Computer in~ (ADFS_Servers)
| where Account !endswith "$"
// Check for scheduled task events
| where EventID in (4697, 4698, 4699, 4700, 4701, 4702)
| extend EventDataParsed = parse_xml(EventData)
| extend SubjectLogonId = tostring(EventDataParsed.EventData.Data[3]["#text"])
// Check specifically for access to IPC$ share and PIPE\svcctl and PIPE\atsvc for Service Control Services and Schedule Control Services
| union (
    SecurityEvent
    | where TimeGenerated > ago(timeframe)
    | where Computer in~ (ADFS_Servers)
    | where Account !endswith "$"
    | where EventID == 5145
    | where RelativeTargetName =~ "svcctl" or RelativeTargetName  =~ "atsvc"
)
// Check for lateral movement
| join kind=inner
(SecurityEvent
| where TimeGenerated > ago(timeframe)
| where Account !endswith "$"
| where EventID == 4624 and LogonType == 3
) on $left.SubjectLogonId == $right.TargetLogonId
| project TimeGenerated, Account, Computer, EventID, RelativeTargetName
| extend timestamp = TimeGenerated
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| extend AccountName = tostring(split(Account, @'\')[1]), AccountNTDomain = tostring(split(Account, @'\')[0])

Declared entities

AccountHost

Related content

Links established from declared identifiers and solution manifests.

Source provenance

GitHub

Displayed values come from files in Azure/Azure-Sentinel. They describe the published template, not your workspace configuration.

Source identifier
12dcea64-bec2-41c9-9df2-9f28461b1295
Additional source files 3Solutions/Windows Security Events/Analytic Rules/GainCodeExecutionADFSViaSMB.yamlsource ↗Detections/SecurityEvent/GainCodeExecutionADFSViaSMB.yamlmigration-note ↗Solutions/Windows Security Events/Data/Solution_Windows Security Events.jsonsolution-membership ↗
GSTEP / CATALOG TRACKING

Added to catalog : 16 Sept 2026 · 05:49 UTC
Last change observed : 16 Sept 2026 · 05:49 UTC

GSTEP sync dates, separate from the source content’s publication dates.