# Midnight Blizzard attack on Microsoft corporate environment: a detailed analysis, detections and recommendations

Midnight Blizzard password-sprayed a legacy MFA-less test tenant, abused over-consented OAuth app permissions to create an admin in Microsoft's corporate tenant and read all mailboxes.

- Payout: Real-world hack
- Severity: critical
- Program: Microsoft
- Credited: Wiz Research
- Disclosed: 2024-02-08
- Write-up quality: 7/10
- Original: https://www.wiz.io/blog/midnight-blizzard-microsoft-breach-analysis-and-best-practices
- Library page: https://bugbountylibrary.com/r/blog%3Awiz-io-blog-midnight-blizzard-microsoft-breach-analysis-and-best-practices
- Tags: domain:cloud impact:data-leak impact:internal-access kind:incident platform:threat-intel sev:critical tech:azure tech:oauth technique:chained technique:default-creds vuln:auth-bypass vuln:misconfiguration vuln:privilege-escalation

**Target:** Entra ID / Exchange Online OAuth applications and tenants
**Root cause:** A legacy non-production test tenant account lacked MFA and could manage OAuth app secrets; a legacy test OAuth app held tenant-wide admin-consented Graph permissions (Directory.ReadWrite.All, RoleManagement.ReadWrite.Directory, Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All) in the production tenant.
**Steps:**
1. Password-spray the legacy test tenant Entra ID user (no MFA) to gain initial access.
2. Use that user's privilege to add a new client secret/certificate to the legacy test OAuth app.
3. Request a token as the test app against the corporate tenant: `curl -X POST -d 'client_id=<test-app>&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=<secret>&grant_type=client_credentials' https://login.microsoftonline.com/<corp-tenant>/oauth2/v2.0/token`.
4. Create a new user in the corporate tenant via Directory.ReadWrite.All.
5. Assign Global Administrator to the new user via RoleManagement.ReadWrite.Directory.
6. Create a new multi-tenant app: `az ad app create --display-name malicious-mail-access --sign-in-audience AzureADMultipleOrgs`.
7. Add full_access_as_app to it: `az ad app permission add --id <app> --api 00000002-0000-0ff1-ce00-000000000000 --api-permissions dc890d15-9560-4a4c-9b7f-a736ec74ec40=Role`.
8. Sign in as the new corporate admin and grant admin consent to the malicious app.
9. Request a token with scope `https://outlook.office365.com/.default` as the malicious app to access any corporate mailbox.
**How found:** Wiz reconstructed the chain from Microsoft's disclosure, inferring the exact Graph permissions required at each step (user creation, role assignment, app creation, app role assignment) from the stated capabilities.
**Exploitation:** After password-spraying into the MFA-less test tenant, the actor minted a client_credentials token for the over-privileged legacy test app against the production tenant, created a Global Admin user, then used that admin to consent a new multi-tenant app to full_access_as_app, yielding unrestricted Exchange Online mailbox access.
**Escalation:** Chained test-tenant compromise -> app secret creation -> cross-tenant app token -> corporate user creation -> Global Admin -> illicit consent of full_access_as_app -> tenant-wide mailbox access.
**Insight:** Legacy test tenants federated or consented into production are a soft underbelly: enumerate service principals with tenant-wide admin consent (Directory.ReadWrite.All, AppRoleAssignment.ReadWrite.All, full_access_as_app) and check whether their owning tenant still has MFA-less or stale accounts that can rotate their secrets.
