Java反序列化-CC2分析

本文深入探讨了Java反序列化过程中,如何利用PriorityQueue和TransformingComparator作为入口点和跳板进行攻击。文章详细阐述了TransformingComparator的compare方法如何调用到利用链,PriorityQueue的readObject方法如何存储反序列化数据,并通过heapify方法形成二叉堆,进而触发比较器的compare方法。同时,文章提到了commons-collections4在绕过黑名单中的作用,指出与旧版的区别在于TransformingComparator实现了Serializable接口。
摘要由CSDN通过智能技术生成

如何将PriorityQueue、TransformingComparator 作为入口点和跳板去利用

首先看一下作为跳板的 TransformingComparator 类是怎么调用到利用链的

public int compare(final I obj1, final I obj2) {
        final O value1 = this.transformer.transform(obj1);
        final O value2 = this.transformer.transform(obj2);
        return this.decorated.compare(value1, value2);
    }

在 TransformingComparator#compare 方法中,调用到了transform 方法去修饰 obj1、obj2 的值。就是这个方法调用到了利用链

接着在看一下 PriorityQueue 类是怎么作为入口点去利用的

    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in (and discard) array length
        s.readInt();

        queue = new Object[size];

        // Read in all elements.
        for (int i = 0; i < size; i++)
            queue[i] = s.readObject();

        // Elements are guaranteed to be in "proper order", but the
        // spec has never explained what that might be.
        heapify();
    }

在PriorityQueue#readObject 方法中,将反序列化的数据存放在queue 字段中,之后调用 heapify 方法来对数据进行调整,形成二叉堆

在对数据进行调整的时候会对数据进行比较,将较小的数排列在前面。而在对数据进行比较的时候就会调用到compare 方法,从而让PriorityQueue 类和TransformingComparator产生联系。看一下这个操作是怎么在代码中实现的

private void heapify() {
        for (int i = (size >>> 1) - 1; i >= 0; i--)
            siftDown(i, (E) queue[i]);
    }

在 heapify 方法中,采用将数向后移动的方式来对数据进行调整。

    private void siftDown(int k, E x) {
        if (comparator != null)
            siftDownUsingComparator(k, x);
        else
            siftDownComparable(k, x);
    }

在后移之前会判断,判断是否有比较器 (compar),如果有的话则调用if 中的方法,否则调用 else 中的方法。这里直接看i分钟的方法,因为只有当有比较器的时候才会调用比较器中的方法来比较两个数

    private void siftDownUsingComparator(int k, E x) {
        int half = size >>> 1;
        while (k < half) {
            int child 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值