Dubbo反序列化RCE利用之新拓展面 - Dubbo Rouge攻击客户端
字数 1239 2025-08-20 18:17:07
Dubbo反序列化RCE利用之新攻击面 - Dubbo Rouge攻击客户端
0x01 前言
本文详细分析Dubbo框架在反序列化过程中的安全漏洞,特别是针对Dubbo客户端的新型攻击方式 - "Dubbo Rouge"攻击。这种攻击方式通过注册恶意服务到Zookeeper注册中心,诱导客户端连接并触发反序列化漏洞实现RCE。
0x02 Dubbo服务集群基础
Dubbo作为高可用RPC框架,通常采用集群部署:
- 服务提供者将自身信息注册到Zookeeper等注册中心
- 服务消费者从注册中心获取服务提供者列表
- 集群模块负责负载均衡和故障转移
- 默认使用Hessian2作为序列化方式
0x03 攻击原理
3.1 传统服务端攻击
- 攻击者向Dubbo服务端发送恶意序列化数据
- 服务端反序列化时触发RCE
- 已有相关研究和防御方案
3.2 新型客户端攻击(Dubbo Rouge)
- 攻击者部署恶意Dubbo服务并注册到Zookeeper
- 客户端从注册中心获取服务列表时包含恶意服务
- 客户端连接恶意服务并接收恶意序列化响应
- 客户端反序列化时触发RCE
0x04 攻击实现细节
4.1 恶意服务注册
- 定位Zookeeper中Dubbo服务注册路径:
/dubbo/{service全限定名}/providers/ - 示例注册信息(URL编码):
dubbo%3A%2F%2F127.0.0.1%3A20881%2Fcom.example.DemoService%3F... - 解码后可见服务配置参数:
dubbo://127.0.0.1:20881/com.example.DemoService?actives=5&anyhost=true&...
4.2 攻击步骤
- 遍历Zookeeper中现有服务注册信息
- 复制合法服务注册信息,修改IP和端口指向恶意服务
- 可选择删除其他合法服务注册信息,确保客户端只能连接恶意服务
- 恶意服务等待客户端连接
4.3 序列化方式控制
关键点:通过serialization参数控制客户端使用的序列化方式
- 默认无此参数时使用Hessian2
- 添加
serialization=java强制客户端使用Java原生序列化 - 响应包头部需修改序列化标识ID:
// org.apache.dubbo.common.serialize.Constants byte HESSIAN2_SERIALIZATION_ID = 2; byte JAVA_SERIALIZATION_ID = 3; // 其他序列化方式ID...
0x05 攻击代码实现
5.1 基本配置
String zookeeperUri = "127.0.0.1:2181"; // Zookeeper地址
String rougeHost = "127.0.0.1"; // 恶意服务IP
int rougePort = 33336; // 恶意服务端口
byte[] maliciousBytes = generatePayload(); // 恶意序列化数据
// 启动恶意服务
new DNSURL().startRougeServer(zookeeperUri, rougeHost, rougePort, maliciousBytes, false);
5.2 直连模式攻击
- 适用于客户端配置直连的场景
- 最后一个参数
attackRegister必须为false
5.3 注册中心模式攻击
- 连接Zookeeper注册中心
- 修改/添加服务提供者信息
- 可选择删除其他合法服务提供者
0x06 防御方案
6.1 服务端防御
- 实现Hessian2黑名单过滤
- 参考《dubbo反序列化问题-Hessian2安全加固和修复》
6.2 客户端防御
- 验证服务提供者身份和来源
- 限制可信任的注册中心
- 实现反序列化过滤器
6.3 通用建议
- 升级到最新Dubbo版本
- 监控Zookeeper注册中心的异常变更
- 实施网络隔离,限制Dubbo服务的网络访问
0x07 总结
Dubbo Rouge攻击通过注册恶意服务到注册中心,利用客户端反序列化漏洞实现RCE。相比传统服务端攻击,这种方式具有以下特点:
- 攻击面更广,可影响大量客户端
- 隐蔽性更强,难以通过常规网络监控发现
- 可利用Java原生序列化扩大攻击影响
防御关键在于严格控制注册中心访问权限和实施严格的反序列化过滤策略。