U8Cloud最新前台RCE漏洞挖掘过程
前言漏洞比较简单可以概括为token硬编码导致的任意方法调用组合RCE。这篇文章主要讲下当时挖这个漏洞的过程,其实就是分析老漏洞就挖到了新漏洞整个过程好像就几个小时,尽量写的新手向一点吧。
反序列化 or 任意方法调用?
/ServiceDispatcherServlet接口之前出过反序列化所有先看看他怎么修复的
我们跟进看看具体实现
这里GET|POST都会进入execCall
execCall里会调用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:}这个漏洞的原理我简单讲下
根据传入的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
总结
这个漏洞本来不想写这么麻烦的简单分析一下调用过程很省时间,但是后面还是想按照当时的挖掘思路来写主要是想告诉读者分析历史漏洞的重要性。
每一个历史漏洞都像是一把钥匙,不仅能开启当时的那扇门,更可能为我们指向新的攻击路径。复现不是终点,而是新发现的起点!!!
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]