Detection rules › Kusto

AD FS Abnormal EKU object identifier attribute

Severity
high
Time window
1d
Group by
OID
Author
Microsoft Security Research
Source
github.com/Azure/Azure-Sentinel

'This detection uses Security events from the "AD FS Auditing" provider to detect suspicious object identifiers (OIDs) as part EventID 501 and specifically part of the Enhanced Key Usage attributes. This query checks to see if you have any new OIDs in the last hour that have not been seen in the previous day. New OIDs should be validated and OIDs that are very long, as indicated by the OID_Length field, could also be an indicator of malicious activity. In order to use this query you need to enable AD FS auditing on the AD FS Server. References: https://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/ https://docs.microsoft.com/windows-server/identity/ad-fs/troubleshooting/ad-fs-tshoot-logging '

MITRE ATT&CK coverage

TacticTechniques
Credential AccessT1552 Unsecured Credentials

Rule body kusto

id: cfc1ae62-db63-4a3e-b88b-dc04030c2257
name: AD FS Abnormal EKU object identifier attribute
description: |
  'This detection uses Security events from the "AD FS Auditing" provider to detect suspicious object identifiers (OIDs) as part EventID 501 and specifically part of the Enhanced Key Usage attributes.
  This query checks to see if you have any new OIDs in the last hour that have not been seen in the previous day. New OIDs should be validated and OIDs that are very long, as indicated
  by the OID_Length field, could also be an indicator of malicious activity.
  In order to use this query you need to enable AD FS auditing on the AD FS Server.
  References:
  https://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/
  https://docs.microsoft.com/windows-server/identity/ad-fs/troubleshooting/ad-fs-tshoot-logging
  '
severity: High
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CredentialAccess
relevantTechniques:
  - T1552
tags:
  - Nobelium
  - MagicWeb
query: |
  // change the starttime value for a longer period of known OIDs
  let starttime = 1d;
  // change the lookback value for a longer period of lookback for suspicious/abnormal
  let lookback = 1h;
  let OIDList = SecurityEvent
  | where TimeGenerated >= ago(starttime)
  | where EventSourceName == 'AD FS Auditing'
  | where EventID == 501
  | where EventData has '/eku'
  | extend OIDs = extract_all(@"<Data>([\d+\.]+)</Data>", EventData)
  | mv-expand OIDs
  | extend OID = tostring(OIDs)
  | extend OID_Length = strlen(OID)
  | project TimeGenerated, Computer, EventSourceName, EventID, OID, OID_Length, EventData
  ;
  OIDList
  | where TimeGenerated >= ago(lookback)
  | join kind=leftanti (
  OIDList
  | where TimeGenerated between (ago(starttime) .. ago(lookback))
  | summarize by OID
  ) on OID
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: HostNameDomain
version: 1.0.4
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Microsoft Security Research
    support:
        tier: Community
    categories:
        domains: [ "Security - Others", "Identity" ]

Stages and Predicates

Parameters

let starttime = 1d;
let lookback = 1h;

The stages below define let OIDList (the rule's main pipeline source).

Stage 1: source

let OIDList

Stage 2: source

SecurityEvent

Stage 3: where

| where TimeGenerated >= ago(starttime)

Stage 4: where

| where EventSourceName == 'AD FS Auditing'

Stage 5: where

| where EventID == 501

Stage 6: where

| where EventData has '/eku'

Stage 7: extend

| extend OIDs = extract_all(@"<Data>([\d+\.]+)</Data>", EventData)

Stage 8: mv-expand

| mv-expand OIDs

Stage 9: extend

| extend OID = tostring(OIDs)

Stage 10: extend

| extend OID_Length = strlen(OID)

Stage 11: project

| project TimeGenerated, Computer, EventSourceName, EventID, OID, OID_Length, EventData

The stages below run on OIDList (the outer pipeline).

Stage 12: where

OIDList
| where TimeGenerated >= ago(lookback)

Stage 13: join (negated)

| join kind=leftanti (
OIDList
| where TimeGenerated between (ago(starttime) .. ago(lookback))
| summarize by OID
) on OID

Stage 14: extend

| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))

Stage 15: extend

| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
HostNameDomain =
ifDomainIndex != -1substring(Computer, (DomainIndex + 1))
elseComputer

Stage 16: summarize

summarize by OID

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
EventDatamatch/eku
EventIDeq501
EventSourceNameeqAD FS Auditing

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.

FieldKindValues
EventDatamatch
  • /eku transforms: term
EventIDeq
  • 501 transforms: cased corpus 2 (kusto 2)
EventSourceNameeq
  • AD FS Auditing transforms: cased

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.

FieldSource
OIDsummarize