A forgotten 2019 SharePoint bug that still rules the top of every exploit leaderboard
CVE-2019-0604 is a deserialization-driven RCE in Microsoft SharePoint Server's EntityInstanceIdEncoder / XmlSerializer path, reachable via crafted XML in the Business Data Connectivity (BDC) module. An unauthenticated attacker who can POST a malicious BDC model to /_layouts/15/Picker.aspx (or ItemPicker.aspx / BDCAdmin.aspx) lands code execution as the SharePoint application pool identity — typically a privileged service account. Affected: SharePoint Foundation 2010 SP2, SharePoint Foundation 2013 SP1, SharePoint Server 2010 SP2, SharePoint Server 2013 SP1, SharePoint Enterprise Server 2016, and SharePoint Server 2019.
Microsoft's CRITICAL (9.8) rating is fully justified and we are leaving it CRITICAL. The vendor vector (AV:N/AC:L/PR:N/UI:N) matches reality: a single HTTP POST, no credentials, no user interaction, and the target is by design a collaboration server reachable by every employee and frequently exposed to the internet. Seven years of weaponization, multiple nation-state campaigns (China Chopper webshells, Iranian APT activity, ransomware affiliates) and an EPSS of 0.99913 mean this is not a theoretical risk — it is an ongoing intrusion vector.
5 steps from start to impact.
Locate exposed SharePoint endpoint
Microsoft-IIS headers plus MicrosoftSharePointTeamServices response headers, or hits known internal collaboration URLs after initial access. SharePoint farms are commonly published to the internet for partner collaboration and remote work.- Network reachability to the SharePoint front-end
- Service is one of the vulnerable versions
- Many enterprises now front SharePoint with Azure AD App Proxy / pre-auth WAF
- Internet-exposed on-prem SharePoint population has shrunk as customers migrate to M365
/_layouts/15/Picker.aspxPOST malicious BDC XML to Picker.aspx
/_layouts/15/Picker.aspx or /_layouts/15/items.aspx with a __VIEWSTATE-style parameter containing a serialized ResourceDictionary / XamlReader.Parse gadget. Tools: public Metasploit module exploit/windows/http/sharepoint_workflows_xoml, Nuclei template CVE-2019-0604, and dozens of GitHub PoCs.- HTTP(S) POST allowed to /_layouts/15/ paths
- No pre-auth in front of SharePoint
- A WAF with the Microsoft-published signature blocks the gadget chain
- If the patch is installed the parser rejects the markup
proc_creation_win_w3wp_susp_child flags w3wp.exe spawning cmd.exe/powershell.exeXAML deserialization → code execution as app-pool identity
ObjectDataProvider to invoke Process.Start, executing arbitrary commands inside the w3wp.exe worker hosting the SharePoint app pool. The default identity is usually a domain service account with elevated SharePoint farm rights.- XAML/XML parsing reaches the gadget
- App pool account has the typical SharePoint farm rights
- AppLocker or WDAC blocking child-process spawning from w3wp.exe (rare)
- EDR script-block logging often catches the PowerShell stage
Drop webshell / persistence
.aspx webshells into the TEMPLATE\LAYOUTS directory, then pivot. CISA and NSA both documented this exact TTP under multiple advisories (AA20-275A, joint Iranian advisory).- Write access to SharePoint hive directories (default for app pool)
- File integrity monitoring on the SharePoint hive directories
eval(Request[...]) patternsPivot to farm account → Active Directory
- Farm account has lateral reach (common)
- LSASS protection / Credential Guard
The supporting signals.
| In-the-wild | Active exploitation since April 2019. Used by Chinese APT (Hafnium-adjacent), Iranian MuddyWater, FIN11 / Clop, and numerous ransomware affiliates per CISA AA20-275A and AA20-259A. |
|---|---|
| Public PoC | Yes — Metasploit module sharepoint_workflows_xoml, Nuclei template, GitHub PoCs by k8gege, mzer0one, and original write-up by Markus Wulftange (Code White) and Soroush Dalili (NCC). |
| EPSS | 0.99913 (99.99th percentile) — among the highest scores in the FIRST EPSS dataset. |
| CISA KEV | Listed 2021-11-03, due date 2022-05-03. Re-cited in multiple CISA / NSA / FBI joint advisories. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H → unauthenticated network RCE, no user interaction. Vector is honest. |
| Affected versions | SharePoint Foundation 2010 SP2 / 2013 SP1, SharePoint Server 2010 SP2 / 2013 SP1 / 2016 / 2019. |
| Fixed by | Microsoft KB4462143/4462211/4462202/4462184/4462199/4462171 (Feb 2019) and follow-ups KB4464534/KB4464556 (March 2019) for the bypass variants. |
| Exposure | Shodan still shows ~70k–120k on-prem SharePoint farms internet-reachable; Censys tags ~25% as unpatched on banner heuristics. |
| Disclosed | Microsoft advisory 2019-02-12 (the 2022-05-13 date in the prompt reflects an MSRC re-publication, not original disclosure). |
| Reporter | Markus Wulftange of Code White GmbH via ZDI (ZDI-19-122). |
noisgate verdict.
Unauthenticated remote code execution in an internet-reachable collaboration server, KEV-listed since 2021, EPSS in the 99.99th percentile, with multiple active nation-state and ransomware campaigns. The decisive factor is active in-the-wild exploitation against a high-value role — SharePoint farm accounts routinely hold domain-wide reach, making a single landed exploit a fleet-compromise event.
Why this verdict
- KEV + EPSS 0.9991: this is the empirical definition of 'being exploited right now'. Friction discussion does not apply when the bug is already at the top of every threat actor's checklist.
- Role multiplier — SharePoint farm = identity-adjacent: the affected component runs as a service account that almost always has SQL DBA on the content DB and frequently has Kerberos delegation to file shares and sometimes DCs. Chain ends in domain compromise.
- Role multiplier — workstation/dev SharePoint: rare; SharePoint is server-class by definition, so the >10% high-value-role share is built into the product. Verdict floor is CRITICAL.
- Unauthenticated, no UI, single HTTP POST: zero friction at the protocol level. The only real-world brake is patching, which is exactly why this CVE is still being exploited seven years on.
- Public, weaponized tooling everywhere: Metasploit, Nuclei, multiple GitHub PoCs — skill floor is near zero.
Why not higher?
9.6 is essentially ceiling. We trim from a theoretical 10 only because a meaningful share of on-prem SharePoint is now behind Azure AD App Proxy / pre-auth reverse proxies, and the on-prem footprint has shrunk as customers move to SharePoint Online (which is not affected).
Why not lower?
Downgrading would require ignoring KEV listing, an EPSS at the 99.99th percentile, seven years of ransomware operator usage, and the canonical high-value-role profile of a SharePoint farm account. None of those factors is going away.
What to do — in priority order.
- Block /_layouts/15/Picker.aspx and ItemPicker.aspx at the WAF/reverse proxy — These are the documented exploit endpoints. Microsoft and CISA both publish WAF signatures. Deploy within 3 days per the noisgate CRITICAL mitigation SLA while you stage the cumulative update.
- Front SharePoint with pre-authentication (Azure AD App Proxy, F5 APM, or NetScaler AAA) — Pre-auth eliminates the unauthenticated reachability that makes this CVE 9.8. Required for any farm still published to the internet.
- Constrain the SharePoint application pool identity — Strip the farm account of unnecessary domain rights, disable unconstrained delegation, and enforce LAPS-style rotation. This caps blast radius if exploitation does land.
- Deploy EDR rules for w3wp.exe spawning cmd.exe/powershell.exe — This child-process chain is the universal post-exploitation tell. Defender for Endpoint, CrowdStrike, and SentinelOne all have built-in detections — verify they are enabled in Block mode.
- Hunt for existing webshells in the SharePoint hive — Search
C:\Program Files\Common Files\microsoft shared\Web Server Extensions\1[56]\TEMPLATE\LAYOUTS\for unexpected.aspxfiles dated since 2019. Assume any vulnerable farm is potentially already compromised.
- MFA — the exploit hits an unauthenticated endpoint; no login is involved.
- Network IDS without TLS inspection — the payload is inside HTTPS POST bodies.
- Disabling anonymous access at the SharePoint site level — the vulnerable layout pages are reachable regardless because the deserialization happens before app-level auth.
- Migrating users to SharePoint Online while leaving the on-prem farm alive — attackers still hit the legacy server.
Crowdsourced verification payload.
Run on the SharePoint server itself as a local administrator. Invoke: powershell -ExecutionPolicy Bypass -File .\Check-CVE-2019-0604.ps1. The script inspects the installed SharePoint build number against the Feb/Mar 2019 fixed builds.
#requires -RunAsAdministrator
# Check-CVE-2019-0604.ps1
# Detects vulnerable Microsoft SharePoint build for CVE-2019-0604
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
$ErrorActionPreference = 'Stop'
# Minimum fixed builds (March 2019 cumulative or later strongly recommended)
$fixed = @{
'14' = [version]'14.0.7237.5000' # SharePoint 2010 SP2 + KB4462143
'15' = [version]'15.0.5023.1000' # SharePoint 2013 SP1 + KB4462211 / KB4464534
'16.0.4' = [version]'16.0.4795.1000' # SharePoint 2016 + KB4462184
'16.0.10' = [version]'16.0.10340.12101' # SharePoint 2019 + KB4462199
}
try {
$reg = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Office Server\' -ErrorAction Stop |
Where-Object { $_.PSChildName -match '^\d+\.\d+$' }
} catch {
Write-Output 'UNKNOWN: SharePoint not installed or registry inaccessible'
exit 2
}
$verdict = 'PATCHED'
foreach ($k in $reg) {
$major = $k.PSChildName
$installed = Get-ItemProperty $k.PSPath | Select-Object -ExpandProperty BuildVersion -ErrorAction SilentlyContinue
if (-not $installed) { continue }
$iv = [version]$installed
$key = if ($major -eq '16.0' -and $iv.Build -ge 10000) { '16.0.10' }
elseif ($major -eq '16.0') { '16.0.4' }
else { $major.Split('.')[0] }
if ($fixed.ContainsKey($key)) {
if ($iv -lt $fixed[$key]) {
Write-Output "VULNERABLE: SharePoint $major build $iv < required $($fixed[$key])"
$verdict = 'VULNERABLE'
} else {
Write-Output "PATCHED: SharePoint $major build $iv"
}
} else {
Write-Output "UNKNOWN: unrecognized SharePoint major $major"
if ($verdict -eq 'PATCHED') { $verdict = 'UNKNOWN' }
}
}
switch ($verdict) {
'VULNERABLE' { exit 1 }
'UNKNOWN' { exit 2 }
default { exit 0 }
}
If you remember one thing.
/_layouts/15/Picker.aspx and ItemPicker.aspx at the WAF today and require pre-auth (Azure AD App Proxy) on any internet-published farm by end of week. Per the noisgate remediation SLA for CRITICAL, the actual cumulative update must be deployed within 90 days, but for a seven-year-old KEV bug with EPSS 0.999 there is no defensible reason to take longer than 30. Hunt the LAYOUTS directory for stray .aspx webshells regardless of patch status.Sources
- Microsoft MSRC advisory (CVE-2019-0604)
- CISA KEV catalog entry
- CISA AA20-275A (China cyber threat overview)
- NSA top 25 vulnerabilities exploited by Chinese state actors
- Code White / Markus Wulftange technical write-up
- Rapid7 Metasploit module documentation
- GitHub Security Advisory GHSA-6mr5-xh3f-7vqm
- FIRST EPSS data for CVE-2019-0604
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.