SharePoint又一个绕过:CVE-2026-33112从XmlValidator限制到低权限RCE
幻泉之洲
2026年7月13日 09:24
北京
在小说阅读器读本章
去阅读
微软修了CVE-2025-53770的泛型类型解析问题,却在XmlValidator里留了个盲区——它完全没管从网络加载的外部schema。配合PerformancePoint服务里的ExcelDataSet反序列化触发点,任何站点成员都能拿shell。补丁打了,但等于白打。
补丁打了一半,留下了后门
CVE-2025-53770的第二次补丁引入了一个新的TypeNameParserImpl,专门处理DataSet里类型名解析的问题,堵死了利用泛型名称的老路。但说句实话,这个补丁太盯着代码逻辑本身,却忘了XML Schema体系一个基础功能——schema import。
当你用XSD定义DataSet结构时,完全可以通过从网络加载外部schema文件。补丁里的XmlValidator只会检查你直接提交的那段XML,对于import进来的外部定义它根本不看。这就好比机场安检只检查旅客随身行李,却不管托运的箱子——防了个寂寞。
XmlValidator到底在干什么
DataSet的序列化过程经过DataSetSurrogateSelector,它只允许\"XmlSchema\"和\"XmlDiffGram\"两种内容。ValidateXml方法遍历文档里的每个元素,检查msdata:DataType、msdata:InstanceType等属性值是否属于白名单类型。白名单里当然没有System.Type这些危险玩意儿。
但是,一旦你用xs:import引入外部schema,那些外部schema里定义的类型声明压根不会出现在你提交的XML文档里。ValidateXml只遍历doc.Descendants(),外部schema定义的namespace和类型约束它根本不知道。验证通过。
从ExcelDataSet到RCE的链条
ExcelDataSet是一个公认的不安全数据集控件,只要触发它的DataTable getter就会执行反序列化。问题是怎么在代码里找到这个触发点?PerformancePoint的Web服务给出了一个现成的入口。
在/\_vti\_bin/PPS/PPSAuthoringService.asmx里有个TestConnection方法,接收一个DataSource对象。调用栈一路往下:
- BIMonitoringAuthoringService.TestConnection()
- BIMonitoringServiceApplication.TestConnection()
- PmServer.TestConnection()
- ServerHelper.TestDataSourceConnection()
- DataSourceRegistry.GetDataSource()
- ExcelDataSourceProvider.SetDataSource()
倒数第二步会根据DataSource.SourceName动态创建数据源提供程序。如果SourceName是\"ExcelWorkbook\",就会实例化ExcelDataSourceProvider,然后调用SetDataSource。在这里,XmlSerializer把dataSource.CustomData字段反序列化为ExcelDataSet对象,紧接着就访问excelDataSet.DataTable。DataTable的getter内部会走BinarySerialization.Deserialize处理一个压缩Base64字符串,触发命令执行。
所以整个利用思路很清晰:构造一个包含外部schema引用的XmlSchema,和对应的XmlDiffGram,通过TestConnection提交。XmlValidator检查时看不到被import的schema里的危险类型,但XmlSerializer在构建完整schema时会去网络加载外部定义,从而用上我们想要的类型,触发反序列化。
外部schema的把戏
攻击者在自己控制的HTTP服务器上放一个common.xsd,里面定义一个类型,把msdata:InstanceType设为System.Configuration.Install.AssemblyInstaller之类的危险类型。主schema像这样:
XmlValidator只看到一个对common:PayloadType的引用,但不会去解析schemaLocation指向的文件,所以PayloadType的实际定义(带危险InstanceType)它不知道,放行。
而服务端XML Schema编译过程会在System.Xml.Schema.Preprocessor.LoadExternals处下载common.xsd,把那个类型完整加载进来,于是反序列化时恶意类型被成功使用。
攻击者提供的common.xsd大概长这样:
配合的XmlDiffGram用来传入压缩的序列化Payload:
Deserialize
利用的门槛与技巧
调用TestConnection需要一个ItemUrl参数,指向SharePoint列表里一个真实存在的Item,而且URL末尾必须跟一个正则匹配数字结尾的片段。比如你的列表URL是/sites/zdi/Lists/test/,Item ID是1,那ItemUrl得写成/sites/zdi/Lists/test/1\.123。后面加个“\.123”就能绕过正则检查,又不会影响列表项定位。
攻击者还得有台SharePoint服务器能访问到的HTTP服务器,用来托管common.xsd。现在很多内网能出公网,这个条件并不算苛刻。
另外,绕过安全控件检查也有一些已知CVE,这里先不展开,但利用链本身依赖ExcelDataSet类不在黑名单里。好在PerformancePoint在很多企业部署中都是默认存在的,鲜有人特意去收紧安全控件列表。
这个漏洞告诉我们什么
微软修漏洞的思路往往是哪儿漏补哪儿,但DataSet这种复杂对象的序列化体系,堵上一个入口很容易被另一个花式绕过。XmlValidator的设计假设是“检查所有可能出现的类型声明”,却完全忽略了外部schema导入这个完全合规的XML Schema特性。说白了,验证器只检查了提交内容本身,没有模拟完整的schema编译过程。
对防守方来说,监控对/\_vti\_bin/PPS/PPSAuthoringService.asmx的调用、限制服务账户的出站HTTP请求、定期审查反序列化类型白名单,这些都比干等补丁要实际得多。
这条利用链虽然步骤不少,但每一步都是标准功能的组合,没有需要复杂堆叠的技巧。唯一的小障碍是那个ItemUrl的正则,加个“\_.123”就破了,完全算不上安全措施。它再次说明一个老道理:在反序列化战场上,只要还在用黑名单,就永远别想睡安稳觉。隔离和权限最小化才是正解。
参考资料
[1] https://blog.viettelcybersecurity.com/cve-2026-33112/
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论