Detection rules › Kusto

ADWS Connection from Process Injection Target

Group by
DeviceId, DeviceName, FileName, InitiatingProcessFileName, InitiatingProcessId, ProcessId
Author
FalconForce
Source
github.com/FalconForceTeam/FalconFriday

The query first collects all network connections to the Active Directory Web Services (ADWS) service. It then searches for processes that inject into a process that makes a connection to ADWS. This can be used to detect process injection into a process that is used to query Active Directory.

Known false positives

  • None expected.

MITRE ATT&CK coverage

References

Telemetry coverage

Rule body

let timeframe = 2*1h;
let ADWSConnections=(
    DeviceNetworkEvents
    | where ingestion_time() >= ago(timeframe)
    | where ActionType == "ConnectionSuccess"
    | where RemotePort == 9389
    | extend InitiatingProcessFileName=tolower(InitiatingProcessFileName)
);
let ADWSFileNames=materialize(
    ADWSConnections
    | distinct InitiatingProcessFileName
);
// Look for processes that inject into a process that makes an ADWS connection.
let InjectorProcesses=materialize(
    DeviceEvents
    | where ingestion_time() >= ago(timeframe)
    | where not(isempty(FileName))
    // Look for actions associated with process injection.
    | where ActionType in~ ("CreateRemoteThreadApiCall", "MemoryRemoteProtect","NtAllocateVirtualMemoryApiCall", "NtAllocateVirtualMemoryRemoteApiCall", "NtMapViewOfSectionRemoteApiCall", "NtProtectVirtualMemoryApiCall", "SetThreadContextRemoteApiCall", "QueueUserApcRemoteApiCall")
    | where FileName in~ (ADWSFileNames)
    | where not(InitiatingProcessFolderPath startswith @"c:\program files\vmware\vmware tools" and InitiatingProcessFileName =~ "vmtoolsd.exe")
    | where not(InitiatingProcessFolderPath =~ @"C:\Windows\System32" and InitiatingProcessFileName =~ "csrss.exe")
    | where not(InitiatingProcessFolderPath =~ @"C:\Windows\System32\csrss.exe")
    | where not(InitiatingProcessFolderPath startswith @"c:\program files\microsoft azure ad sync\" and InitiatingProcessFileName =~ "miiserver.exe")
    | extend FileName=tolower(FileName)
    | lookup kind=inner ADWSConnections on DeviceId, $left.ProcessId == $right.InitiatingProcessId, $left.FileName == $right.InitiatingProcessFileName
    // Begin environment-specific filter.
    // End environment-specific filter.
    | project DeviceId, ProcessId, FileName, InjectorProcessId=InitiatingProcessId, InjectorFileName=InitiatingProcessFileName, InjectorActionType=ActionType
);
// Find ADWS connections from processes that were injected into by another process.
ADWSConnections
| lookup kind=inner InjectorProcesses on DeviceId, $left.InitiatingProcessId == $right.ProcessId, $left.InitiatingProcessFileName == $right.FileName
| summarize arg_min(Timestamp,*), InjectionMethods=make_set(InjectorActionType) by DeviceId, DeviceName, InitiatingProcessId, InitiatingProcessFileName
| extend HostName=tostring(split(DeviceName,".")[0]),DnsDomain=iif(DeviceName contains ".", substring(DeviceName, indexof(DeviceName, ".") + 1, strlen(DeviceName)),"")
// Begin environment-specific filter.
// End environment-specific filter.

Stages and Predicates

Parameters

let timeframe = 2*1h;

let ADWSConnections is inlined into the numbered stages below.

Let binding: ADWSFileNames used in Stage 2

let ADWSFileNames = materialize(
    ADWSConnections
    | distinct InitiatingProcessFileName
);

Let binding: InjectorProcesses used in Stages 3, 9

let InjectorProcesses = materialize(
    DeviceEvents
    | where ingestion_time() >= ago(timeframe)
    | where not(isempty(FileName))
    | where ActionType in~ ("CreateRemoteThreadApiCall", "MemoryRemoteProtect","NtAllocateVirtualMemoryApiCall", "NtAllocateVirtualMemoryRemoteApiCall", "NtMapViewOfSectionRemoteApiCall", "NtProtectVirtualMemoryApiCall", "SetThreadContextRemoteApiCall", "QueueUserApcRemoteApiCall")
    | where FileName in~ (ADWSFileNames)
    | where not(InitiatingProcessFolderPath startswith @"c:\program files\vmware\vmware tools" and InitiatingProcessFileName =~ "vmtoolsd.exe")
    | where not(InitiatingProcessFolderPath =~ @"C:\Windows\System32" and InitiatingProcessFileName =~ "csrss.exe")
    | where not(InitiatingProcessFolderPath =~ @"C:\Windows\System32\csrss.exe")
    | where not(InitiatingProcessFolderPath startswith @"c:\program files\microsoft azure ad sync\" and InitiatingProcessFileName =~ "miiserver.exe")
    | extend FileName=tolower(FileName)
    | lookup kind=inner ADWSConnections on DeviceId, $left.ProcessId == $right.InitiatingProcessId, $left.FileName == $right.InitiatingProcessFileName
    | project DeviceId, ProcessId, FileName, InjectorProcessId=InitiatingProcessId, InjectorFileName=InitiatingProcessFileName, InjectorActionType=ActionType
);

Stage 1: source

let ADWSConnections

Stage 2: source

let ADWSFileNames

Stage 3: source

let InjectorProcesses

Stage 4: source

DeviceNetworkEvents

Stage 5: where

where ...

Stage 6: where

where ActionType =~ "ConnectionSuccess"

Stage 7: where

where RemotePort == 9389

Stage 8: extend

extend InitiatingProcessFileName

Stage 9: kusto:lookup

lookup kind=inner (InjectorProcesses) on DeviceId, InitiatingProcessId, ProcessId, InitiatingProcessFileName, FileName

Stage 10: summarize

summarize InjectionMethods by DeviceId, DeviceName, InitiatingProcessId, InitiatingProcessFileName

Stage 11: extend

extend DnsDomain, HostName

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
ActionTypeeq
  • ConnectionSuccess
field:"ActionType" kind:eq value:"ConnectionSuccess"
ActionTypein
  • CreateRemoteThreadApiCall
  • MemoryRemoteProtect
  • NtAllocateVirtualMemoryApiCall
  • NtAllocateVirtualMemoryRemoteApiCall
  • NtMapViewOfSectionRemoteApiCall
  • NtProtectVirtualMemoryApiCall
  • QueueUserApcRemoteApiCall
  • SetThreadContextRemoteApiCall
field:"ActionType" kind:in
FileNamein
  • ADWSFileNames
field:"file_name" kind:in value:"ADWSFileNames"
RemotePorteq
  • 9389
field:"DestinationPort" kind:eq value:"9389"

Output fields

These fields are emitted when the rule matches.

FieldSource
DeviceIdsummarize
DeviceNamesummarize
InitiatingProcessFileNamesummarize
InitiatingProcessIdsummarize
InjectionMethodssummarize
DnsDomainextend
HostNameextend