IP with multiple failed Microsoft Entra ID logins successfully logs in to Palo Alto VPN
Description
This query creates a list of IP addresses with the number of failed login attempts to Entra ID above a set threshold ( default of 5 ). It then looks for any successful Palo Alto VPN logins from any of these IPs within the same timeframe.
Query · kql
//Set a threshold of failed AAD signins from an IP address within 1 day above which we want to deem those logins suspicious.
let signin_threshold = 5;
//Make a list of IPs with AAD signin failures above our threshold.
let aadFunc = (tableName:string){
let suspicious_signins =
table(tableName)
//Looking for logon failure results
| where ResultType !in ("0", "50125", "50140")
//Exclude localhost addresses to reduce the chance of FPs
| where IPAddress !in ("127.0.0.1", "::1")
| summarize count() by IPAddress
| where count_ > signin_threshold
| summarize make_set(IPAddress);
suspicious_signins
};
let aadSignin = aadFunc("SigninLogs");
let aadNonInt = aadFunc("AADNonInteractiveUserSignInLogs");
let suspicious_signins =
union isfuzzy=true aadSignin, aadNonInt
| summarize make_set(set_IPAddress);
//See if any of those IPs have sucessfully logged into PA VPNs during the same timeperiod
CommonSecurityLog
//Select only PA VPN sucessful logons
| where DeviceVendor == "Palo Alto Networks" and DeviceEventClassID == "globalprotect"
| where Message has "GlobalProtect gateway user authentication succeeded"
//Parse out the logon source IP from the Message field to match on
| extend SourceIP = extract("Login from: ([^,]+)", 1, Message)
| where SourceIP in (suspicious_signins)
| extend Reason = "Multiple failed AAD logins from SourceIP"
//Parse out other useful information from Message field
| extend User = extract('User name: ([^,]+)', 1, Message)
| extend ClientOS = extract('Client OS version: ([^,\"]+)', 1, Message)
| extend Location = extract('Source region: ([^,]{2})',1, Message)
| project TimeGenerated, Reason, SourceIP, User, ClientOS, Location, Message, DeviceName, ReceiptTime, DeviceVendor, DeviceEventClassID, Computer, FileName
| extend timestamp = TimeGenerated