0x00、前言
用友nc(NCMessageServlet)反序列化漏洞复现与分析,同样也是InvokerServlet引发的问题,调用的Servlet类变成NCMessageServlet类,也是直接实现反序列化,分析内容不多,当做审计过程记录。
0x01、漏洞描述
用友 NC 系统InvokerServlet调用NCMessageServlet过程中存在反序列化漏洞,远程未授权攻击者可向目标服务器发送恶意请求包,最终实现任意代码执行。
0x02、漏洞范围
NC version <= 6.5
0x03、环境搭建
用友NC 6.5安装包网盘下载的,安全性未知,就不贴地址了。
安装步骤可以参考:
https://xz.aliyun.com/t/8242
https://blog.csdn.net/m0_53100713/article/details/130056482
https://www.rstk.cn/news/881081.html?action=onClick
过程没太多的注意点,主要是尽量使用jdk1.7启动服务,高版本jdk启动容易出现问题
运行安装home目录下startServer.bat启动服务器即可
0x04、漏洞复现
这里用CC6链进行复现
0x05、原理分析
同样还是NCInvokerServlet
访问/service/
和/servlet/
目录下即可访问NCInvokerServlet
跟进nc.bs.framework.server.InvokerServlet
,get/post
都会调用doAction
方法,doAction
前半段获取token
、userCode
不重要,用不到这些字段。
直接看下面部分,这里对Path
路径有个取值逻辑
若path
以/~
开头,则取值/~
后的字符串,若该字符串存在/
符号,则/
前面的字符串赋值给module
,/
符号后面的字符赋值给serviceName
,例如path
路径为/~modulename/servicename
,则modulename
赋值给module
,servicename
赋值给serviceName
获取到模块module
和服务名serviceName
过后,调用getServiceObject
方法获取服务对象
getServiceObject
方法开始判断moduleName
是否为空,由于存在,因此进入else
判断体
从serviceObjMap
常量中获取moduleName:serviceName
,由于并未添加该内容,因此此时返回给的retObject
为null
接着获取模块moduleName
的容器Container
,为了后面的jndi调用
获取到容器后,再获取上下文器然后进行jndi调用,查询对象为serviceName
,如果serviceName
对象在jndi注册对象中不存在,则会抛出异常进入catch
代码段,这里直接获取容器的类加载器,直接类加载serviceName
,然后newInstance()
实例化,因此找到module
下存在实现反序列化功能的serviceName
类,即可实例化触发反序列化漏洞
因此该漏洞找到了baseapp
模块下的nc.message.bs.NCMessageServlet
类
实例化时调用父类的doAction
方法,从而调用子类nc.message.bs.NCMessageServlet
的doAction
方法
该类很直接,直接获取序列化输入流然后直接反序列化触发漏洞
因此直接向该类发送序列化数据,即可直接反序列化触发漏洞
0x06、漏洞修复
官方以发布修复补丁:
https://security.yonyou.com/#/noticeInfo?id=293