某云星空的前台反序列化和任意文件上传漏洞分析
字数 2430 2025-08-20 18:18:16

某云星空前台反序列化和任意文件上传漏洞分析

环境搭建

所需环境

  • 操作系统:Windows Server 2012
  • 软件版本:金蝶云星空 7.6
  • 建议使用云服务器或纯净虚拟机进行搭建

调试工具

  • dnSpy调试工具(推荐使用v6.1.8 win64版本)
    • 下载地址:https://github.com/dnSpy/dnSpy/releases/tag/v6.1.8

调试环境配置

  1. 添加系统环境变量:COMPLUS_ZapDisable = 1
  2. 调试IIS进程:
    • 进入C:\Windows\System32\inetsrv目录
    • 执行appcmd list wp查看应用程序池进程ID
  3. 使用dnSpy附加进程:
    • 打开dnSpy,选择"调试"->"附加到进程"
    • 选择相应的进程ID并附加
    • 在"调试"->"窗口"->"模块"中搜索要调试的程序集
    • 双击程序集,在程序集资源管理器中找到要调试的类并打断点

反序列化漏洞分析

漏洞入口

  • 源码位置:C:\Program Files (x86)\Kingdee\K3Cloud\WebSite
  • web.config配置文件中,.kdsvc后缀文件由KDServiceHandler处理
    • 处理类:Kingdee.BOS.ServiceFacade.KDServiceFx.KDServiceHandler,Kingdee.BOS.ServiceFacade.KDServiceFx

请求处理流程

  1. KDServiceHandler返回KSDVHandler处理请求
  2. KSDVHandlerProcessRequest方法中处理请求
  3. 通过Action类进入ProcessRequestInternal
  4. 进入ExecuteRequest方法
  5. 进入StartRequest
  6. 进入BeginRequest方法处理会话session
  7. 调用RequestExcuteRuntime.pipeline.ExcuteRequest(kdserviceContext)
  8. 最终调用ExecuteServiceModuleOnProcess方法

关键点分析

1. GetServiceParameters()

  • requestExtractorKDSVCHandler#ProcessRequest中通过Create()方法初始化
  • 将JSON body参数转换为key-value的form
    • 如果Content-Type: text/json,使用JQueryRequestExtractor转换
    • 否则直接作为key-value的form

参数获取方式:

  1. 如果POST参数中有parameters,获取后变成JSON数组
    • Payload示例:{"format": 3, "parameters": "[\"gadget\"]"}
  2. 否则参数可以为pparamsap0形式
    • Payload示例:{"ap0":"gadget","format":"3"}
    • 或:{"pparams":"gadget","format":"3"}

2. new SerializerProxy()

  • 根据传入的format选择对应的SerializerProxy(JSON或Binary)
  • format=3对应BinaryFormatterProxy

3. this.executor.Execute()

  • 调用相应的serializer进行反序列化
  • 使用BinaryFormatterProxy
  • this.encoder.Decoding支持多种编码方式(Base64或Hex)

漏洞复现

使用ysoserial.net生成payload:

ysoserial.exe -o base64 -f BinaryFormatter -g ClaimsIdentity -c "cmd /c \"ping xxxx\""

补丁分析

补丁直接禁用了二进制序列化方式

任意文件上传漏洞分析

漏洞位置

  • 处理类:ScpSupRegHandler(继承IHttpHandler接口)
  • 配置文件位置:\WebSite\App_Data\Common.config
  • 配置文件加载:通过FileConfig.xml.deploy加载Common.config

漏洞分析流程

  1. ScpSupRegHandlerProcessRequest方法处理路由
  2. 如果是POST方法且是文件上传格式,进入SavaAttach方法
  3. SavaAttach方法中:
    • context.Request.Files[0]获取HTTP请求中的第一个文件
    • Path.GetExtension(httpPostedFile.FileName)获取文件扩展名
      • 处理方式:去掉点号,转换为小写
      • 例如:test.aspx.txt.txttest.aspx.取空字符串
  4. 检查扩展名:"abc".Contains(value)
    • 当value为空时,字符串包含空,可绕过检查
  5. 需要添加FIDdbId_v参数
  6. 文件上传时利用Windows特性:
    • 文件名中的../可进行路径遍历
    • Windows会删除文件名最后的点号

漏洞利用技巧

  1. 文件扩展名检查使用Contains方法,空扩展名可绕过
  2. 利用Windows处理文件名时删除最后点号的特性

POC示例

POST /路径 HTTP/1.1
Host: target
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxxxx

------WebKitFormBoundaryxxxx
Content-Disposition: form-data; name="FID"

任意值
------WebKitFormBoundaryxxxx
Content-Disposition: form-data; name="dbId_v"

任意值
------WebKitFormBoundaryxxxx
Content-Disposition: form-data; name="file"; filename="test.aspx."
Content-Type: application/octet-stream

恶意文件内容
------WebKitFormBoundaryxxxx--

总结

反序列化漏洞要点

  1. 路由通用性:只要能进入KDSVCHandler的路由都可利用
  2. JSON参数格式灵活:parameterspparamsap0均可
  3. 编码方式多样:支持Base64和Hex编码
  4. 请求格式:支持JSON格式和常规POST参数

文件上传漏洞要点

  1. 利用Contains方法检查扩展名的缺陷
  2. 利用Windows处理文件名的特性
  3. 需要配合FIDdbId_v参数

这两个漏洞的组合利用可以实现在目标系统上执行任意代码和上传恶意文件,危害性较高。

某云星空前台反序列化和任意文件上传漏洞分析 环境搭建 所需环境 操作系统:Windows Server 2012 软件版本:金蝶云星空 7.6 建议使用云服务器或纯净虚拟机进行搭建 调试工具 dnSpy调试工具(推荐使用v6.1.8 win64版本) 下载地址:https://github.com/dnSpy/dnSpy/releases/tag/v6.1.8 调试环境配置 添加系统环境变量: COMPLUS_ZapDisable = 1 调试IIS进程: 进入 C:\Windows\System32\inetsrv 目录 执行 appcmd list wp 查看应用程序池进程ID 使用dnSpy附加进程: 打开dnSpy,选择"调试"->"附加到进程" 选择相应的进程ID并附加 在"调试"->"窗口"->"模块"中搜索要调试的程序集 双击程序集,在程序集资源管理器中找到要调试的类并打断点 反序列化漏洞分析 漏洞入口 源码位置: C:\Program Files (x86)\Kingdee\K3Cloud\WebSite web.config配置文件中, .kdsvc 后缀文件由 KDServiceHandler 处理 处理类: Kingdee.BOS.ServiceFacade.KDServiceFx.KDServiceHandler,Kingdee.BOS.ServiceFacade.KDServiceFx 请求处理流程 KDServiceHandler 返回 KSDVHandler 处理请求 KSDVHandler 在 ProcessRequest 方法中处理请求 通过 Action 类进入 ProcessRequestInternal 进入 ExecuteRequest 方法 进入 StartRequest 进入 BeginRequest 方法处理会话session 调用 RequestExcuteRuntime.pipeline.ExcuteRequest(kdserviceContext) 最终调用 ExecuteServiceModule 的 OnProcess 方法 关键点分析 1. GetServiceParameters() requestExtractor 在 KDSVCHandler#ProcessRequest 中通过 Create() 方法初始化 将JSON body参数转换为key-value的form 如果 Content-Type: text/json ,使用 JQueryRequestExtractor 转换 否则直接作为key-value的form 参数获取方式: 如果POST参数中有 parameters ,获取后变成JSON数组 Payload示例: {"format": 3, "parameters": "[\"gadget\"]"} 否则参数可以为 pparams 或 ap0 形式 Payload示例: {"ap0":"gadget","format":"3"} 或: {"pparams":"gadget","format":"3"} 2. new SerializerProxy() 根据传入的 format 选择对应的 SerializerProxy (JSON或Binary) format=3 对应 BinaryFormatterProxy 3. this.executor.Execute() 调用相应的serializer进行反序列化 使用 BinaryFormatterProxy this.encoder.Decoding 支持多种编码方式(Base64或Hex) 漏洞复现 使用ysoserial.net生成payload: 补丁分析 补丁直接禁用了二进制序列化方式 任意文件上传漏洞分析 漏洞位置 处理类: ScpSupRegHandler (继承 IHttpHandler 接口) 配置文件位置: \WebSite\App_Data\Common.config 配置文件加载:通过 FileConfig.xml.deploy 加载 Common.config 漏洞分析流程 ScpSupRegHandler 的 ProcessRequest 方法处理路由 如果是POST方法且是文件上传格式,进入 SavaAttach 方法 在 SavaAttach 方法中: context.Request.Files[0] 获取HTTP请求中的第一个文件 Path.GetExtension(httpPostedFile.FileName) 获取文件扩展名 处理方式:去掉点号,转换为小写 例如: test.aspx.txt 取 .txt , test.aspx. 取空字符串 检查扩展名: "abc".Contains(value) 当value为空时,字符串包含空,可绕过检查 需要添加 FID 和 dbId_v 参数 文件上传时利用Windows特性: 文件名中的 ../ 可进行路径遍历 Windows会删除文件名最后的点号 漏洞利用技巧 文件扩展名检查使用 Contains 方法,空扩展名可绕过 利用Windows处理文件名时删除最后点号的特性 POC示例 总结 反序列化漏洞要点 路由通用性:只要能进入 KDSVCHandler 的路由都可利用 JSON参数格式灵活: parameters 、 pparams 或 ap0 均可 编码方式多样:支持Base64和Hex编码 请求格式:支持JSON格式和常规POST参数 文件上传漏洞要点 利用 Contains 方法检查扩展名的缺陷 利用Windows处理文件名的特性 需要配合 FID 和 dbId_v 参数 这两个漏洞的组合利用可以实现在目标系统上执行任意代码和上传恶意文件,危害性较高。