Detect Cloud Accounts in Microsoft Sentinel
Adversaries may compromise cloud accounts to use during targeting operations. Compromised cloud accounts (Azure, AWS, GCP, Dropbox, OneDrive, GitHub) allow adversaries to leverage trusted third-party infrastructure for command and control, exfiltration to cloud storage, sending phishing or spam via cloud messaging services (AWS SES/SNS, SendGrid, Twilio), and acquiring additional cloud infrastructure without managing their own servers. Compromise methods include phishing for cloud credentials, password spraying, purchasing leaked credential sets from criminal markets, or stealing OAuth access tokens. APT29 has been observed using compromised Azure Virtual Machine accounts with residential proxies to obfuscate access to victim environments. This is a PRE-ATT&CK technique — the initial account compromise occurs outside the victim environment on third-party cloud platforms. Detection pivots to observable downstream effects: anomalous authentication events in cloud identity provider logs, risk signals from Identity Protection engines, MFA bypass indicators, and post-compromise behaviors such as bulk cloud storage access or cloud messaging API abuse.
MITRE ATT&CK
- Tactic
- Resource Development
- Technique
- T1586 Compromise Accounts
- Sub-technique
- T1586.003 Cloud Accounts
- Canonical reference
- https://attack.mitre.org/techniques/T1586/003/
KQL Detection Query
// T1586.003 — Compromised Cloud Account Usage Detection
// Detects compromised cloud accounts via Azure AD Identity Protection risk events,
// confirmed compromise states, impossible travel, and cross-tenant MFA bypass patterns
let SuspiciousRiskEventTypes = dynamic([
"impossibleTravel", "anonymizedIPAddress", "maliciousIPAddress",
"unfamiliarFeatures", "passwordSpray", "leakedCredentials",
"nationStateIP", "riskyIPAddress", "investigationsThreatIntelligence"
]);
SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| extend CountryCode = tostring(LocationDetails.countryOrRegion)
| extend City = tostring(LocationDetails.city)
| extend ParsedBrowser = tostring(DeviceDetail.browser)
| extend ParsedOS = tostring(DeviceDetail.operatingSystem)
| extend IsHighRiskSignIn = RiskLevelDuringSignIn in ("high", "medium")
| extend IsCompromisedState = RiskState in ("atRisk", "confirmedCompromised")
| extend HasSuspiciousRiskEvent = RiskEventTypes_V2 has_any (SuspiciousRiskEventTypes)
| extend IsCrossTenantMFABypass = AuthenticationRequirement == "singleFactorAuthentication"
and isnotempty(HomeTenantId)
and HomeTenantId != ResourceTenantId
| where IsHighRiskSignIn or IsCompromisedState or HasSuspiciousRiskEvent or IsCrossTenantMFABypass
| extend AlertReason = case(
IsCompromisedState, "ConfirmedCompromise",
IsHighRiskSignIn and HasSuspiciousRiskEvent, strcat("HighRisk+Event:", tostring(RiskEventTypes_V2)),
IsHighRiskSignIn, "HighRiskSignIn",
HasSuspiciousRiskEvent, strcat("RiskEvent:", tostring(RiskEventTypes_V2)),
IsCrossTenantMFABypass, "CrossTenantMFABypass",
"UnknownRisk"
)
| extend RiskIndicatorCount = toint(IsHighRiskSignIn) + toint(IsCompromisedState)
+ toint(HasSuspiciousRiskEvent) + toint(IsCrossTenantMFABypass)
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress,
CountryCode, City, ParsedBrowser, ParsedOS,
RiskLevelDuringSignIn, RiskLevelAggregated, RiskState,
RiskEventTypes_V2, ConditionalAccessStatus, AuthenticationRequirement,
HomeTenantId, ResourceTenantId,
AlertReason, RiskIndicatorCount
| sort by RiskIndicatorCount desc, TimeGenerated desc Detects compromised cloud account usage through Azure AD SigninLogs by correlating Azure Identity Protection risk events (impossible travel, leaked credentials, malicious IPs, password spray signals, anonymized IPs), confirmed compromise states (atRisk, confirmedCompromised), and cross-tenant MFA bypass indicators where single-factor authentication succeeded against a resource in a different tenant. RiskIndicatorCount provides a composite score to prioritize alerts: score of 2+ indicates high-confidence compromise. Requires Azure AD P2 licensing for full Identity Protection risk event population in RiskEventTypes_V2.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate business travel — users authenticating from new geographic regions trigger impossibleTravel and unfamiliarFeatures risk events; correlate against HR travel records or user-submitted travel notifications
- Corporate VPN or proxy services routing authentication traffic through anonymizing or geographically unexpected IP ranges, triggering anonymizedIPAddress or unfamiliarFeatures events
- Automated service accounts and CI/CD pipelines authenticating from cloud-hosted build agents (GitHub Actions, Azure DevOps) with IP ranges that Identity Protection classifies as anomalous or associated with hosting providers
- Cross-tenant guest access patterns for legitimate B2B collaboration where users regularly authenticate to partner tenant resources using single-factor authentication under legacy conditional access policies
Other platforms for T1586.003
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Azure AD Password Spray Simulation
Expected signal: Azure AD SigninLogs: multiple ResultType != 0 (error code 50126: invalid credentials) entries from the same source IPAddress within a 5-10 minute window, each with a different UserPrincipalName. Azure Identity Protection will aggregate the spray pattern and generate a passwordSpray risk event type within 15-30 minutes of the spray completing, appearing in Azure AD > Security > Identity Protection > Risk Detections.
- Test 2Sign-In from Anonymizing Proxy to Trigger Identity Protection Risk Event
Expected signal: Azure AD SigninLogs: successful sign-in (ResultType=0) with IPAddress matching a known Tor exit node (verifiable against dan.me.uk/torlist or similar). RiskEventTypes_V2 populated with 'anonymizedIPAddress'. RiskLevelDuringSignIn set to 'medium' or 'high' within 5-15 minutes. The risk detection appears in Azure AD > Security > Identity Protection > Risk Detections with detectionTimingType='realtime' or 'nearRealtime'.
- Test 3OAuth Access Token Reuse for Cloud Storage Access
Expected signal: Azure Storage diagnostic logs (StorageBlobLogs): AuthenticationType='OAuth', RequesterObjectId matches the test user's object ID, URI shows container list and blob download operations. No new SigninLogs entry is generated since token reuse does not trigger interactive authentication. Defender for Cloud Apps (if deployed) generates an anomalous cloud storage access alert when detecting storage API access from an unusual user agent or IP without corresponding SigninLogs event.
- Test 4AWS Cloud Credential Validation and Reconnaissance
Expected signal: AWS CloudTrail events (sourcetype=aws:cloudtrail in Splunk): GetCallerIdentity (eventSource=sts.amazonaws.com), ListAttachedUserPolicies and ListGroupsForUser (eventSource=iam.amazonaws.com), ListBuckets (eventSource=s3.amazonaws.com), DescribeInstances (eventSource=ec2.amazonaws.com) — all sharing the same sourceIPAddress, userAgent (aws-cli/<version>), and accessKeyId within a 2-minute window. If AWS GuardDuty is enabled, Recon:IAMUser/MaliciousIPCaller or Recon:IAMUser/PortProbeUnprotectedPort findings may fire depending on source IP reputation.
References (10)
- https://attack.mitre.org/techniques/T1586/003/
- https://unit42.paloaltonetworks.com/compromised-cloud-compute-credentials/
- https://awakesecurity.com/blog/threat-hunting-series-detecting-command-control-in-the-cloud/
- https://www.netcraft.com/blog/popular-email-platform-used-to-impersonate-itself/
- https://www.microsoft.com/security/blog/2021/10/25/nobelium-targeting-delegated-administrative-privileges-to-facilitate-broader-attacks/
- https://learn.microsoft.com/en-us/azure/active-directory/identity-protection/concept-identity-protection-risks
- https://learn.microsoft.com/en-us/azure/active-directory/reports-monitoring/reference-azure-monitor-sign-ins-log-schema
- https://learn.microsoft.com/en-us/microsoft-365/security/defender/advanced-hunting-emailevents-table
- https://docs.splunk.com/Documentation/AddOns/released/MSCloudServices/ConfigureInputs
- https://mandiant.com/resources/blog/apt29-microsoft-365
Unlock Pro Content
Get the full detection package for T1586.003 including response playbook, investigation guide, and atomic red team tests.