T1586

Compromise Accounts

This detection identifies indicators of compromised accounts being leveraged against the organization, including credential stuffing attacks that transition from repeated failures to success, impossible travel anomalies where a single identity authenticates from geographically distant locations within an implausible timeframe, sign-ins from known hosting or anonymization infrastructure, and MFA bypass patterns consistent with session token theft or adversary-in-the-middle phishing toolkits such as Evilginx2 or Modlishka. Because T1586 is a PRE-ATT&CK technique occurring outside the victim environment, detections focus on the observable authentication artifacts generated when adversaries weaponize stolen credentials or session material against organizational identity providers including Azure AD, on-premises Active Directory, and SaaS application login flows.

Microsoft Sentinel / Defender
kusto
let timeWindow = 24h;
let failThreshold = 5;
let travelWindowMinutes = 60;
// --- Signal 1: Credential stuffing — many failures then success from multiple IPs ---
let CredentialStuffing = AADSignInLogs
| where TimeGenerated > ago(timeWindow)
| where ResultType != "50053" and ResultType != "50076" // exclude locked-out and MFA-required noise
| summarize
    FailureCount = countif(ResultType != "0"),
    SuccessCount = countif(ResultType == "0"),
    UniqueIPs = dcount(IPAddress),
    IPList = make_set(IPAddress, 10),
    Apps = make_set(AppDisplayName, 5),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
    by UserPrincipalName
| where FailureCount >= failThreshold and SuccessCount >= 1
| extend DetectionType = "CredentialStuffing",
    RiskScore = iff(UniqueIPs > 5, 90, iff(UniqueIPs > 2, 75, 60));
// --- Signal 2: Impossible travel — successful logins from 2+ countries within 60 minutes ---
let ImpossibleTravel = AADSignInLogs
| where TimeGenerated > ago(timeWindow)
| where ResultType == "0"
| where isnotempty(Location)
| extend Country = tostring(LocationDetails.countryOrRegion)
| where isnotempty(Country)
| summarize
    Countries = make_set(Country, 20),
    IPList = make_set(IPAddress, 10),
    Apps = make_set(AppDisplayName, 5),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated),
    SuccessCount = count()
    by UserPrincipalName, bin(TimeGenerated, 1h)
| where array_length(Countries) > 1
| extend DetectionType = "ImpossibleTravel", RiskScore = 85,
    FailureCount = 0, UniqueIPs = array_length(IPList);
// --- Signal 3: Successful login from Tor exit node or known bulletproof hosting ASN ---
let SuspiciousASN = AADSignInLogs
| where TimeGenerated > ago(timeWindow)
| where ResultType == "0"
| extend ASN = tostring(todynamic(NetworkLocationDetails)[0].networkNames)
| where ASN has_any ("M247", "Frantech", "Sharktech", "Psychz", "Quasi Networks",
    "FranTech", "Alexhost", "ITL-Bulgaria", "Serverius", "Combahton")
    or IPAddress matches regex @"^185\.(220|129|220)\."
| summarize
    IPList = make_set(IPAddress, 10),
    Apps = make_set(AppDisplayName, 5),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated),
    SuccessCount = count(),
    Countries = make_set(tostring(LocationDetails.countryOrRegion), 5)
    by UserPrincipalName
| extend DetectionType = "SuspiciousHostingASN", RiskScore = 80,
    FailureCount = 0, UniqueIPs = array_length(IPList);
// --- Union all signals ---
CredentialStuffing
| union ImpossibleTravel
| union SuspiciousASN
| project
    TimeGenerated = LastSeen,
    UserPrincipalName,
    DetectionType,
    RiskScore,
    FailureCount,
    SuccessCount,
    UniqueIPs,
    IPList,
    Apps,
    Countries,
    FirstSeen,
    LastSeen
| sort by RiskScore desc, TimeGenerated desc
high severity medium confidence

Data Sources

Azure Active Directory Microsoft Entra ID

Required Tables

AADSignInLogs

False Positives

  • Legitimate corporate VPN services routing authentication through shared exit nodes may match ASN-based detection; allowlist known corporate egress IP ranges
  • Traveling employees authenticating from multiple countries within a short window (e.g. connecting through an airline hub) will trigger impossible travel; cross-reference with HR travel records and conditional access named locations
  • Shared service accounts used by automation platforms (CI/CD, monitoring) may generate high failure counts if misconfigured credentials are in rotation before being corrected; baseline service account authentication patterns
  • Password reset self-service workflows may generate multiple ResultType failures before a successful reset, mimicking credential stuffing; filter on UserType and correlate with SSPR audit events in AuditLogs

Unlock Pro Content

Get the full detection package for T1586 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections