Zscaler ZPA/ZIA - Perfect Impostor: Account Takeover Hiding Within Normal Traffic
36 CSL ZPA Perfect Impostor Account Takeover
Query
let baselineWindow = 14d;
let recentWindow = 4h;
let ZPA_Baseline =
CommonSecurityLog
| where TimeGenerated between (ago(baselineWindow) .. ago(recentWindow))
| where DeviceVendor == "Zscaler" and DeviceProduct has "ZPA"
| where DeviceAction !in ("block", "BLOCK", "Failed")
| where isnotempty(SourceUserName)
| extend BaselineCountry = tostring(geo_info_from_ip_address(SourceIP).country)
| summarize
BaselineCountries = make_set(BaselineCountry, 20),
BaselineAppCount = dcount(DestinationHostName)
by UserName = tolower(SourceUserName);
let ZPA_Recent =
CommonSecurityLog
| where TimeGenerated > ago(recentWindow)
| where DeviceVendor == "Zscaler" and DeviceProduct has "ZPA"
| where isnotempty(SourceUserName)
| extend RecentCountry = tostring(geo_info_from_ip_address(SourceIP).country)
| summarize
RecentCountries = make_set(RecentCountry, 5),
RecentApps = make_set(DestinationHostName, 10),
RecentIPs = make_set(SourceIP, 5),
RecentConnCount = count(),
ZPA_FirstSeen = min(TimeGenerated)
by UserName = tolower(SourceUserName);
let ZIA_Suspicious =
CommonSecurityLog
| where TimeGenerated > ago(recentWindow)
| where DeviceVendor == "Zscaler"
| where isnotempty(SourceUserName)
| where DeviceCustomString2 has_any (
"REMOTE_ACCESS_TOOLS", "REMOTE_ADMINISTRATION", "WEB_BASED_ADMIN",
"ACCOUNT_CREATION", "TUNNEL_SOCKS_PROXY", "ANONYMOUS_PROXY",
"ONLINE_STORAGE", "FILE_SHARE", "TOR", "VPN_SERVICES",
"NEWLY_REGISTERED_DOMAINS", "PHISHING")
| summarize
ZIA_Categories = make_set(DeviceCustomString2, 10),
ZIA_Destinations = make_set(DestinationHostName, 10),
ZIA_RequestCount = count(),
ZIA_FirstSeen = min(TimeGenerated)
by UserName = tolower(SourceUserName);
let IdP_Changes =
OfficeActivity
| where TimeGenerated > ago(recentWindow)
| where isnotempty(UserId)
| where Operation in (
"New-InboxRule",
"Set-Mailbox",
"Add-MailboxPermission",
"Add OAuth2PermissionGrant",
"Consent to application",
"Add service principal credentials",
"Update user",
"Disable Strong Authentication",
"Update StsRefreshTokenValidFrom",
"Add member to role")
| summarize
IdP_EventCount = count(),
IdP_Operations = make_set(Operation, 10),
IdP_FirstSeen = min(TimeGenerated)
by UserName = tolower(UserId);
ZPA_Recent
| join kind=inner ZPA_Baseline on UserName
| extend NewCountries = set_difference(RecentCountries, BaselineCountries)
| join kind=leftouter ZIA_Suspicious on UserName
| join kind=leftouter IdP_Changes on UserName
| extend
ZIA_RequestCount = coalesce(ZIA_RequestCount, 0),
IdP_EventCount = coalesce(IdP_EventCount, 0)
| extend ImpostorScore =
iff(array_length(NewCountries) > 0, 40, 0)
+ (ZIA_RequestCount * 5)
+ (IdP_EventCount * 30)
| where ImpostorScore >= 40
or (IdP_EventCount >= 1 and ZIA_RequestCount >= 1)
or array_length(NewCountries) > 0
| project
UserName,
NewCountries, RecentCountries, BaselineCountries,
RecentApps, RecentIPs, RecentConnCount,
ZIA_Categories, ZIA_Destinations, ZIA_RequestCount,
IdP_Operations, IdP_EventCount,
ImpostorScore,
ZPA_FirstSeen
| order by ImpostorScore descExplanation
This query is designed to detect potential account takeovers by identifying unusual behavior across different layers of user activity. Here's a simplified breakdown:
-
Purpose: The query aims to identify "perfect impostor" scenarios where an attacker uses stolen credentials and mimics a legitimate user's behavior but introduces subtle anomalies.
-
Layers Analyzed:
- ZPA Layer: Checks for user sessions from countries not seen in the past 14 days, indicating possible use of a new device, VPN, or compromised session.
- ZIA Layer: Looks for browsing activity to suspicious sites like remote admin tools, proxies, or newly registered domains, which are not typical for the user.
- IdP/SaaS Layer: Monitors critical account changes such as MFA removal or privilege escalation.
-
Scoring: Each layer is scored individually. A high score or a combination of suspicious activities across layers flags the account as potentially compromised.
-
Outcome: The query generates a prioritized list of high-risk accounts for further review and action, such as session termination or MFA re-enforcement, to prevent attackers from gaining persistence or escalating privileges.
-
Frequency and Duration: The query runs every 4 hours and analyzes data from the past 14 days.
-
Alerting: If suspicious activity is detected, an alert is created with details about the anomalies and a calculated "ImpostorScore" to prioritize investigation.
Overall, this query helps security teams quickly identify and respond to potential account takeovers by correlating anomalies across multiple layers of user activity.
Details

David Alonso
Released: March 2, 2026
Tables
Keywords
Operators
Severity
HighTactics
Frequency: PT4H
Period: P14D