SigninLogs — Fresh IP Authenticating Multiple Accounts (Compromised Proxy)
22 SIGNIN Fresh IP Multi Account Auth
Query
// ---- Network Allowlist (exclude trusted IPs / CIDR / ranges) --------------
let _allow = materialize(union isfuzzy=true (print R="" | take 0), (_GetWatchlist('NetworkAllowlist') | project R = tostring(IPOrRange)) | where isnotempty(R));
let _allowCIDR = toscalar(_allow | where not(R matches regex @'^\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+$') | extend R = iff(R has '/', R, strcat(R, '/32')) | summarize make_list(R));
let _allowRange = toscalar(_allow | where R matches regex @'^\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+$' | summarize make_list(R));
let _ExcludeAllowlistedIPs = (T:(IPAddress:string)) {
T
| extend IPAddress = tostring(IPAddress)
| where array_length(_allowCIDR) == 0 or isnull(ipv4_is_in_any_range(IPAddress, _allowCIDR)) or not(ipv4_is_in_any_range(IPAddress, _allowCIDR))
| mv-apply _r = _allowRange to typeof(string) on (
extend _lo = tostring(split(_r,'-')[0]), _hi = tostring(split(_r,'-')[1])
| extend _inRange = ipv4_compare(IPAddress, _lo) >= 0 and ipv4_compare(IPAddress, _hi) <= 0
| summarize _anyInRange = max(toint(_inRange)))
| where isnull(_anyInRange) or _anyInRange == 0
| project-away _anyInRange
};
// ---------------------------------------------------------------------------
let lookback = 2h;
let baselineDays = 14d;
let minUsers = 5;
let KnownIPs =
SigninLogs
| invoke _ExcludeAllowlistedIPs()
| where TimeGenerated between (ago(baselineDays) .. ago(lookback))
| where ResultType == "0"
| distinct IPAddress;
SigninLogs
| invoke _ExcludeAllowlistedIPs()
| where TimeGenerated > ago(lookback)
| where ResultType == "0"
| where isnotempty(IPAddress)
| join kind=leftanti KnownIPs on IPAddress
| summarize
UniqueUsers = dcount(UserPrincipalName),
AuthenticatedUsers = make_set(UserPrincipalName, 30),
TotalLogins = count(),
Apps = make_set(AppDisplayName, 5),
Locations = make_set(Location, 3),
ClientTypes = make_set(ClientAppUsed, 5),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by IPAddress
| where UniqueUsers >= minUsers
| project
TimeGenerated = FirstSeen,
IPAddress, UniqueUsers, TotalLogins,
AuthenticatedUsers, Apps,
Locations, ClientTypes, LastSeenExplanation
This query is designed to detect suspicious activity in sign-in logs, specifically focusing on identifying potential attack proxies or relays. Here's a simplified breakdown of what it does:
-
Purpose: The query aims to find IP addresses that have not been seen in the last 14 days but have successfully authenticated five or more distinct user accounts within a two-hour window. This behavior suggests the use of a newly-provisioned attack proxy or relay, potentially using a list of purchased credentials.
-
Exclusions: It excludes IP addresses that are on a predefined allowlist (trusted IPs or ranges) to avoid false positives from known safe sources.
-
Data Source: It uses data from Azure Active Directory's SigninLogs.
-
Detection Logic:
- It first identifies IP addresses that have successfully logged in during the past 14 days.
- Then, it looks for IP addresses that have appeared in the last two hours but were not seen in the previous 14 days.
- It checks if these new IP addresses have authenticated five or more distinct user accounts.
-
Output: For each suspicious IP address, it provides details such as:
- Number of unique users authenticated
- Total logins
- List of authenticated users
- Applications accessed
- Locations and client types used
- First and last seen timestamps
-
Alerting: If such an IP address is detected, an alert is generated with a high severity level, indicating a potential security threat. The alert includes details about the IP address and the number of accounts it authenticated.
-
Incident Management: The query is set to create incidents for detected cases, with configurations for grouping related alerts and managing incident states.
Overall, this query helps in identifying and alerting on potential credential-based attacks using new IP addresses, enhancing security monitoring and response capabilities.
Details

David Alonso
Released: April 20, 2026
Tables
Keywords
Operators