Query Details
id: a3b4c5d6-e7f8-4a9b-0c1d-2e3f4a5b6c7d
name: "Correlation: Firewall Allowed Traffic + Azure AD Sign-In from Same IP"
version: 1.0.0
kind: Scheduled
description: |
Correlates firewall-allowed outbound traffic with Azure AD sign-in events sharing the same
external IP. An IP that appears in both AAD sign-in logs and firewall sessions simultaneously
may indicate a threat actor using the same infrastructure for credential-based cloud access
and network-level data collection. This correlation amplifies low-confidence signals from
each source into a high-confidence cross-vector indicator.
MITRE ATT&CK: T1078 (Valid Accounts)
severity: High
requiredDataConnectors:
- connectorId: CommonSecurityEvents
dataTypes:
- CommonSecurityLog
- connectorId: AzureActiveDirectory
dataTypes:
- SigninLogs
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
- DefenseEvasion
relevantTechniques:
- T1078
query: |
let FirewallExternalIPs =
CommonSecurityLog
| where TimeGenerated > ago(1d)
| where DeviceVendor in ("Fortinet", "Palo Alto Networks", "Zscaler")
| where DeviceAction !in ("deny", "block", "drop", "BLOCK", "DROP")
| where ipv4_is_private(DestinationIP) == false
| summarize
FW_Connections = count(),
FW_Sources = make_set(SourceIP, 10),
FW_BytesSent = sum(SentBytes),
FW_Vendors = make_set(DeviceVendor)
by ExternalIP = DestinationIP;
SigninLogs
| where TimeGenerated > ago(1d)
| where ResultType == 0
| where isnotempty(IPAddress)
| summarize
AAD_SignInCount = count(),
AAD_Users = make_set(UserPrincipalName, 20),
AAD_AppNames = make_set(AppDisplayName, 10),
AAD_Countries = make_set(Location, 5),
AAD_RiskLevels = make_set(RiskLevelDuringSignIn, 5)
by IPAddress
| join kind=inner FirewallExternalIPs on $left.IPAddress == $right.ExternalIP
| project
IPAddress,
AAD_SignInCount,
AAD_Users,
AAD_Countries,
AAD_RiskLevels,
FW_Connections,
FW_Sources,
FW_BytesSent,
FW_Vendors
| order by FW_Connections desc
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPAddress
customDetails:
AAD_SignInCount: AAD_SignInCount
FW_Connections: FW_Connections
alertDetailsOverride:
alertDisplayNameFormat: "Cross-Signal IP Match - {{IPAddress}} in Firewall + AAD Sign-In"
alertDescriptionFormat: "IP {{IPAddress}} generated {{AAD_SignInCount}} AAD sign-ins and {{FW_Connections}} firewall sessions. Multi-vector activity from a single source is a strong compromise indicator."
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: PT12H
matchingMethod: Selected
groupByEntities:
- IP
groupByAlertDetails: []
groupByCustomDetails: []
This query is designed to detect potential security threats by correlating data from two sources: firewall logs and Azure Active Directory (AAD) sign-in logs. Here's a simplified breakdown of what the query does:
Purpose: The query identifies instances where the same external IP address is involved in both successful Azure AD sign-ins and allowed outbound traffic through firewalls. This could indicate a threat actor using the same IP for unauthorized access and data collection.
Data Sources:
Process:
Output: The result is a list of IP addresses that appear in both datasets, along with details like the number of sign-ins, users involved, countries, risk levels, firewall connections, source IPs, bytes sent, and vendors.
Alerting: If any matches are found, an alert is generated with a high severity level, indicating potential compromise. The alert includes details about the IP address, the number of AAD sign-ins, and firewall sessions.
Incident Management: The query is configured to create incidents for these alerts, grouping them by IP address to manage related alerts together.
Overall, this query helps security teams identify and respond to potential threats by highlighting suspicious multi-vector activity from the same IP address.

David Alonso
Released: March 2, 2026
Tables
Keywords
Operators