Detection rules › Kusto
NRT Azure DevOps Audit Stream Disabled
'Azure DevOps allow for audit logs to be streamed to external storage solutions such as SIEM solutions. An attacker looking to hide malicious Azure DevOps activity from defenders may look to disable data streams before conducting activity and then re-enabling the stream after (so as not to raise data threshold-based alarms). Looking for disabled audit streams can identify this activity, and due to the nature of the action its unlikely to have a high false positive rate.'
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Stealth | T1562.008 Impair Defenses: Disable or Modify Cloud Logs |
Rule body kusto
id: 74ed028d-e392-40b7-baef-e69627bf89d1
name: NRT Azure DevOps Audit Stream Disabled
description: |
'Azure DevOps allow for audit logs to be streamed to external storage solutions such as SIEM solutions. An attacker looking to hide malicious Azure DevOps activity from defenders may look to disable data streams before conducting activity and then re-enabling the stream after (so as not to raise data threshold-based alarms). Looking for disabled audit streams can identify this activity, and due to the nature of the action its unlikely to have a high false positive rate.'
severity: High
status: Available
requiredDataConnectors: []
tactics:
- DefenseEvasion
relevantTechniques:
- T1562.008
query: |
ADOAuditLogs
| where OperationName =~ "AuditLog.StreamDisabledByUser"
| extend StreamType = tostring(Data.ConsumerType)
| project-reorder TimeGenerated, Details, ActorUPN, IpAddress, UserAgent, StreamType
| extend timestamp = TimeGenerated
| extend AccountName = tostring(split(ActorUPN, "@")[0]), AccountUPNSuffix = tostring(split(ActorUPN, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: ActorUPN
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IpAddress
version: 1.0.4
kind: NRT
Stages and Predicates
Stage 1: source
ADOAuditLogs
Stage 2: where
| where OperationName =~ "AuditLog.StreamDisabledByUser"
Stage 3: extend
| extend StreamType = tostring(Data.ConsumerType)
Stage 4: project-reorder
| project-reorder TimeGenerated, Details, ActorUPN, IpAddress, UserAgent, StreamType
Stage 5: extend
| extend timestamp = TimeGenerated
Stage 6: extend
| extend AccountName = tostring(split(ActorUPN, "@")[0]), AccountUPNSuffix = tostring(split(ActorUPN, "@")[1])
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 |
|---|---|---|
OperationName | 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 |
|---|---|
StreamType | extend |
timestamp | extend |
AccountName | extend |
AccountUPNSuffix | extend |