找回密码
 立即注册
首页 业界区 安全 U8Cloud最新前台RCE漏洞挖掘过程

U8Cloud最新前台RCE漏洞挖掘过程

井晶灵 2025-8-10 16:43:51
前言

漏洞比较简单可以概括为token硬编码导致的任意方法调用组合RCE。这篇文章主要讲下当时挖这个漏洞的过程,其实就是分析老漏洞就挖到了新漏洞整个过程好像就几个小时,尽量写的新手向一点吧。
反序列化 or 任意方法调用?

/ServiceDispatcherServlet接口之前出过反序列化所有先看看他怎么修复的
1.png

2.png

我们跟进看看具体实现
3.png

这里GET|POST都会进入execCall
4.png

execCall里会调用readObject但是这个方法是他自己实现的
5.png

注意到NCObjectInputStream#resolveClass
6.png

此处添加了黑白名单判断,且传入的rootChecked为false,whiteList为我们刚才传入的InvocationInfo.class所以这里使用白名单修复了之前的反序列化漏洞
然后我们回到readObject这里研究一下怎么生成这个序列化数据
7.png

8.png

他先检查了前四字节然后使用前四字节计算了数据长度判断是否符合,最后使用nc.bs.framework.comn.NetObjectInputStream#readObject进行反序列化。这里我们可以直接套用它的序列化方法来进行序列化数据的生成
nc.bs.framework.comn.NetObjectOutputStream#writeObject
9.png

既然这里反序列化RCE走不通我们继续看execCall的后续实现
10.png

从我们反序列化的对象invInfo中获取数据先进入vertifyToken进行token验证,然后进入invokeBeanMethod进行反射调用。我们看下vertifyToken的实现
11.png

如果service或者clientIP在可信列表里则直接不进行token验证,然后看vertifyTokenIllegal怎么验证token
12.png

获取userCode传入genToken
13.png

获取tokenSeed作为盐然后sha1加密
14.png

所以我们只要知道tokenSeed即可伪造token
15.png

从nc.bs.framework.server.token.TokenUtil可知tokenSeed储存在/ierp/bin/token/tokenSeed.conf里我们直接查看安装包和安装后的这个文件发现没有任何变化说明是硬编码的不是启动后随机生成写入文件的。
16.png

17.png

所以token可以伪造,然后我们这里就有了一个调用符合下面规则方法的点
18.png

从历史漏洞寻找RCE方法

上面我们找到了一个调用符合某些规则方法的点,我们这里不跟入nc.bs.framework.naming.Context#lookup查看具体实现然后找到符合的beanName&methodName因为如果对用友代码不熟悉或者这个符合规则的方法很多但是要找到一个RCE的可能也不太容易。正好挖洞之前分析过一个历史漏洞。数据包如下
  1. POST /service/esnserver HTTP/1.1
  2. Host: 192.168.179.140:8088
  3. Pragma: no-cache
  4. Cache-Control: no-cache
  5. Upgrade-Insecure-Requests: 1
  6. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
  7. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
  8. Token: 469ce01522f64366750d1995ca119841
  9. Accept-Encoding: gzip, deflate, br
  10. Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,fil;q=0.6
  11. Cookie: currentToken=0d1001e88bd4373e7f07ff61caddeaf8; JSESSIONID=62C880D54C98B7CD3CEFF70A169A4DC2.server
  12. Connection: keep-alive
  13. Content-Type: application/x-www-form-urlencoded
  14. Content-Length: 60484
  15. {"invocationInfo":{"ucode":"123","dataSource":"U8cloud","lang":"en"},"method":"uploadFile","className":"nc.itf.hr.tools.IFileTrans","param":{"p1":"shelltext","p2":"webapps/u8c_web/test1234.jsp"},"paramType":["p1:[B","p2:java.lang.String"]}
复制代码
这个漏洞的原理我简单讲下
19.png

20.png

21.png

根据传入的pathInfo获取obj比如上面的包传入的即为esnserver,然后进入获取到的obj的service方法这里最后会进入com.yonyou.esn.servlet.EsnServlet#doAction
22.png

也是先进行Token检测,上面数据包头部Token也是用来绕过检测的
23.png

他这个token和tokenSeed都是由用户传入的tokenSeed对应数据包中的ucode过了token检测以后会进入到com.yonyou.esn.ulink.LightAppService#processBusi
24.png

我这个代码是修复了这个漏洞以后的加了包名限制。这里其实和我们上面反射调用方法是一样的只不过这里是json格式上面是反序列化。所以我们看下"method":"uploadFile","className":"nc.itf.hr.tools.IFileTrans"修复了没还是只加了包名限制反射调用。
25.png

26.png

解压数据然后写入我们指定的路径没有任何限制。
组合RCE

结合反序列化token硬编码,反射调用nc.itf.hr.tools.IFileTrans#uploadFile可写出POC生成代码
27.png

隐藏了关键代码部分需要研究的请自行实现。
28.png

成功getshell
29.png

总结

这个漏洞本来不想写这么麻烦的简单分析一下调用过程很省时间,但是后面还是想按照当时的挖掘思路来写主要是想告诉读者分析历史漏洞的重要性。
每一个历史漏洞都像是一把钥匙,不仅能开启当时的那扇门,更可能为我们指向新的攻击路径。复现不是终点,而是新发现的起点!!!

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册