Detection rules › Kusto

Multiple Sources Affected by the Same TI Destination

Status
available
Severity
medium
Time window
1d
Group by
Fqdn, ThreatDescription
Source
github.com/Azure/Azure-Sentinel

'Identifies multiple machines trying to reach out to the same destination blocked by TI in Azure Firewall. This can indicate attack on the organization by the same attack group. Configurable Parameters: - Minimum affected threshold - alert only if more than this number of hosts affected. Default is set to 5. - Recommendation is to use the new resource specific logs. If you are using both, the TiTraffic Count will be duplicated.'

MITRE ATT&CK coverage

TacticTechniques
Command & ControlT1071 Application Layer Protocol
ExfiltrationT1041 Exfiltration Over C2 Channel

Rule body kusto

id: 4644baf7-3464-45dd-bd9d-e07687e25f81
name: Multiple Sources Affected by the Same TI Destination
description: |
  'Identifies multiple machines trying to reach out to the same destination blocked by TI in Azure Firewall. This can indicate attack on the organization by the same attack group.
  
  Configurable Parameters:
  
  - Minimum affected threshold - alert only if more than this number of hosts affected. Default is set to 5.
  - Recommendation is to use the new resource specific logs. If you are using both, the TiTraffic Count will be duplicated.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: AzureFirewall
    dataTypes: 
      - AzureDiagnostics
      - AZFWThreatIntel
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Exfiltration
  - CommandAndControl
relevantTechniques:
  - T1041
  - T1071
query: |
  let Timeframe = 1d;
  let StartTime = ago(Timeframe);
  let EndTime = now(); 
  let MinAffectedThreshold = 5;
  union isfuzzy=true
  (AzureDiagnostics 
  | where TimeGenerated  between (StartTime .. EndTime)
  | where OperationName == "AzureFirewallThreatIntelLog"
  | parse msg_s with * "from " SourceIp ":" SourcePort:int " to " Fqdn ":" DestinationPort:int  "." * "Action: Deny. " ThreatDescription),
  (AZFWThreatIntel
  | where TimeGenerated between (StartTime .. EndTime))
  | extend Fqdn = DestinationIp
  | summarize TiTrafficCount = count(), dCountSourceIps = dcount(SourceIp), AffectedIps = make_set(SourceIp, 10000) by Fqdn, ThreatDescription
  | where array_length(AffectedIps) > MinAffectedThreshold
  | mv-expand SourceIp = AffectedIps
  | order by TiTrafficCount desc, Fqdn asc, parse_ipv4(tostring(SourceIp)) asc
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SourceIp
  - entityType: URL
    fieldMappings:
      - identifier: Url
        columnName: Fqdn
customDetails:
  ThreatDescription: ThreatDescription
version: 1.1.5
kind: Scheduled

Stages and Predicates

Parameters

let Timeframe = 1d;
let StartTime = ago(Timeframe);
let EndTime = now();
let MinAffectedThreshold = 5;

union isfuzzy=true (2 sources)

Each leg below queries one source; the rule matches if any leg does. Sources: AzureDiagnostics, AZFWThreatIntel

Leg 1: AzureDiagnostics

AzureDiagnostics 
| where TimeGenerated  between (StartTime .. EndTime)
| where OperationName == "AzureFirewallThreatIntelLog"
| parse msg_s with * "from " SourceIp ":" SourcePort:int " to " Fqdn ":" DestinationPort:int  "." * "Action: Deny. " ThreatDescription

Leg 2: AZFWThreatIntel

AZFWThreatIntel
| where TimeGenerated between (StartTime .. EndTime)

Applied to the combined result

| extend Fqdn = DestinationIp
| summarize TiTrafficCount = count(), dCountSourceIps = dcount(SourceIp), AffectedIps = make_set(SourceIp, 10000) by Fqdn, ThreatDescription
| where array_length(AffectedIps) > MinAffectedThreshold
| mv-expand SourceIp = AffectedIps
| order by TiTrafficCount desc, Fqdn asc, parse_ipv4(tostring(SourceIp)) asc

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
AffectedIpsgt
  • 5 transforms: array_length
OperationNameeq
  • AzureFirewallThreatIntelLog transforms: cased
TimeGeneratedge
  • StartTime
TimeGeneratedle
  • EndTime

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
AffectedIpssummarize
Fqdnsummarize
ThreatDescriptionsummarize
TiTrafficCountsummarize
dCountSourceIpssummarize