T1586.002

Email Accounts

Adversaries may compromise existing email accounts to support operations. Unlike creating new accounts, compromising legitimate accounts leverages established trust relationships, bypasses reputation-based email filters, and enables thread hijacking. Compromise methods include credential phishing, password reuse from breach dumps, brute force, and insider access (buying credentials from employees). Threat actors including APT28, APT29, Kimsuky, OilRig, Star Blizzard, and LAPSUS$ have all used compromised email accounts to conduct spearphishing, harvest additional credentials, and acquire infrastructure. Because the compromise itself occurs externally, detection must focus on observable post-compromise behaviors within the organization: risky sign-in patterns, impossible travel, inbox rule manipulation, bulk sending anomalies, and thread hijacking indicators.

Microsoft Sentinel / Defender
kusto
// T1586.002 — Compromised Email Account Detection
// Detects post-compromise behaviors: impossible travel, risky sign-ins,
// inbox rule creation/forwarding setup, and bulk outbound email anomalies.

let LookbackWindow = 24h;
let ImpossibleTravelThreshold = 2; // distinct countries within 1 hour
let BulkSendThreshold = 50; // emails sent in 1 hour

// Branch 1: Risky or impossible travel sign-ins to email services
let RiskySignIns =
SigninLogs
| where TimeGenerated > ago(LookbackWindow)
| where ResultType == "0" // Successful sign-in only — compromise achieved
| where AppDisplayName has_any ("Exchange", "Outlook", "Office 365", "Microsoft 365", "Exchange Online", "OWA")
| where RiskLevelDuringSignIn in ("high", "medium") or RiskState == "atRisk"
    or IsRisky == true
| extend Country = tostring(Location.countryOrRegion)
| extend City = tostring(Location.city)
| project TimeGenerated, UserPrincipalName, IPAddress, Country, City,
          AppDisplayName, DeviceDetail, RiskLevelDuringSignIn, RiskState,
          RiskDetail, AutonomousSystemNumber, AuthenticationRequirement,
          ConditionalAccessStatus
| extend DetectionBranch = "RiskySignIn";

// Branch 2: Impossible travel — same account from multiple countries within 1 hour
let ImpossibleTravel =
SigninLogs
| where TimeGenerated > ago(LookbackWindow)
| where ResultType == "0"
| where AppDisplayName has_any ("Exchange", "Outlook", "Office 365", "Microsoft 365", "Exchange Online", "OWA")
| extend Country = tostring(Location.countryOrRegion)
| summarize
    Countries = make_set(Country),
    IPAddresses = make_set(IPAddress),
    SignInCount = count(),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
  by UserPrincipalName, bin(TimeGenerated, 1h)
| where array_length(Countries) >= ImpossibleTravelThreshold
| extend DetectionBranch = "ImpossibleTravel"
| project FirstSeen, UserPrincipalName, Countries, IPAddresses, SignInCount, DetectionBranch;

// Branch 3: Inbox rule creation or email forwarding configured post-sign-in
let InboxRuleCreation =
OfficeActivity
| where TimeGenerated > ago(LookbackWindow)
| where Operation in (
    "New-InboxRule", "Set-InboxRule", "UpdateInboxRules",
    "Set-Mailbox", "Set-MailboxAutoReplyConfiguration"
  )
| where Parameters has_any (
    "ForwardTo", "ForwardAsAttachmentTo", "RedirectTo",
    "DeleteMessage", "MarkAsRead", "MoveToFolder"
  )
| extend RuleParameters = tostring(Parameters)
| project TimeGenerated, UserId, ClientIP, Operation, RuleParameters,
          OfficeWorkload, OrganizationName
| extend DetectionBranch = "InboxRuleManipulation";

// Branch 4: High-volume email sending anomaly (bulk phishing from compromised account)
let BulkSending =
OfficeActivity
| where TimeGenerated > ago(LookbackWindow)
| where Operation == "Send"
| where OfficeWorkload == "Exchange"
| summarize
    EmailsSent = count(),
    UniqueRecipients = dcount(tostring(parse_json(tostring(Parameters))[0].Value)),
    FirstSend = min(TimeGenerated),
    LastSend = max(TimeGenerated)
  by UserId, ClientIP, bin(TimeGenerated, 1h)
| where EmailsSent >= BulkSendThreshold
| extend DetectionBranch = "BulkEmailSending"
| project FirstSend, UserId, ClientIP, EmailsSent, UniqueRecipients, DetectionBranch;

// Combine all branches
RiskySignIns
| union (ImpossibleTravel | project TimeGenerated = FirstSeen, UserPrincipalName, DetectionBranch, IPAddress = tostring(IPAddresses))
| union (InboxRuleCreation | project TimeGenerated, UserPrincipalName = UserId, DetectionBranch, IPAddress = ClientIP)
| union (BulkSending | project TimeGenerated = FirstSend, UserPrincipalName = UserId, DetectionBranch, IPAddress = ClientIP)
| sort by TimeGenerated desc
high severity medium confidence

Data Sources

Application Log: Application Log Content Network Traffic: Network Traffic Content Microsoft 365 Unified Audit Log Azure AD Identity Protection

Required Tables

SigninLogs OfficeActivity

False Positives

  • Legitimate travel: employees using email from multiple countries in rapid succession (e.g. layovers, VPN with auto-selected exit nodes, or roaming with split-tunnel VPN)
  • IT administrators creating inbox rules or forwarding configurations on behalf of users during mailbox migrations, offboarding, or automated workflow setup
  • Marketing automation or bulk email campaigns sent through compromised-looking patterns when authorized tools (Mailchimp, HubSpot) relay via Exchange
  • Azure AD Identity Protection flagging sign-ins from corporate IP ranges not yet registered as named locations, generating false risk scores
  • Service accounts or shared mailboxes that legitimately sign in from multiple locations or send high volumes of transactional email

Unlock Pro Content

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

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections