用友U8Cloud ServiceDispatcherServlet 三种反序列化方式和深入利用研究
字数 2525 2025-10-01 14:05:52

用友U8Cloud ServiceDispatcherServlet 反序列化漏洞分析与利用研究

1. 前言

用友U8 Cloud近期曝光了多个可链式利用的安全缺陷,其中ServiceDispatcherServlet的反序列化入口是核心攻击向量。攻击者可通过此漏洞组合实现"先获取执行权限,再落地webshell"的攻击链。本文将详细分析三种反序列化方式的原理、利用条件和实战方法。

2. 环境搭建要求

2.1 基础环境

  • Java项目基于Maven构建
  • JDK版本需与U8 Cloud匹配(建议使用较低版本)
  • 准备U8 Cloud完整源码

2.2 依赖配置

  1. 收集U8 Cloud所有JAR包(fw.jar、commons系列、基础u8包等)
  2. 如不确定所需JAR,可全部导入项目
  3. 添加ysoserial JAR用于反序列化payload生成

3. 漏洞分析

3.1 漏洞背景

  • 官方公告日期:2025-08-29
  • 公告地址:https://security.yonyou.com/#/noticeInfo?id=720
  • 漏洞本质:通过反序列化绕过鉴权机制,实现任意文件上传和系统破坏

3.2 请求处理流程分析

Client → POST /ServiceDispatcherServlet 
→ 映射CommonServletDispatcher 
→ doPost → doGet 
→ serviceHandler.execCall(request, response) 
→ ServiceDispatcher.execCall()
├─ 反序列化request输入流(NetObjectInputStream)
├─ 得到InvocationInfo(服务名、方法、参数)
├─ 执行目标方法
└─ 将Result对象序列化写回response

3.3 web.xml配置分析

ServiceDispatcherServlet的实际处理类为CommonServletDispatcher,初始化参数为ServiceDispatcherCommonServletDispatcher仅作为外壳,核心处理逻辑在ServiceDispatcher中。

4. 三种反序列化方式详解

4.1 第一种:修复前的反序列化(需绕过token)

4.1.1 修复前状况

  • 2025-04-03之前版本无token校验
  • 直接反序列化NetObjectInputStream即可利用

4.1.2 数据格式要求

  • 读取4字节长度前缀(对象数据长度)
  • 根据长度读取字节数组
  • 不符合格式会导致EOF异常

4.1.3 利用方法

  1. 构造恶意对象
  2. 使用NetObjectOutputStream写入对象
  3. 发送精心构造的请求

4.2 第二种:修复后的反序列化(带token验证)

4.2.1 token验证机制

  • /ierp/bin/token/trustIPList.conf读取IP列表
  • 读取可信服务名
  • 使用tokenseed配置生成token

4.2.2 token种子来源

  1. 文件中的tokenseed值:ab7d823e-03ef-39c1-9947-060a0a08b931
  2. 文件不存在时的默认值:232asfdsjkfmsdgldfg

4.2.3 token生成方式

invInfo.setToken(genToken(userCode));

其中userCode为#UAP#

4.2.4 完整利用流程

  1. 获取正确的token种子
  2. 生成合法token
  3. 构造包含token的InvocationInfo对象
  4. 执行反序列化攻击

4.2.5 EJB服务查找机制

  • 使用自定义ServiceCache缓存对象
  • 新模块先查询缓存,未命中则通过JNDI查找
  • ServiceCache中的对象会创建EJB代理返回

4.3 第三种:IPFxxFileService反序列化

4.3.1 文件位置

.../modules/uapeai/META-INF/lib/uapeaipfxx.jar!/nc/bs/pfxx/pub/PFxxFileServiceImpl.class

4.3.2 可利用方法分析

writeDocToXMLFile方法
  • 参数:byte[] filedata, String filePath
  • 可直接写入文件
  • 限制:文件后缀强制为.xml
writeInputStreamData方法
  • 存在漏洞但利用有限
  • 只能覆盖GZIP文件
  • 实用性较低
writeMiddleFile方法
  • 参数:byte[] filedata, String filePath, String fileName, String billId
  • billId参数用途不确定,需要进一步研究
getHomeFileByte方法
  • 将指定路径下的多个文件打包为ZIP返回
  • 可用于文件读取/下载

4.3.3 writeDocToXMLFile利用细节

写入操作通过XMLUtil.printDOMTree(writer, newdoc, 0, "UTF-8")实现,需要构造byte[]和String类型参数。

4.4 第四种:C6链反序列化(无需token验证)

4.4.1 技术原理

直接通过NetObjectInputStream.readObject(bis, streamRet)重建InvocationInfo对象,在重建过程中执行类的反序列化回调(readObject/readResolve/动态代理初始化等)。

4.4.2 优势

  • 完全绕过token验证
  • 只需在参数中嵌入恶意对象即可
  • 更直接有效

5. 各方式对比与利用特点

5.1 日志痕迹

  • 第一、二种方式:只留下少量log,无明显异常信息
  • 第三种方式:会产生报错日志,但留痕概率较低

5.2 回显问题

  • 通过Tomcat链可实现回显
  • 国外环境测试中回显不稳定(原因未明)
  • 本地环境回显正常

6. 漏洞修复方案

6.1 官方修复措施

  1. 增强token验证机制
  2. 修改文件上传路径,避免文件落地到项目目录
  3. 加强输入验证和过滤

6.2 修复参考

详细修复方案参考:https://security.yonyou.com/#/home

7. 测试工具与资源

7.1 项目地址

https://github.com/sudo-Yangziran/U8-POC-Study

7.2 使用说明

  • 修改测试方式适应实际环境
  • 根据研究思路扩展测试用例
  • 严格遵守授权测试原则

8. 免责声明

本文内容仅用于技术研究与防御,请勿用于非法用途。使用者需获得目标系统授权并在安全环境进行测试。滥用本文信息产生的后果由使用者自负,与作者无关。


注意:本文提供的Hex编码payload仅用于测试,使用一次后会自动删除,仅限于本机测试使用,不得用于实际攻击。

用友U8Cloud ServiceDispatcherServlet 反序列化漏洞分析与利用研究 1. 前言 用友U8 Cloud近期曝光了多个可链式利用的安全缺陷,其中ServiceDispatcherServlet的反序列化入口是核心攻击向量。攻击者可通过此漏洞组合实现"先获取执行权限,再落地webshell"的攻击链。本文将详细分析三种反序列化方式的原理、利用条件和实战方法。 2. 环境搭建要求 2.1 基础环境 Java项目基于Maven构建 JDK版本需与U8 Cloud匹配(建议使用较低版本) 准备U8 Cloud完整源码 2.2 依赖配置 收集U8 Cloud所有JAR包(fw.jar、commons系列、基础u8包等) 如不确定所需JAR,可全部导入项目 添加ysoserial JAR用于反序列化payload生成 3. 漏洞分析 3.1 漏洞背景 官方公告日期:2025-08-29 公告地址:https://security.yonyou.com/#/noticeInfo?id=720 漏洞本质:通过反序列化绕过鉴权机制,实现任意文件上传和系统破坏 3.2 请求处理流程分析 3.3 web.xml配置分析 ServiceDispatcherServlet的实际处理类为 CommonServletDispatcher ,初始化参数为 ServiceDispatcher 。 CommonServletDispatcher 仅作为外壳,核心处理逻辑在 ServiceDispatcher 中。 4. 三种反序列化方式详解 4.1 第一种:修复前的反序列化(需绕过token) 4.1.1 修复前状况 2025-04-03之前版本无token校验 直接反序列化NetObjectInputStream即可利用 4.1.2 数据格式要求 读取4字节长度前缀(对象数据长度) 根据长度读取字节数组 不符合格式会导致EOF异常 4.1.3 利用方法 构造恶意对象 使用NetObjectOutputStream写入对象 发送精心构造的请求 4.2 第二种:修复后的反序列化(带token验证) 4.2.1 token验证机制 从 /ierp/bin/token/trustIPList.conf 读取IP列表 读取可信服务名 使用tokenseed配置生成token 4.2.2 token种子来源 文件中的tokenseed值: ab7d823e-03ef-39c1-9947-060a0a08b931 文件不存在时的默认值: 232asfdsjkfmsdgldfg 4.2.3 token生成方式 其中userCode为 #UAP# 4.2.4 完整利用流程 获取正确的token种子 生成合法token 构造包含token的InvocationInfo对象 执行反序列化攻击 4.2.5 EJB服务查找机制 使用自定义ServiceCache缓存对象 新模块先查询缓存,未命中则通过JNDI查找 ServiceCache中的对象会创建EJB代理返回 4.3 第三种:IPFxxFileService反序列化 4.3.1 文件位置 .../modules/uapeai/META-INF/lib/uapeaipfxx.jar!/nc/bs/pfxx/pub/PFxxFileServiceImpl.class 4.3.2 可利用方法分析 writeDocToXMLFile方法 参数:byte[ ] filedata, String filePath 可直接写入文件 限制:文件后缀强制为.xml writeInputStreamData方法 存在漏洞但利用有限 只能覆盖GZIP文件 实用性较低 writeMiddleFile方法 参数:byte[ ] filedata, String filePath, String fileName, String billId billId参数用途不确定,需要进一步研究 getHomeFileByte方法 将指定路径下的多个文件打包为ZIP返回 可用于文件读取/下载 4.3.3 writeDocToXMLFile利用细节 写入操作通过 XMLUtil.printDOMTree(writer, newdoc, 0, "UTF-8") 实现,需要构造byte[ ]和String类型参数。 4.4 第四种:C6链反序列化(无需token验证) 4.4.1 技术原理 直接通过 NetObjectInputStream.readObject(bis, streamRet) 重建InvocationInfo对象,在重建过程中执行类的反序列化回调(readObject/readResolve/动态代理初始化等)。 4.4.2 优势 完全绕过token验证 只需在参数中嵌入恶意对象即可 更直接有效 5. 各方式对比与利用特点 5.1 日志痕迹 第一、二种方式:只留下少量log,无明显异常信息 第三种方式:会产生报错日志,但留痕概率较低 5.2 回显问题 通过Tomcat链可实现回显 国外环境测试中回显不稳定(原因未明) 本地环境回显正常 6. 漏洞修复方案 6.1 官方修复措施 增强token验证机制 修改文件上传路径,避免文件落地到项目目录 加强输入验证和过滤 6.2 修复参考 详细修复方案参考:https://security.yonyou.com/#/home 7. 测试工具与资源 7.1 项目地址 https://github.com/sudo-Yangziran/U8-POC-Study 7.2 使用说明 修改测试方式适应实际环境 根据研究思路扩展测试用例 严格遵守授权测试原则 8. 免责声明 本文内容仅用于技术研究与防御,请勿用于非法用途。使用者需获得目标系统授权并在安全环境进行测试。滥用本文信息产生的后果由使用者自负,与作者无关。 注意 :本文提供的Hex编码payload仅用于测试,使用一次后会自动删除,仅限于本机测试使用,不得用于实际攻击。