Storm-2949: Living Off the Cloud via SSPR, Graph, and Azure RBAC

Share:

Storm-2949 ran a two-phase, identity-centric intrusion that pivoted from a single SSPR-abused account into a full cross-plane compromise (SaaS → PaaS → IaaS → endpoint). The hallmark of the campaign is the near-total reliance on legitimate administrative primitives (Graph API, Azure RBAC, Run Command, VMAccess, publishing profiles, listkeys) rather than custom malware — which is what allowed the activity to blend with normal admin behavior. Endpoint footprint (ScreenConnect on VMs) was secondary and used for credential harvesting, not core exfiltration.

Severity: High

Actor Profile

  • Threat Actor: Storm-2949
  • Motivation: Data theft (high-confidence, based on terminal objectives)
  • Sophistication: High methodical, multi-stage, cloud-native tradecraft
  • Tooling philosophy: Living-off-the-cloud; minimal traditional malware; abuse of legitimate Azure/Entra control-plane features

Targeting

  • Selective victimology: IT personnel and senior leadership compromised first → indicates pre-attack reconnaissance and a deliberate path-to-privilege strategy.
  • Target assets: M365 (OneDrive/SharePoint), Azure production subscriptions, App Services, Key Vaults, Storage accounts, SQL, and VMs.
  • Document targeting bias: VPN configs and remote-access procedures — suggests interest in hybrid pivot into on-prem.

Attack Chain

Phase 1: Identity Compromise

  1. Social engineering of targeted users posing as internal IT.
  2. Attacker-initiated SSPR; victim coerced into approving “verification” MFA prompts.
  3. Password reset; legitimate auth methods (phone, email, Authenticator) stripped.
  4. Attacker registers own Microsoft Authenticator device → persistent, MFA-backed access; legitimate user locked out.
  5. Process repeated across multiple users (≥4 total compromises observed).

Phase 2: Tenant Reconnaissance

  • Custom Python tooling against Microsoft Graph (/v1.0/users with $select and $filter=startsWith(displayName,…)) to enumerate users by name patterns and job titles.
  • Attempted service principal credential addition (failed insufficient permissions); continued enumerating SPs and app IDs for application-tier persistence paths.

Phase 3: M365 Data Theft

  • OneDrive web UI used to bulk-download thousands of files in single sessions.
  • Behavior repeated across each compromised identity to expand share/folder coverage.

Phase 4: Azure Control-Plane Abuse

  • App Service: Primary production web app gated by network controls. Pivoted to peripheral apps in the same ecosystem; called microsoft.Web/sites/publishxml/action to pull publishing profiles (FTP / Web Deploy / Kudu credentials). Secondary apps yielded foothold but not the prize.
  • Key Vault: Compromised identity held Owner on a vault containing production credentials. Over a ~4-minute window: access policy/RBAC manipulation → extraction of dozens of secrets (DB connection strings, identity credentials).
  • Production web app takeover: Authenticated using Key Vault-sourced credentials, rotated the password to lock out legitimate owners, then exfiltrated data.

Phase 5: Data-Plane Exfiltration

  • Azure SQL: microsoft.sql/servers/firewallrules/write → temporary allow-list of attacker IPs → connect with Key Vault creds → exfil → firewall rules deleted post-exfil.
  • Azure Storage: microsoft.storage/storageaccounts/write to open public access from attacker IPs; microsoft.Storage/storageAccounts/listkeys/action to harvest SAS tokens and account keys. Bulk blob download via custom Python (Azure SDK for Storage).

Phase 6: IaaS Pivot

  • VMAccess extension deployed to add a new local admin on target VMs (legitimate “recovery” feature weaponized).
  • Run Command used for:
    • IMDS managed-identity token theft → attempted Key Vault secret retrieval
    • PowerShell deployment of ScreenConnect.

Phase 7: Endpoint Operations

  • Defender AV tampering: real-time protection and behavior monitoring disabled; service interference.
  • ScreenConnect installed from attacker infrastructure; service renamed/relocated to mimic Windows components.
  • Anti-forensics: event log clearing, command-history wipe, temp/artifact deletion.
  • Via ScreenConnect: host/domain enumeration, .pfx certificate theft, file-share password-string sweeps.

Recommendations

  1. Implement strictly mandated phishing-resistant MFA for all administrative and high-privilege identities.
  2. Ensure all corporate users have pre-registered and locked MFA profiles to prevent external threat actors from conducting malicious first-time MFA registrations during SSPR abuse.
  3. Enable Conditional Access policies requiring compliant devices or trusted location footprints, combined with Microsoft Entra ID Protection to flag and auto-remediate risky sign-ins.
  4. Enforce private endpoints for Azure Storage and disable all public network/anonymous read capabilities. Implement immutable storage policies to prevent data tampering during a breach.
  5. Enable Purge Protection with a standard retention delay (e.g., 90 days) to mitigate irreversible data or credential deletion.
  6. Eliminate blanket “Owner” or high-tier administrative roles on subscriptions. Transition to fine-grained Azure Attribute-Based Access Control (ABAC) and Just-In-Time (JIT) access policies.
  7. Turn on Tamper Protection within security solutions like Microsoft Defender for Endpoint to prevent threat actors from systematically disabling antivirus services and monitoring agents.
  8. Block the IOCs at their respective controls
    https://www.virustotal.com/gui/collection/ef364c17ec824abc950fc1a7b6e72f3bef4511ea8b9151935c6942a7cfa12823/iocs

Source:

  • https://www.microsoft.com/en-us/security/blog/2026/05/18/storm-2949-turned-compromised-identity-into-cloud-wide-breach/

Enjoyed reading this Threat Intelligence Advisory? Stay updated with our latest exclusive content by following us on Twitter and LinkedIn

No related posts found.

Talk to an expert