Query Details

Post Phishing Url Click Suspicious Sign Ins

Query

# *Post Phishing UrlClick SuspiciousSignIns*

## Query Information

#### MITRE ATT&CK Technique(s)

| Technique ID | Title    | Link    |
| ---  | --- | --- |
| T1566 | Phishing | https://attack.mitre.org/techniques/T1566 |

#### Description

Most of us know the Task, that you have to analyse post Phishing E-Mail Events. This Query detects users who clicked on a defined phishing link (Defined by SenderIP [phishingSenderIPs] or Subject [phishingSubjects] ) and experienced a successful login from an unknown or rare IP address within 24 hours of the click.

#### Author <Optional>
- **Name: Benjamin Zulliger**
- **Github: https://github.com/benscha/KQLAdvancedHunting**
- **LinkedIn: https://www.linkedin.com/in/benjamin-zulliger/**


## Defender XDR
```KQL
// Define whitelisted URLs
let whitelistedURLs = dynamic([
    "https://aka.ms/LearnAboutSenderIdentification",
    "https://givmegithubstars.com"
]);
// Define whitelisted login IP ranges
let whitelistedIPRange = dynamic(["XX.XX.0.0/16", "10.0.0.0/8"]);
// Define known phishing indicators
let phishingSenderIPs = dynamic(["XX.XX.XX.XX", "XX.XX.XX.XX"]);
let phishingSubjects = dynamic([
    "Complete Document E-sign Agreement Review",
    'Gambrinus Hoppus shared "Document!"'
]);
// IP History: Count how many times the user has logged in from this IP (last 29 days)
let HistoricalIPCounts = EntraIdSignInEvents
| where ErrorCode == 0
| where Timestamp >= ago(29d)
| summarize IPSeenCount = count() by AccountUpn, IPAddress;
// Identify users who clicked on phishing links
let PhishClickUsers = EmailEvents
| where SenderIPv4 in (phishingSenderIPs)
    or Subject in (phishingSubjects)
    or Subject has_any (phishingSubjects)
| join EmailUrlInfo on NetworkMessageId
| join UrlClickEvents on Url
| where Url !in (whitelistedURLs)
| project AccountUpn, Url, ClickTimestamp = Timestamp;
// Correlate logins after the click with IP history
PhishClickUsers
| join kind=leftouter (
    EntraIdSignInEvents
    | where ErrorCode == 0
    | project 
        AccountUpn,
        LoginTimestamp = Timestamp,
        IPAddress,
        Country,
        City,
        DeviceName,
        Application,
        LogonType,
        IsManaged,
        ConditionalAccessStatus,
        RiskLevelDuringSignIn,
        UserAgent
) on AccountUpn
| where isnotempty(LoginTimestamp)
| where LoginTimestamp > ClickTimestamp
| where LoginTimestamp < ClickTimestamp + 24h
| extend MinutesSinceClick = datetime_diff('minute', LoginTimestamp, ClickTimestamp)
| where not(ipv4_is_in_any_range(IPAddress, whitelistedIPRange))
// Join with IP history data
| join kind=leftouter HistoricalIPCounts on AccountUpn, IPAddress
| extend IPSeenCount = coalesce(IPSeenCount, 0)
| extend IPRiskLevel = case(
    IPSeenCount == 0,            "High Risk - New IP",
    IPSeenCount < 3,             "Medium Risk - Rare IP",
    IPSeenCount >= 3,            "Lower Risk - Frequent IP",
    "Unknown"
)
| where IPSeenCount < 2
| project
    AccountUpn,
    ClickTimestamp,
    Url,
    LoginTimestamp,
    MinutesSinceClick,
    IPAddress,
    Country,
    City,
    DeviceName,
    Application,
    RiskLevelDuringSignIn,
    ConditionalAccessStatus,
    IPSeenCount,
    IPRiskLevel,
    UserAgent
| sort by MinutesSinceClick asc
```

Explanation

This query is designed to detect potentially suspicious activity following a phishing email event. Here's a simplified breakdown of what it does:

  1. Whitelist Setup: It starts by defining lists of URLs and IP ranges that are considered safe (whitelisted). These are URLs and IP addresses that should not trigger alerts.

  2. Phishing Indicators: It identifies known phishing indicators, such as specific sender IP addresses and email subjects that are associated with phishing attempts.

  3. IP History: It checks how often a user has logged in from a particular IP address over the past 29 days to establish a baseline of normal activity.

  4. Phishing Click Detection: It identifies users who have clicked on links in emails that match the phishing indicators. It excludes clicks on whitelisted URLs.

  5. Login Correlation: It looks for successful logins from these users within 24 hours of clicking a phishing link. It checks if these logins come from IP addresses that are not in the whitelisted range.

  6. Risk Assessment: It assesses the risk level of the IP address used for login based on how frequently the user has logged in from that IP in the past:

    • High Risk: New IP (never seen before)
    • Medium Risk: Rare IP (seen less than 3 times)
    • Lower Risk: Frequent IP (seen 3 or more times)
  7. Output: It provides a list of users who clicked on phishing links and then logged in from a potentially suspicious IP address, along with details such as the time between the click and login, the IP address used, and the assessed risk level.

The query is useful for identifying potential security incidents where a user might have been compromised after interacting with a phishing email.

Details

Benjamin Zulliger profile picture

Benjamin Zulliger

Released: April 28, 2026

Tables

EntraIdSignInEventsEmailEventsEmailUrlInfoUrlClickEvents

Keywords

UrlsIpAddressSenderSubjectEmailUserDeviceApplicationCountryCityUseragent

Operators

letdynamicwheresummarizecountbyjoinonprojectextenddatetime_diffcasecoalescesortascinhas_any!inisnotempty><==>=<=!=agoipv4_is_in_any_rangeleftouter

Actions