漏洞

KnowledgeDeliver 跨客户共用同一组 ASP.NET machineKey(CVE-2026-5426

CVE-2026-5426 把独立 KnowledgeDeliver 客户之间复用的部署秘密变成跨实例签名权:未认证的密钥持有者能够提交被另一套安装信任的 ViewState,进入反序列化并取得操作系统级代码执行。

三个有独立围栏的机构把密封状态送向同一把过大的共享钥匙,调查人员正沿服务器和配置证据追查这条信任关系。
文章导航

研究依据复核 Mandiant 事件与公告证据、公开 CVE 记录、Microsoft .NET Framework Reference Source、有效配置,以及防御性密钥轮换与狩猎流程

来源Mandiant / Digital Knowledge / Microsoft Reference Source / Microsoft Learn / SOSEC 源码复核

1 一份被复制的秘密,把客户隔离改写为共享信任

CVE-2026-5426 是 KnowledgeDeliver 的严重部署缺陷:掌握复用 ASP.NET machineKey 的未认证攻击者,能够让一个客户实例把恶意 ViewState 当成本地授权状态接受,并继续走到操作系统级代码执行。

1.1 公告命名漏洞之前,真实事件已经暴露边界失效

2025 年末,Mandiant 响应了一起运行 Digital Knowledge KnowledgeDeliver 学习管理系统的 Web 服务器失陷事件。初始执行没有停留在服务器端的一次性动作。身份未公开的操作者把 BLUEBEAM(又称 Godzilla)内存 Web Shell 放进 IIS 工作进程,修改 Web 目录权限和应用 JavaScript,再借受信任学习门户向访问者展示虚假安全提示。Mandiant 最终把未认证入口追到标准化部署配置中跨客户相同的 ASP.NET machineKey。

公开事件报告与 MNDT-2026-0009 确认了决定性事实:2026 年 2 月 24 日之前部署的 KnowledgeDeliver 使用厂商提供的标准 web.config,其中硬编码 validationKeydecryptionKey,且彼此独立的客户环境拿到了相同值。攻击者只要从一处部署取得这组值,便可针对另一套仍沿用它且可达的安装,为其 Web Forms 上下文构造受保护 ViewState,推动服务器反序列化攻击者控制的状态。

这不是简单的“弱密钥”,也不是“启用 ViewState”本身。缺陷是把本应只属于一个应用安全边界的凭据复制给无关客户。即便值本身有足够密码强度,复制也不会改善安全性,因为持有即授权。如果升级应用二进制后最终生效的继承配置仍保留旧值,暴露仍在。处置起点是撤销共享凭据,而不是只更改版本标签或封禁某一个已见载荷。

Mandiant 于 2026 年 1 月 19 日向 Digital Knowledge 报告问题;厂商在 2 月 24 日实施更新后的部署流程,双方 3 月 18 日讨论披露,MNDT-2026-0009 于 4 月 16 日发布。页面日期为 5 月 25 日的后续事件报告,补充了利用、BLUEBEAM、文件篡改、学习者诱饵与狩猎细节。这组日期把“新部署流程改变”与“旧安装仍需核验和换密钥”清楚区分开来。

因此,公开资料没有常规的“升级到固定版本 X”答案。受影响对象是部署状态而非一段具名二进制版本范围:CVE 记录描述流程更新前的部署,公告则把“预共享 key 未改变”列为决定条件。新安装包可以为未来部署带来安全模板,却不一定改动现存实例的有效配置。资产负责人需要逐实例提交配置证明,而不是用采购记录或补丁控制台截图代替。

CVE 与公告从互补角度描述问题。MNDT-2026-0009 同时列出“不可信数据反序列化”和“使用硬编码凭据”;CVE 记录描述 2 月 24 日前硬编码的 ASP.NET/IIS key 以及恶意 ViewState 结果。凭据缺陷解释不可信字节如何获得授权,反序列化缺陷解释字节被接受后为何能够成为执行。只修一边都会留下缺口:序列化器过滤不能撤销复制的签名者,轮换密钥也不会自动清除后渗透。

公开报告没有说明攻击者最初如何取得共享值。跨客户复用使几条路径具有可能性,例如合法管理的一套安装、可读配置备份或此前的服务器访问,但本案没有确认其中任何一条。可辩护结论从“已经持有”之后开始:独立部署使用相同显式材料,所以任一副本的机密性失守,都可能把授权输出给其他副本。本地调查应追踪配置读取与处理,却不能替 Mandiant 编造未公开的 key 获取故事。

Mandiant 公告给出 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H。其中 High 攻击复杂度提醒我们:key 是必要条件,可用请求还必须契合接收应用和页面上下文;网络可达、无需权限与无需用户交互,则描述上下文已知后的入口。真实事件也说明 Scope Changed 并非抽象评分:IIS 工作进程中的代码被用于更改随后交付给另一群学习者终端的内容。

1.2 machineKey 是签名者,不是产品序列号

ASP.NET Web Forms 把页面和控件状态发送给浏览器,并在之后的回发中收回。客户端可以修改隐藏字段,因此服务器用 machine-key 材料验证真实性,并在配置要求时保护机密性。这个判断既局部又有很高权限:MAC 可接受的状态会被视为出自应用验证秘密的持有者。框架并不知道部署自动化是否已经把这份秘密复制到预期边界以外。

Web Farm 展示了显式配置 key 的正当用途。浏览器可能从节点 A 取得页面,再把状态回发到节点 B。Microsoft 的 ViewState 排错文档因此要求,同一个逻辑应用的 Farm 成员使用兼容的固定验证材料;Microsoft 的 machine-key 处置指南也要求把替换值部署到 Farm 每台服务器。边界内部共享维持可用性,和无关客户共享同一组值则把互操作能力变成跨客户信任。

边界应围绕逻辑应用划分,而不是围绕每个进程,也不是覆盖整个厂商生态。必须接收彼此状态的节点共享一组新生成的值;生产客户、另一客户、测试环境、不应接收生产状态的灾备副本以及独立管理的租户,需要分别决策。运维应记录少数有意的等价组,不能把“产品相同”当作密钥相同的合理理由。

这组凭据承担两个不同安全职责。验证材料让应用判断受保护状态是否真实;解密材料在启用加密时恢复机密状态。复用因此可能同时输出签名权和打开受保护数据的能力,具体仍受上下文与格式限制。轮换规划必须盘点该安装中实际消费 machine-key 材料的 System.Web 功能,而不能只看 CVE 点名的一个隐藏字段;测试也应验证认证和状态生命周期,同时避免声称所有普通服务端 Session 都使用这组 key。

受影响应用源码、部署包、共享值、接收页面和可用利用对象图均未公开。本文因此始终区分三层材料:产品与事件事实来自 Mandiant 处置报告及固定提交的公告;框架行为来自 Microsoft 文档与固定在提交 ec9fa9ae770d522a5b5f0607898044b7478574a3 的 .NET Framework Reference Source;清单、证据关联、发布和验收方案属于 SOSEC 基于公开机制的防守分析,不宣称了解闭源 KnowledgeDeliver 内部实现。

这条证据边界避免两类常见错误。第一,公开事实不足以点名具体 KnowledgeDeliver 页面、gadget chain、框架兼容模式或自定义 handler。第二,缺少这些利用细节并不削弱修复结论:公告直接确认复用凭据,并要求每个 KnowledgeDeliver 实例使用独立、密码学强度足够的 machineKey。防守方可以证明新边界成立,而无须重现恶意对象图,也无须暴露原秘密。

一把巨大的红色钥匙连到三个各有围栏、各含两台服务器的 Farm;修复一侧则给每个 Farm 一把形状不同的钥匙。
图 1。共享只在一个逻辑 Farm 内有意发生。缺陷把互不相关的客户 Farm 接到同一签名者;修复是在保持各自节点一致的同时,为每个边界配置独立密钥对。

2 暴露是一种配置状态,不是简单版本范围

实际受影响集合由最终生效的 key、围绕它的应用上下文以及攻击者能否到达接收页面共同决定,因此部署日期只能用作初筛,不能直接充当结论。

2.1 公开公告给出两个必要条件

MNDT-2026-0009 列出两项受影响配置条件:组织没有更改默认预共享 ASP.NET machineKey,且应用可以被威胁行为者访问,公告用“开放在互联网”说明这种可达性。事件报告又把历史来源收紧到 2026 年 2 月 24 日前使用的标准化 web.config。这些信息足以启动按日期筛查,却没有说每套旧安装都仍有漏洞,也没有保证每套新安装天然安全。

旧客户可能已经生成独立值、把应用放进有效访问控制之后,或在迁移时替换配置。反过来,复制的备份、待命服务器、克隆测试环境或重新部署的镜像,也可能在厂商改流程后把旧值带回来。可辩护的分类必须结合每台现役和可恢复节点的有效配置、配置历史、部署来源与入口可达性。采购记录和页面显示的产品版本无法单独回答这些问题。

Digital Knowledge 产品页把 KnowledgeDeliver 描述为集教材制作、课程交付和学习者管理于一体的平台,并提供 ASP、On-Premises 与 Cloud 等部署形态。这个范围用于资产盘点,而不是证明暴露。托管环境、客户自管服务器和云镜像的所有权、入口及秘密交付路径可能完全不同;能看到应用版本的团队未必控制继承的 ASP.NET 配置,托管方也可能在共享基础设施上运行多个逻辑边界。

可达性会随时间改变。维护绕行、临时厂商规则、直连 origin 地址、备用端口或 failover VIP,可能只在 key 有效期的一部分时间暴露入口。不能只测试今天的路由;应复核 firewall 与 proxy 配置历史,并在适用且获授权时查看 certificate transparency、DNS 历史、负载均衡变更和支持访问记录。按时间区间记录从哪个网络位置可以到达哪些路径,同时写明证据覆盖和未知段。现在拒绝访问并不会抹去过去的利用机会,也不能替代对当时接收请求的 worker 与配置进行调查。

“攻击者可达”比公开 DNS 记录更宽。反向代理可能只发布部分路由,VPN 或身份网关能够限制入口,失陷合作方主机可能触达内网应用,旧灾备 URL 也可能在主站受限后继续开放。盘点要记录潜在客户端到应用的完整路径,包括 CDN、WAF、代理、负载均衡、备用域名、管理网络和陈旧发布规则,并从合适的外部位置实际测试策略。

限制访问是有价值的遏制措施,Mandiant 也把它列入缓解建议,但它不会撤销凭据。复制的 key 对今后重新获得网络路径的人仍然有效,并可能保护该应用中不止这一个请求。组织应当在准备协调轮换的同时收紧暴露,而不能因为防火墙规则暂时减少可达性就宣布修复完成。

2.2 有效配置可能不等于应用目录旁的文件

ASP.NET 配置具有层级。应用目录可见的 web.config 可以从父应用或机器级配置继承 machineKey,部署工具也可能在发布时变换文件。正确清单要记录继承和变换后最终生效的 system.web/machineKey、提供它的物理来源,以及交付到每个节点的配置修订。只搜索一个代码库或只打开一个文件,可能错过工作进程真正消费的值。

两个属性应作为一组凭据管理,又必须分别核验。validation key 支撑真实性判断;decryption key 在 ViewState 加密时支撑机密性,并参与较新的受保护数据格式。一个属性换新、另一个仍旧,不算完成轮换。比较系统要分别和组合计算解码后指纹,从而发现整组复用、局部复用、格式差异,以及只改一边的错误发布。

原始秘密绝不能集中进表格、支持工单、聊天记录或日志平台。更安全的比较在获批秘密处理边界内进行:规范化十六进制表示,输出组织内部 keyed digest、实例标识、key 角色、来源层和秘密版本;用于摘要的比较 key 本身也要保护。这样能够识别等价组,却不会新建一份可反推出漏洞材料的数据库。

每个 Farm 节点、被动节点、蓝绿槽位、扩容镜像、备份镜像和灾备模板都在范围内,因为一个旧成员就能撤销正确变更。它现在可能不接流量,但扩容或故障切换会让它带陈旧 key 回来。恢复介质同样重要:恢复轮换前镜像时,部署门禁必须阻止它上线,直到重新注入秘密。验收记录既要列活跃群体,也要列未来可能创建成员的机制。

采集配置后,还要证明运行中的应用确实加载了预期修订。ASP.NET 配置变化可以触发应用域回收,但部署竞争、锁文件、变换错误、容器层或被排除在作业外的节点,都可能让观察状态偏离期望状态。重启后重新取得有效指纹,把它绑定到新工作进程生命周期,并在该节点执行受保护页面。期望状态仪表板证明“已交付”,运行时指纹和行为才证明“已激活”。

配置加密改变静态存储暴露,却不会改变密码作用域。Microsoft Protected Configuration 可以避免 machine-key 节以明文落盘,访问控制可以限制谁有权解密;但三个客户各自加载同一个加密保存的值后,仍共享一个签名者。静态保护、边界唯一性、安全交付和可审计访问是四项独立控制,长期修复必须同时具备。

2.3 已知 key 仍需匹配接收端 Web Forms 上下文

machine-key 对是本漏洞必要条件,却不是所有 ASP.NET 应用的万能钥匙。请求必须到达处理客户端 ViewState 的页面,受保护值还要匹配页面所用算法、框架行为、应用与页面上下文、加密状态及其他修饰量。较新的 Reference Source 路径在主 purpose 之外,把页面模板源目录、页面类型名和可选 ViewStateUserKey 纳入子密钥派生。

旧兼容路径用不同方式绑定状态,包括页面派生的 MAC modifier 与可选用户 key。公开 KnowledgeDeliver 材料没有说明受害者使用哪种兼容模式或 .NET Framework 具体配置。因此本文追踪默认隐藏字段生命周期和较新密码实现,却不声称观测载荷走了某条未公开分支。本地评估必须记录 Framework 版本、应用池设置、有效 machineKey 算法与兼容模式,以及代表性页面行为。

如果应用在足够早的页面生命周期把 ViewStateUserKey 设置为不可预测的逐用户值,它会增加阻止状态跨用户转移的上下文。但它不能替代独立秘密:各页面实现可能不同,值可能不存在或可预测,而公告已经确认受影响产品遭到未认证利用。防守方应把它当成一个需测量的前提,不能从通用 ASP.NET 建议推定其存在,也不能据此推迟轮换。

端点同样属于证明。扫描器找到 __VIEWSTATE 只证明普通 Web Forms 行为。大型 Base64 字段、Event 1316 或 HTTP 500 都可能来自正常过期、Farm key 不一致、截断、代理改写或敌意输入。暴露评估应使用良性请求和配置证据,失陷评估则把接收 URI 与事件原因关联到进程、程序集、文件与网络效果。日常核验既不需要也不应使用可工作的恶意载荷。

安全核验止步于构造敌意状态之前。沿受支持用户旅程浏览代表性页面,记录 ViewState 是否存在、是否分片,并确认哪些节点接收由此产生的良性回发;再检查负责人能够取得的有效配置和源码,核实用户绑定与加密设置。这些观察足以建立接收面和测试计划,不需要猜测未披露 URL、整理 gadget 清单,也不需要向生产发送异常序列化对象。

由此形成三级范围结论。“历史候选”表示部署来源早于 2 月 24 日;“密码学暴露”表示有效 key 指纹匹配已知复用组且相关路径可达;“已失陷”则需要证据证明敌意状态跨过验证并产生执行或后渗透效果。分开这三种标签,既避免用干净磁盘扫描制造虚假安全,也避免把一个畸形回发直接升级为完整入侵。

判断所需证据它不能证明
历史候选部署、镜像或配置来源早于 2026 年 2 月 24 日。共享值仍生效,或应用可达。
密码学暴露受保护指纹比较确认复用 validation/decryption 材料,并存在可达的相关 Web Forms 路径。攻击者提交过上下文有效载荷。
尝试反序列化完整 Event 1316/4009 原因显示完整性通过而 ViewState 无效,并能连接到请求。对象图执行完成或命令运行。
已失陷进程、程序集、内存、文件、凭据或网络证据证明载荷效果。轮换已经移除持久化或修复学习者终端。
运维人员手持钥匙,周围依次环绕规格设计、本地生成、密封交付、Farm 部署、验证、监测、撤销与受保护归档。
图 2。暴露与关闭都存在于凭据生命周期:识别有效值、交付路径和等价组,再证明轮换、拒绝、监测与安全恢复,不能从产品版本推断安全。

3 请求依次跨过收集、purpose 绑定、密码处理与对象解释

公开 System.Web 源码说明被复制的部署秘密在何处变成受信任对象流;未披露的 KnowledgeDeliver 页面与 gadget 仍明确留在证据之外。

3.1 页面状态先重组,再进入普通回发处理

SOSEC 把 .NET Framework Reference Source 固定在提交 ec9fa9ae770d522a5b5f0607898044b7478574a3,避免函数名和行为随分支漂移。在 Page.ProcessRequestMain() 中,实际回发在初始化之后、ProcessPostData() 与页面 Load 事件之前进入 LoadAllState()。后者要求 LoadPageStateFromPersistenceMedium() 取得状态;该方法取出配置的 PageStatePersister 并调用 Load()

默认客户端持久化实现是 HiddenFieldPageStatePersister。它的 Load() 读取 Page.RequestViewStateString,再把页面状态格式化器和主用途 WebForms.HiddenFieldPageStatePersister.ClientState 交给 Util.DeserializeWithAssert()。返回值预期是包含 ViewState 和 control state 的 Pair。应用可以覆盖持久化行为,所以这是文档化的默认框架路径,不是对未公开 KnowledgeDeliver 自定义逻辑的断言。

RequestViewStateString 解释 HTTP 字段如何成为一份序列化值。若禁用分片或没有 __VIEWSTATEFIELDCOUNT,它直接返回 __VIEWSTATE;若存在计数,则转换计数、拒绝负值,再依次拼接 __VIEWSTATE__VIEWSTATE1__VIEWSTATE2 及后续分片。声明的任何分片缺失都会抛错。因此检测和证据采集必须保留字段计数及全部分片,而不是只保存第一段。

分片重组不等于密码接受,它只生成交给格式化器的文本。代理大小限制、截断、重复参数处理、表单解析差异或缺失分片,都可能在 MAC 判断前失败。解释 500 响应或“invalid viewstate”症状时,必须用请求捕获、框架事件详情与源码行为定位阶段。把每个解析错误都当成错误 key 的利用尝试,会淹没真正序列需要的信号。

源码还保留一个重要扩展点:LoadPageStateFromPersistenceMedium() 是 virtual,页面也可以选择不同 persister。产品可以把状态放在服务端,或包装默认行为。公开材料没有显示受影响 KnowledgeDeliver 页面这样做,Mandiant 又明确点名恶意 __VIEWSTATE。因此本文以默认隐藏字段处理流程作为有依据的解释路径,同时要求运行时证据存在后,才把每项默认源码细节应用到具体客户。

普通 IIS 日志通常记录时间、方法、URI、状态、耗时和 User-Agent,却不保存包含状态的 POST 正文。如果 WAF 或反向代理依法保留请求体,应把完整参数集放进受限证据存储,并记录任何规范化动作。没有正文时,仍可把 IIS 请求与 Event 1316、worker PID、应用池和端点遥测连接;调查人员应说明“提交字节不可得”,而不是根据假设重建。

多份密封状态卷轴先合并成一个包裹并压上封印,再经过目录、页面和用户上下文印章,最后走向上锁的格式化器保险柜。
图 3。字段重组、purpose 绑定和密码接受是不同阶段。复制的 key 只解决其中一部分;请求仍要契合接收应用和页面上下文。

3.2 显式配置仍处在主密钥根部

页面创建与自身关联的 ObjectStateFormatter。在较新密码路径中,格式化器在 persister 主 purpose 后加入更具体的 purpose:大写页面 TemplateSourceDirectory、大写页面类型名,以及存在时的 ViewStateUserKeyAspNetCryptoServiceProvider.GetCryptoService() 随后取得为这些 purpose 派生的加密和验证 key。purpose 限制可转移范围,但派生起点仍是应用配置的主材料。

MachineKeyMasterKeyProvider.GenerateCryptographicKey() 含有让配置复用成为关键的分支。函数把配置属性解析为十六进制;只要得到有效非空字节,就直接用这些字节构造 CryptographicKey。只有属性指定 AutoGenerate 时,provider 才取运行时自动生成材料的一部分,并可借 IsolateAppsIsolateByAppId 派生应用专属 key。源码因此支持一个严格结论:显式值被复制后,主密钥层仍然相同。

purpose 派生缩小同一主密钥能授权的数据范围,却不会让客户真正独立。同一根密钥加相同 purpose 输入,会产生相同的应用 purpose key。标准化虚拟路径和页面类型提高对齐概率,不同路径或用户 key 则可能让状态被拒。真正的租户边界不能依赖这些字符串的偶然差异:路由变化可能消除差异,根植于同一复制主密钥的其他 System.Web purpose 也仍在凭据暴露面内。

自动生成材料也有自己的运维约束。Microsoft 说明它保存在相关机器或应用池身份下,Reference Source 则根据运行时标识派生可选应用隔离。迁移应用、改变 identity profile 或恢复机器,都可能在改善唯一性的同时改变可用性。紧急事件中不能未经测试就切换存储模式;眼前不变式更简单:任何无关边界都不得继续持有已经披露的显式 key 对。

不能由此推出“所有场景都删除 machineKey”。Microsoft 说明,单服务器应用可以回到自动生成值,但 Web Farm 要在成员间使用兼容的固定值,使一个节点签发的状态能在另一个节点工作。KnowledgeDeliver 的正确动作遵循公告:每个实例边界生成独立强 key,再把同一组值部署到有意服务同一逻辑实例的全部节点。拓扑决定显式还是自动存储适用。

算法与兼容模式也必须进入清单。属性会选择验证和解密行为,Framework 版本同时存在较新的 purpose-derived provider 与旧保护路径。若轮换 key 字节时悄然改变算法,可能造成中断,也可能让验收测试走到不同路径。记录旧有效设置,与厂商和平台负责人选择受支持的新设置,在有代表性的非生产边界测试,再把 key 对与算法配置作为一次受控变更发布。

machine-key 影响超出一个序列化器,因为 System.Web 会按应用配置把它用作多个保护功能的根。因此发布测试包含登录、代表性回发和本地识别出的其他 protected-data 消费者;轮换后的支持症状要追到具体功能,而不是靠恢复旧值“修好”。消费者清单必须从实际应用和框架设置得到;闭源产品源码不可得,本文不会声称列出 KnowledgeDeliver 的完整专属清单。

key 相同表示授权根相同,并不证明客户 A 的密文可以原样复制到客户 B。purpose-derived key、页面名、虚拟路径、可选用户绑定与序列化预期都可能不同。漏洞成立,是因为标准化部署让足够多上下文重复,而共享 key 持有者可为目标上下文构造状态。防守结论仍是消除跨客户根密钥等价,证据结论则严格停在公告与公开源码可支持的范围。

3.3 较新 protected-data 路径先认证、后解密

ObjectStateFormatter.Deserialize(string, Purpose) 先拒绝空字符串并对输入执行 Base64 解码。当默认较新 provider 生效,且页面要求加密或 ViewState MAC 时,函数加入页面专属 purpose、取得密码服务,再调用 Unprotect();只有返回的明文字节才成为流反序列化输入。若应用强制旧密码模式,另一组函数执行解密验证或 MAC 解码,核心问题仍是状态是否在该应用秘密和上下文下被接受。

NetFXCryptoService.Unprotect() 把预期包络写成 initialization vector、加密载荷,以及覆盖前两者的签名。函数先检查输入是否容得下各部分,计算验证签名并与提交签名比较;不匹配时在解密前返回失败。匹配后才提取 IV,用派生 encryption key 配置对称算法,解密载荷并返回明文。这一顺序说明 validation key 是授权边界,而不是装饰性校验和。

旧分支进一步说明为什么必须记录运行条件。存在加密 ViewState 时,旧代码使用页面 MAC modifier 调用 machine-key 解密/验证;只有 MAC 保护时,则先解码并验证,再把剩余字节交给格式化器。它与 NetFXCryptoService 的实现和包络不同,但都会拒绝缺少可接受 key-derived 证明的状态。本文用较新函数展示明确的“认证后解密”,不声称 Mandiant 在受害者上观察到这个具体类。

掌握共享 key 对会改变比较的含义。没有 key 时,攻击者选择的字节通常止步于外层完整性决策;有 key 且 purpose 匹配时,攻击者能够产生框架期待由应用给出的密码证明。服务正确地认定载荷来自获授权 key 持有者,错误发生在部署已经让这条结论越过客户边界。不需要攻破密码原语,修复也不是再为一个序列化类增加过滤器。

当签名者同时拥有解密侧材料时,加密不会中和它。加密用来向无 key 方隐藏状态,MAC 防止未授权修改;标准化配置却把两种值同时暴露给独立部署。持有者可以准备目标会认证并打开的包络。关闭 ViewState 加密不能恢复真实性,保留共享 key 再开启加密也不会撤权,唯一且受保护的凭据才是控制性改变。

这一阶段的错误对诊断有价值,却不足以单独定案。签名失败、最小长度失败、畸形 Base64 或解密异常,都可能以不同细节表现为状态错误。调查应保留完整 ASP.NET 事件 Message 与可得的内部原因,关联请求时间,不能只压缩为“出现 Event 1316”。格式化器阶段也会拒绝已经认证的字节,这就产生 Mandiant 描述的更高优先级但仍非最终结论的“Viewstate was invalid”。

3.4 密码接受会把已授权字节交给丰富格式化器

移除保护后,ObjectStateFormatter 检查序列化流头与格式版本,创建 reader,再进入 DeserializeValue()。格式化器识别字符串、整数、数组、列表、Pair、Triplet、字典、indexed string 和类型等常见 Web Forms 状态的紧凑 token。这种广度服务于高效重建控件状态;安全假设是,不可信浏览器没有 validation secret,因而无法授权任意 token stream。

固定源码还包含 Token_BinarySerialized。遇到该 token 时,格式化器读取长度和嵌套字节缓冲,创建 BinaryFormatter,再对嵌套流调用 Deserialize()。这是公开源码中“已认证状态格式”进入通用对象反序列化的一处具体位置,足以解释签名者失陷为何危险;但它并不证明未公开 KnowledgeDeliver 利用使用了这个 token、gadget 或对象图。

因此 formatter exception 说明“走到哪里”,而不是给出二元安全结论。异常可能在创建危险对象前发生,也可能出现在类型解析中、constructor 或 converter 已运行后,或者嵌套 deserializer 已产生局部效果后。这正是 Mandiant 使用“可能执行也可能未执行”的原因。最终后果要由进程和主机遥测解析;HTTP 错误页不会把应用回滚到反序列化开始前。

Mandiant 公告提供产品专属结果:恶意 ViewState 路径能够导致操作系统级远程代码执行,真实事件也观察到未认证执行。Reference Source 提供从隐藏字段输入、密码接受到对象解释的公开框架机制。把这两层结合是有依据的;点名 KnowledgeDeliver 内部 handler、具体 gadget assembly 或载荷构造命令则属于推测,还会不必要地公开可操作利用细节。

同一边界也指导测试。防守验收可以提交组织自己在轮换前保存的良性状态并确认拒绝,再用新生成的合法页面验证 Farm 互操作,无需触发危险 formatter token。安全团队可以在隔离且获授权的实验室单独测试控制,但生产关闭不能依赖重现远程代码执行。真正要证明的属性是:旧签名者不再能够授权任何受保护应用状态。

这条机制也说明为什么封禁一个 User-Agent、载荷哈希或序列化标记不完整。共享签名者可以授权目标接受的其他状态编码,后渗透动作也可变化。网络签名适合识别已知活动,首要预防仍是边界唯一的秘密材料;失陷判断则依赖状态通过验证后的连续证据。两者分别处理根因与观测后果,而不是只处理样本。

一个密封包裹停在认证拦杆前,另一个通过完整性放大镜和解密舱,随后打开存放多种对象形状的柜子。
图 4。认证与解密只授权进入,并不会让每种对象图变得安全。公开源码展示多类原生 token 与 binary-serialized 分支,而事件中的确切对象图仍未披露。

4 证据要一路跟随:从状态拒绝到服务器与学习者影响

只有明确区分外层检查失败、认证后的反序列化尝试、w3wp.exe 内执行、持久化或文件改变,以及内容投递给学习者,调查结论才可靠。

4.1 Event 1316 有两种实质不同的含义

Mandiant 要求关注 Windows Application Event ID 1316,来源可能是 ASP.NET 4.0.30319.0,通常携带 event code 4009。Microsoft 把 4009 定义为 AuditInvalidViewStateFailure,即 ViewState 验证失败的主健康监测代码。因此事件号只是一个家族标签;原因文本和 detail 才能区分失败阶段,完整 Message 还可能保留可供重建的请求状态。

“The viewstate supplied failed integrity check”表示提交值没有在有效 key 和上下文下通过认证。它可能是攻击者用错 key,也可能是普通损坏、字段截断、Farm 节点 key 不一致或轮换后的旧页面。处理在认证格式化器路径前停止。该事件是狩猎线索和部署健康信号,却不能确认攻击者掌握共享凭据,更不能证明代码执行。

“Viewstate was invalid”在 Mandiant 事件中权重更高。其报告说明完整性校验通过、反序列化已尝试,但载荷可能执行也可能未执行。格式化器可能在认证后拒绝坏流,对象图可能产生局部效果后抛错,也可能缺少请求类型。准确标签应是“完整性通过后的反序列化尝试”,不能自动写成“成功利用”;相邻进程和文件证据决定下一步发生了什么。

健康监测配置会改变可见性。ASP.NET 可以把 Web event 交给配置的 provider,本地 Windows Application log 也会轮转,或在进入中心系统前被过滤。要确认每个节点的相关 provider 和 channel 是否启用、转发是否保留完整 Message、应用重启是否改变 source 名称。没有 1316 但采集禁用或有损的节点存在证据缺口;完整保留且没有关联活动,才是强得多的负面观察。

Mandiant 使用服务器 machine key 解开事件日志 Message 中记录的载荷字符串,并恢复出 BLUEBEAM 相关内容。由此,完整 Message 成为敏感证据对象:可能包含受保护状态、可执行内容、凭据材料或其他位置没有的指标。应把原始事件连同时间戳、provider 元数据、record ID、主机和正文导出到访问受控存储,不能把状态粘进普通工单,也不能交给未获批的在线解码服务。

Mandiant 报告中的双浏览器标识拼接 User-Agent 可以连接已观测活动,却既不是密码学前提,也不是稳定 actor 身份。保留原始 header、代理附加值和来源解释,再与接收事件及 worker 行为比较。只有字符串匹配而没有验证通过事件,仍只是线索;header 不同也不能为已通过完整性的请求洗清。这种层级避免方便的网络字符串压过框架自身处理证据。

上方密封包裹停在双封印闸门前,下方包裹穿过闸门并继续连到打开的档案柜、工作服务器、破损文档和取证灯。
图 5。完整性失败停在外层闸门;完整性通过但无效的状态已进入更深处理,但执行只有通过闸门后的进程、内存、文件与网络证据才能成立。

4.2 BLUEBEAM 把搜索范围从 Web 根文件推入 worker 内存

取得初始代码执行后,操作者把 BLUEBEAM(又称 Godzilla)作为 .NET 内存 Web Shell 部署到 w3wp.exe。它通过 HTTP POST 正文接收加密数据,允许继续执行命令或载荷。此驻留方式会绕过狭窄的文件检查:Web 根目录可以没有新增 Shell 页面,受影响应用池却仍在内存中承载恶意程序集和命令能力。

因此,在条件允许时,应在紧急回收之前采集易失证据。材料包括 worker PID 与启动时间、已加载 .NET 程序集和模块、可执行内存区域、活动连接、命令行、handle、AppDomain 信息及父子进程关系。采集要遵守组织取证流程,因为随意检查可能影响生产或改变证据。如果持续运行风险更高而必须立即终止,应先记录原因、准确时间与将损失的材料。

Mandiant 的狩猎建议点名 w3wp.exe 的异常子进程,以及观测命令 cmd.exe /cwhoamipowershell.exe。这些字符串并不专属于本次 actor,管理和应用功能也可能产生。若同一主机、同一应用池的完整性通过 ViewState 事件后,紧接新程序集、稀有子进程、可疑命令、外联、权限变更或 Web 应用身份不应做出的文件改变,置信度才明显上升。

范围由 worker 的安全上下文决定。记录应用池账户、Windows 权限、可写目录、数据库连接权限、可达共享、出站策略和进程可读取的秘密。这些能力定义任意代码的最大合理触达范围,却不证明攻击者使用了每一项权限。要把访问日志、数据库审计、凭据使用事件和网络遥测连接到执行窗口,再把“可能触达”升级为确认的机密性或完整性结论。

应用池回收会使关联复杂:同一小时内多个 w3wp.exe 生命周期可以服务同一站点,overlapped recycle 还会让新旧 worker 短暂并存。保留进程启停、PID 到 pool 映射、配置修订和 listener 交接;把 Event 1316 关联到真正处理它的 worker,而不是所有同名 executable。采到错误 PID 的内存可以干净,但相关 worker 可能早已退出。

公开 IOC LoadLibrary.dll 的 SHA-256 为 7c1f99dca8e5a7897892f9d224a6495023a2cfd2671697d229d355978c415ed2,命中可强关联公告中的 BLUEBEAM 样本,但未命中不能清场。Shell 可以只驻留内存,名称可变,后续阶段也可不同。哈希应与 assembly 元数据、内存扫描、进程祖先、HTTP 行为及可信基线结合,而不能成为唯一关闭条件。

操作者还调用 icacls,给 Everyone 授予 Web 应用目录完全控制。调查要重建变更前后 ACL、执行变更的 principal 与进程,以及宽松权限窗口内写入的全部文件。只恢复干净 JavaScript 而不修继承权限,会继续允许篡改;只恢复权限而不识别其间执行内容,则可能留下持久化或被盗凭据。

4.3 受信任学习门户变成面向用户的投递通道

Mandiant 观察到操作者修改应用 JavaScript。注入逻辑显示虚假安全告警,要求访问者安装所谓“security authentication plugin”,并静默加载远端恶意脚本。遵循诱饵的用户会得到假安装包,最终感染 Cobalt Strike BEACON。载荷 encryption key 纳入受害组织名称,说明这一步为具体组织准备,而不是通用无差别下载链。

这条序列把影响边界从 IIS 主机扩展到恶意资产提供期间收到它的每个浏览器。服务器是学习内容的可信来源,用户无须主动访问陌生恶意站点。调查必须确定坏文件版本最早和最晚时间、引用它的页面、CDN 或代理缓存、响应哈希与 ETag、加载页面的会话、远端脚本请求、安装包下载和端点执行。

缓存可能延长或切碎时间窗。修复 origin 文件不代表每个 CDN edge、反向代理、浏览器缓存或 service worker 同时停止提供坏字节。要逐层 purge 并验证,保留缓存日志和对象版本,并从有代表性的地域或网络测试路由。学习者清单应依据会话实际得到的内容版本,不能假定修复前全部请求恶意,也不能假定 origin 修复后全部请求干净。

即使被改响应正文已经丢失,远端资源证据仍能细分群体。DNS resolver、secure web gateway、TLS metadata、浏览器历史、下载 provenance、文件哈希和 EDR process tree,可以说明设备只是解析 actor 域名、真正拉取脚本、保存安装包,还是已经执行。每次转换都要有自己的时间和设备身份;共享 NAT 地址或用户账户只是关联候选,单独不足以认定端点感染。

不同用户组需要不同动作。浏览器只拿到干净页面的人无需恶意软件处置;收到被改 JavaScript 但远端域被拦的会话,需要证据保全与定向检查;拉取远端脚本或安装包的机器需要隔离调查;执行假安装包或出现 BEACON 行为,则进入完整端点和身份响应。通知应给出具体时间窗与动作,不能向所有人发送同一封笼统改密通知。

公开报告支持高机密性、完整性风险和 OS 级执行路径,却没有给出每个受影响实例的完整数据库访问或凭据窃取清单。本地团队要确认应用池身份、服务账户、文件 ACL、数据库角色和网络位置能够触达什么,再与真实遥测比较。最坏能力指导遏制,已观测证据支撑确认影响;二者不能合并为没有依据的事实陈述。

公开来源没有把 2025 年末 KnowledgeDeliver 行动归因给具名威胁组织。Godzilla、异常 User-Agent、ViewState 技术和按受害组织定制的 Cobalt Strike 材料支持活动导向的狩猎,但工具可共享也可仿冒。归因仍需独立基础设施、开发、目标选择和运营证据。响应不需要等 actor 名称:现有证据足以要求撤销信任根、保全链条、根除持久化并处理暴露学习者。

受影响服务器把修改后的应用资产通过门户送到三台学习者笔记本,其中一台显示警示色页面,外部远端资源仍连接在投递路径上。
图 6。可信应用资产改变后,事件出现第二类人群:只收到页面、拉取远端资源、下载安装包或执行载荷的学习者,需要逐级不同的证据和响应。

5 检测是一架证据阶梯,不是一组魔法字符串

团队需要一条统一工作流:盘点凭据边界、保全脆弱时间窗,并按照目前确认的最深阶段升级发现。

5.1 改变状态之前,先建立暴露与证据台账

从所有来源可能早于 2 月 24 日的 KnowledgeDeliver 生产、待命、灾备、测试、迁移和对外实例开始。逐项记录负责人、环境、逻辑应用边界、Farm 节点、虚拟路径、应用池身份、Framework 与兼容配置、入口、部署来源、有效 key 来源、受保护指纹、最后变更和日志保留。该台账把配置暴露连接到证据保管,防止一个遗忘节点或克隆把旧签名者带回。

在轮换和重建截断证据之前,保全最长可辩护的利用窗口。至少覆盖本地数据可追溯的 2025 年末并延伸到遏制完成。采集完整 Event 1316/4009、IIS 与反代日志、依法保留的 WAF 告警或正文、应用池回收和崩溃历史、EDR 进程事件、.NET assembly/module 遥测、DNS 与网络出口、文件完整性、部署日志、备份,以及与应用池触达范围相关的认证和数据库审计。

把来源统一到 UTC,同时保留原始时间戳与时区。关联键包括主机、应用池、worker PID 与生命周期、可信代理解释后的客户端地址、URI、request/correlation ID、User-Agent、依法使用的 session 和文件路径。NAT、负载均衡、pool recycle 与时钟偏差可能把请求连接到错误 worker,因此要记录变换规则,使另一名分析人员能够重现为何两件工件被视作同一序列。

请求正文、内存、应用数据库和学习者记录可能包含个人信息或受监管数据。扩大采集前,应记录事件处置授权、目的、可访问人员组、存储区域、保留周期,以及删除或法律保全要求;日常分析视图尽量最小化,并在可行时把身份查找与技术关联分开。隐私控制不等于丢弃决定性证据,而是通过可问责的保管流程收集必要对象,避免把完整内容复制到不受限工作区。若字段必须解封或关联到真实身份,还要记录谁在何时因何目的执行,并让导出与派生副本继承相同限制。

可信基线应来自签名发行物、部署工件和有时间及保管证明的事件前备份,而不能来自当前运行服务器。比较 .js.aspx.config、二进制、scheduled task、service、startup path、IIS module、handler mapping 与 ACL。面对内存风险,干净文件差异只是一个组件;进程内存、程序集证据或从可信介质重建,才把结论推进到 Web 根以外。

5.2 按跨越信任阶段的序列升级

最低一级是“有暴露、无活动”:受保护指纹确认跨实例复用,但保留数据中没有相关请求或事件。仍需立即轮换、记录证据缺口,并持续狩猎 key 有效期间。只有日志本来启用、完整保留且覆盖所有节点时,“没看到事件”才有负面意义;否则它只是未知。

下一级是被拒输入:完整性失败、畸形分片或无法认证的可疑 POST。数量、来源分布、重复目标 URI、Mandiant 描述的双浏览器 User-Agent 拼接,以及跨节点尝试都能提升优先级,但外层边界仍挡住请求。轮换后浏览器提交旧页面可能短暂增加 wrong-key 事件,应按时间、原因和客户端行为分类,而不能把全部 4009 一概压制。

完整性通过的“Viewstate was invalid”是持有可接受上下文与 key 的一方进入反序列化的第一个高置信信号。立即围绕同一 worker 生命周期核查稀有 assembly load、w3wp.exe 子进程、命令解释器、身份发现、网络连接、权限变化、应用文件写入及崩溃。若有正文,只能在隔离且获授权环境保全分析;生产团队无须执行它才可升级。

执行证据把案件推进为确认服务器失陷。关联到事件的 BLUEBEAM 工件、可疑内存程序集、子进程命令或未授权修改,足以启动遏制、易失采集、凭据范围判断和重建。学习者资产被改又形成下游分支:确定提供窗口、相关请求、远端 loader 流量、下载和端点结果。案件记录要逐服务器、逐用户写清确认阶段,而不能给整个组织只贴一个状态。

关闭是这架阶梯的逆向证明:新的跨客户 key 等价必须消失,旧状态必须失败,新状态必须在预期 Farm 节点之间工作,陈旧节点不得返回;重建服务器必须符合可信发行和 ACL 基线;可疑进程与网络链必须停止;每个学习者人群都完成其阶段对应动作。一次绿色漏洞扫描不能取代这些互相独立的证明。

信号解释立即动作
共享 key 指纹,无保留活动密码学暴露已确认;是否失陷未知。限制访问、保全可得证据、轮换并记录保留缺口。
完整性检查失败状态在认证反序列化前被拒。关联活动上下文与 Farm 健康,不标记执行。
完整性通过,ViewState 无效已尝试反序列化;载荷效果未解。把 worker 生命周期连接到内存、程序集、进程、文件与网络数据。
BLUEBEAM 或执行链服务器失陷已确认。保全易失证据、隔离、界定凭据并从可信介质重建。
被改资产向学习者提供下游客户端暴露,存在多个可能阶段。按接收、拉取、下载和执行遥测划分人群并处置。
取证人员沿一根连续线索,从密封状态包裹经过网络设备、事件铃、worker 机柜、访问闸门,最终抵达带污迹的应用文件。
图 7。可辩护单位是请求、事件原因、worker 生命周期、执行、权限或文件变化、外联与学习者投递组成的连续序列,而不是单独查看任何工件。

6 轮换撤销签名者,恢复清除签名者已经带来的后果

凭据修复和失陷恢复彼此相连却不是同一条工作流;仅仅出现新 web.config,两者都不能算完成。

6.1 先遏制可达性,再逐个逻辑 Farm 轮换

从符合业务要求且可逆的遏制开始:把 LMS 限制到已知组织地址或认证网关,移除陈旧发布规则,封禁确认恶意基础设施并保留日志。若证据指向正在失陷,按事件计划隔离服务器或 Farm。除非继续运行风险更大,否则不要在易失采集前回收可疑 w3wp.exe;要记录风险决定及准确遏制时间。

通过受支持 IIS 或本地密码工具生成新的 validation/decryption 值,不能用在线生成器,也不能从文档复制。Mandiant 要求每个 KnowledgeDeliver 实例使用独立且密码学强度足够的 machine key。Microsoft 提供 IIS Manager 和 PowerShell 生成方式,并解释拓扑选择:单机可用受保护的自动生成材料,一个 Web Farm 的所有节点则需要相同的新显式值。最终模型要和厂商及平台负责人确认。

把 Farm 发布当成一次协调应用变更。盘点每个节点和流量路径,备份配置但不把原始秘密导入变更工单,通过受保护通道暂存新值,排空流量或使用维护窗,把 key 对与算法设置应用到所有成员,再按受控顺序回收应用池。混合 key Farm 会拒绝其他节点签发的状态,正常用户旅程期间不能让流量在新旧签名者间来回跳转。

回滚设计不能让已失陷 key 成为最容易的恢复路径。保留经过测试、引用新秘密版本的应用和配置回滚,阻止自动恢复旧值,任何例外都需事件负责人批准。功能失败时先诊断算法、继承、节点与应用状态差异,再考虑改变密码信任。恢复共享签名者也许能恢复可用性,却会重新打开跨客户授权,这项安全后果必须明确写进决策。

轮换会有意让旧 key 保护的工件失效。旧页面提交的 ViewState 必须失败;取决于应用配置,Forms Authentication ticket 或其他 System.Web protected data 也可能失效。提前安排重新认证与刷新页面,说明维护影响,并监控 4009 原因,使预期 old-state rejection 不会被误认成持续利用,也能发现漏更节点。

从每个配置源、部署变量、镜像、备份流程、自动化可访问的 Secret Store 版本和 break-glass 文档中移除旧值。重新开放流量前停用陈旧节点。只把新 secret version 与受保护指纹登记到预期 Farm 组,不保存原值。应用包升级而不撤销共享 key,不满足公告修复要求;主站更新而灾备镜像仍旧,同样不满足。

6.2 已失陷服务器与暴露学习者需要分别恢复

若证据支持利用,轮换能阻止旧 key 继续签状态,却无法移除 BLUEBEAM、逆转未授权 ACL、恢复 JavaScript 或撤销代码执行后拿到的凭据。Microsoft 的 machine-key 处置指南明确警告:成功利用后只轮换不够,并建议对发现公开 key 的互联网服务器全面调查,强烈考虑离线重格式化和重装。恢复应优先从可信介质重建,而不是尝试宣布一台已被修改的主机“已清理”。

重建前先保全用于理解触达范围并满足法律或监管要求的证据。随后用验证过的来源替换操作系统和应用层,应用受支持 KnowledgeDeliver 与 .NET 更新,只恢复已审核数据,按批准基线重建 IIS 配置与 ACL,部署边界唯一的新 key,并轮换应用池身份能够读取或内存中出现的凭据。服务账户、数据库秘密、API token、签名材料、部署凭据和管理会话要按真实访问与证据划界,而不是自动轮换全企业一切。

安排顺序,使恢复系统永远不再用已经存在于失陷主机上的凭据认证。通过干净管理路径创建或轮换秘密,隔离状态下重建服务器,注入新值,使旧 session 和 token 失效,再连接依赖与流量。恢复前审核备份,因为可信时间戳不保证其中配置或脚本干净。证据副本要和运维备份分开保留,后续分析无须把可疑镜像重新投入服务。

在文件、配置、module、handler、scheduled task、service 与权限层面,把重建应用和可信发行版比较。确认应用池不能在无需要处广泛写入,远端脚本和未授权 redirect 已消失。如果恢复既有数据库,应在重新连接前审查窗口内的管理变更与数据访问。干净服务器镜像无法撤销恶意数据库账户,也无法让其他位置仍有效的被盗凭据失效。

学习者分支使用自己的证据台账。保全被改 JavaScript 与投递日志,确定提供时间窗,识别返回它的页面与缓存,再按页面接收、远端脚本拉取、安装包下载和执行分组。代理、DNS、浏览器、EDR 及支持记录可细化群体。隔离调查执行诱饵或出现 BEACON 的终端,并为更大群体提供与观测阶段相符的浏览器、端点和凭据操作。

恢复沟通必须区分“暴露、确认服务器失陷、确认端点感染”。说明复核了哪个期间、哪些工件支撑结论、哪些材料不可得以及用户该做什么。若诱饵、端点证据或服务器权限让凭据泄露具有合理可能,执行密码或 token 重置;但重置不能替代端点遏制。服务器和学习者工作流只有分别形成验收证据,并由负责人签署剩余风险后才能关闭。

旧共享钥匙封入证据袋,三个各有围栏、各含两台服务器的 Farm 收到三组不同 key,验证托盘显示功能正常、节点一致、旧状态拒绝与旧 key 退役。
图 8。轮换是理解拓扑后的撤权:一个 Farm 内节点保持一致,无关 Farm 必须不同,归档旧状态失败,旧共享值也从每条可能恢复它的路径中移除。

7 关闭由一组正向与负向证明组成

团队必须证明密码边界恢复、应用与服务器可信、学习者人群得到处置,并且共享值不会回流,调查才算结束。

7.1 验证互操作、撤销、唯一性与恢复

先证明预期互操作。在每台负载均衡节点启动新登录,执行会产生和消费 ViewState 的代表性页面;把请求固定到各节点,再跨节点验证一个节点签发的状态能被同一逻辑 Farm 的其他节点接受。记录节点身份、应用池启动时间、配置修订、秘密版本、测试 URI、时间和结果。普通健康检查接口不会覆盖这次变更影响的受保护状态路径。

再用组织自己的应用在轮换前捕获的良性材料证明撤销。在受控测试提交一份归档普通页面状态,确认新 key 下被拒,并检查所有节点的原因符合旧 key 失败,没有陈旧节点接受。日常生产验收不使用共享脆弱 key 或恶意对象图。测试问题是“原授权是否撤销”,不是“能否重现代码执行”。

随后证明唯一性。在获批比较系统内计算每个节点 validation/decryption 材料的受保护指纹。同一声明 Farm 组内节点应匹配,无关客户、环境与独立实例不应匹配;局部匹配和整组匹配都要调查。对未启用镜像、灾备自动化与部署模板重复比较,并在未来克隆意外获得既有边界指纹时让部署直接失败。

若环境因失陷重建,验证还要越过密码学。确认 OS 与应用来自可信工件,文件和配置哈希符合批准发行,ACL 符合最小权限,没有未批准 module/handler,应用池内存从重建镜像启动,出站行为符合文档应用;数据库与身份变化另行验证。保留前后证据,使审核无需信任曾被失陷的同一主机。

最后回放检测工作流。预期旧状态失败应在维护窗后下降;完整性通过的 invalid-state 序列不应继续;w3wp.exe 不应启动无法解释的子进程或加载未批准程序集;应用文件和权限应稳定;学习者终端不应继续访问已记录投递链。观察期按流量和保留设计,而不是套一个任意天数,并明确事件团队退出后由谁审核告警。

验收属性正向证明负向证明
Farm 连续性新状态在每个预期节点间正常工作。任何节点都不会对新状态产生密钥不匹配。
旧签名者撤销新配置修订与 secret version 已生效。良性轮换前归档状态在每个节点都失败。
客户隔离每个声明边界拥有独立受保护指纹。没有无关边界或未启用模板复用任一旧值。
服务器恢复可信 build、ACL、module、数据和凭据复核已签字。没有无法解释的内存、进程、文件或外联序列。
学习者恢复每个暴露人群都有负责人且动作完成。没有下载、执行或 BEACON 证据未分诊。

7.2 长期控制不能让部署便利再次扩大信任

只有当新安全边界获得唯一身份后,部署系统才生成秘密。把它放入受管秘密系统或受保护部署通道,只允许必要服务与运维读取,并在不打印到构建日志的情况下注入。基础设施模板保存引用,不保存可复用 key 字节。发布流水线记录秘密版本和受保护指纹、执行唯一性检查,并拒绝发布尚未取得独立凭据的克隆。

静态保护和访问监测降低一台服务器成为下一次攻击来源的概率。Microsoft 文档说明可用 Protected Configuration 加密敏感 web.config 节;其 machine-key 威胁指南建议监测配置访问,包括在正确配置 audit policy 与文件 SACL 时使用 Windows Event 4663。按应用池和管理进程调校预期 reader;陌生身份或 executable 的事件是狩猎线索,不是自动的 key 窃取证明。

把确认或疑似 key 泄露当作签名权事件处理,即便尚未发现载荷。记录哪些边界使用该值、每份副本何时有效、谁与什么进程可读取,以及哪些受保护工件仍活动;在整个等价组撤销,而不是只修首台告警服务器。有证据时,负责人可以把“利用”关闭为未观测,但在每份副本和恢复路径完成清点前,不能关闭凭据暴露。

轮换需要演练过的操作手册,而不是只勾一个到期选项。操作手册列出 Farm 成员、流量排空方式、预期认证和 ViewState 影响、回滚权限、秘密交付、陈旧节点控制、良性旧状态测试、指纹比较、监测负责人与证据记录。定期演练要证明边界能在不复制别家秘密的情况下轮换,回滚也不能恢复撤销值;轮换周期由策略和暴露决定,怀疑泄露则立即轮换并调查。

治理还要追踪边界变化。合并 Farm、拆分租户、在托管与客户自管间迁移、增加灾备区域或把生产克隆到测试,都会改变哪些节点可以合法共享状态。把秘密作用域审查设为这些架构决策的必选项。规则足以自动化——声明的节点可以相同,未声明边界不得相同——但声明本身需要业务和安全负责人,防止便利默默扩大信任组。

平台加固提供纵深防御,却不替代边界修复。应用厂商支持的 KnowledgeDeliver 与 .NET 更新,减少公开可达性,让应用池以最小权限运行,限制 Web 资产写入,监控文件完整性和子进程,并在兼容时评估 ASP.NET 4.8 AMSI 与服务器 attack-surface 控制。这些措施能发现或阻碍后渗透,却都不能让已知共享 validation key 变安全,也不能为部署方便而继续保留它。

最终记录必须保留仍未知的范围。公开报告没有点名 KnowledgeDeliver 页面、观测到的 Framework 兼容分支、确切 serialization token 或 gadget、完整受影响客户集合,也没有 actor 归因。这些缺口不能用推断填满。可确认内容已经足够且可测量:2 月 24 日前标准部署可能共享签名者;可达且未换 key 的实例能够接受恶意 ViewState 并抵达 OS 级执行;真实行动延伸到服务器内存与受信任学习者内容;独立 key、证据驱动恢复与明确验收能够重建边界。今后每次拓扑或凭据变化都必须保留这份证明。

研究记录

8证据、对象与来源

下面保留本文实际使用的标识、时间和原始材料,便于继续调查。

8.1可检索观测值

来自引用材料或本次调查的值,并附有使用这些值所需的上下文。

类型说明操作
SHA-2567c1f99dca8e5a7897892f9d224a6495023a2cfd2671697d229d355978c415ed2公开的 BLUEBEAM LoadLibrary.dll 哈希

8.2研究对象

报告涉及的产品、行为者、技术、受影响对象和控制点。

CVECVE-2026-5426

KnowledgeDeliver 硬编码共享 machineKey 导致未认证 ViewState 代码注入

HTTP 字段__VIEWSTATE

正常 ASP.NET 受保护页面状态输入;字段存在本身不代表恶意

Windows 事件Event ID 1316 / Event code 4009

保留完整 ViewState 失败原因和 Message,用于判断处理阶段

进程w3wp.exe

承载内存 BLUEBEAM 的 IIS worker;关联异常子进程、程序集和网络活动

命令icacls

观测到的权限修改工具;结合 Everyone 完全控制与 Web 根写入判断

文件LoadLibrary.dll

KnowledgeDeliver 事件中公开的 BLUEBEAM 相关文件名

HTTP 模式Concatenated dual-browser User-Agent

Mandiant 描述的活动关联点;单独不足以证明利用

8.3事件时间

  1. KnowledgeDeliver 事件调查

    Mandiant 响应一台失陷 LMS Web 服务器,把未认证执行追到客户部署之间相同的 machineKey。

  2. 问题报告给 Digital Knowledge

    Mandiant 与厂商开始协调处置。

  3. 部署流程更新

    Digital Knowledge 改变部署流程,处理共享 key 条件。

  4. 讨论公开披露

    Mandiant 与 Digital Knowledge 进行 MNDT-2026-0009 记录的披露沟通。

  5. MNDT-2026-0009 发布

    Mandiant 披露受影响配置、CVSS 向量与独立 key 解决方案。

  6. 事件与狩猎报告发布

    Mandiant 公开 BLUEBEAM、文件篡改、学习者投递、IOC 与 Event 1316 语义。

  7. SOSEC 完成框架源码复核

    SOSEC 固定 Microsoft Reference Source 修订,并追踪字段重组、key 使用、密码解保护与对象格式化。

8.4来源与材料

  1. Mandiant:KnowledgeDeliver 利用、后渗透、狩猎与 IOChttps://cloud.google.com/blog/topics/threat-intelligence/knowledgedeliver-viewstate-deserialization-vulnerability
  2. 固定在仓库提交 4005e5a 的 Mandiant 公告 MNDT-2026-0009https://github.com/mandiant/Vulnerability-Disclosures/blob/4005e5a11a47fda91ea4524bb3bf1c4f6d5348ad/2026/MNDT-2026-0009.md
  3. CVE 记录:CVE-2026-5426https://www.cve.org/CVERecord?id=CVE-2026-5426
  4. Digital Knowledge:KnowledgeDeliver 产品能力与部署形态https://www.digital-knowledge.co.jp/product/kd/
  5. Microsoft:公开 machine key 导致的 ViewState 代码注入、轮换与狩猎指南https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/
  6. 固定修订的 Microsoft .NET Framework System.Web Reference Sourcehttps://github.com/microsoft/referencesource/tree/ec9fa9ae770d522a5b5f0607898044b7478574a3/System.Web
  7. Microsoft Reference Source:Page 请求生命周期与 ViewState 字段重组https://github.com/microsoft/referencesource/blob/ec9fa9ae770d522a5b5f0607898044b7478574a3/System.Web/UI/Page.cs
  8. Microsoft Reference Source:HiddenFieldPageStatePersisterhttps://github.com/microsoft/referencesource/blob/ec9fa9ae770d522a5b5f0607898044b7478574a3/System.Web/UI/HiddenFieldPageStatePersister.cs
  9. Microsoft Reference Source:ObjectStateFormatter purpose 绑定与 token 反序列化https://github.com/microsoft/referencesource/blob/ec9fa9ae770d522a5b5f0607898044b7478574a3/System.Web/UI/ObjectStateFormatter.cs
  10. Microsoft Reference Source:显式与自动生成 machine-key 材料https://github.com/microsoft/referencesource/blob/ec9fa9ae770d522a5b5f0607898044b7478574a3/System.Web/Security/Cryptography/MachineKeyMasterKeyProvider.cs
  11. Microsoft Reference Source:受保护数据的认证与解密顺序https://github.com/microsoft/referencesource/blob/ec9fa9ae770d522a5b5f0607898044b7478574a3/System.Web/Security/Cryptography/NetFXCryptoService.cs
  12. Microsoft:machineKey 元素与 Web Farm 配置https://learn.microsoft.com/en-us/previous-versions/aspnet/w8h3skw9(v=vs.100)
  13. Microsoft:排查 invalid ViewState 与 Web Farm key 一致性https://learn.microsoft.com/en-us/troubleshoot/developer/webapps/aspnet/performance/troubleshooting-view-state-is-invalid-error
  14. Microsoft:AuditInvalidViewStateFailure event code 4009https://learn.microsoft.com/en-us/dotnet/api/system.web.management.webeventcodes.auditinvalidviewstatefailure
  15. Microsoft:使用 Protected Configuration 保护 Web.config 节https://learn.microsoft.com/en-us/previous-versions/aspnet/dtkwfdky(v=vs.100)
  16. Microsoft:ASP.NET health monitoring 与 event providerhttps://learn.microsoft.com/en-us/previous-versions/aspnet/bb398933(v=vs.100)
  17. Microsoft:协调 ASP.NET ViewState key 轮换示例https://learn.microsoft.com/en-us/sharepoint/security-for-sharepoint-server/improved-asp-net-view-state-security-key-management