java反序列化漏洞学习之Apache Commons Collections

demo 一波。 最近群里都在学Java 参考:
https://p0sec.net/index.php/archives/121/
https://www.xmanblog.net/java-deserialize-apache-commons-collections/
https://www.smi1e.top/java反序列化学习之apache-commons-collections/
https://xz.aliyun.com/t/2028

1 环境

java反序列化漏洞学习之Apache Commons Collections_第1张图片


import org.apache.commons.collections.functors.InvokerTransformer;
public class test {
    public static void main(String[] args){
        InvokerTransformer invokerTransformer = new InvokerTransformer("exec", new Class[]{ String.class}, new Object[] {"calc.exe"});
        invokerTransformer.transform(Runtime.getRuntime());
    }
}

运行上面代码 先弹出个计算器的小demo,搭建成功。
或者郁师傅这样也可以:
java反序列化漏洞学习之Apache Commons Collections_第2张图片
transform 方法介绍:

java反序列化漏洞学习之Apache Commons Collections_第3张图片
传入的参数是input是一个实例化对象,调用的方法iMethodName和参数iArgs都是InvokerTransformer实例化时设定的。所以利用这个方法便可以调用任意对象的任意方法。

那么关键
**在apache.commons.collections.functors中,有一个

InvokerTransformer

类,

public Object transform(Object input) {
    if (input == null) {
        return null;
    } else {
        try {
            Class cls = input.getClass();//获得类
            Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
            return method.invoke(input, this.iArgs);
        } catch (NoSuchMethodException var5) {
            throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' does not exist");
        } catch (IllegalAccessException var6) {
            throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
        } catch (InvocationTargetException var7) {
            throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' threw an exception", var7);
        }
    }
}

它继承了TransformerSerializable接口,在类中有一个成员函数
transform
获得类名字, 通过 。getmethod方法获得
它通过反射技术可以调用任意类的任意方法。**

因此实现反序列化执行命令的目标中,它是一个重要的函数,我们要想办法去调用它。比如我们利用Runtime.getRuntime().exec(cmd)去执行命令就可以这样调用
在Java中调用外部命令不像PHP中直接使用system()或者exec(),Java是完全面向对象的编程,调用外部命令也需要对象->方法或者类->静态方法这样调用,常用的就是 Runtime.getRuntime().exec(cmd),所以单纯的利用上面一个transform是不能达到执行命令的目的的。要多次调用此transform并且上一次的返回结果作为下一次的输入,相当于一个递归(非严格意义)。这是开发中的一个正常的功能,所以commons-collections早就封装好了相关的方法:ChainedTransformer,该类实例化是传入的是一个Transform相关对象的列表,调用ChainedTransformer的transform方法是挨个调用这个列表里对象的transform方法。

你可能感兴趣的:(java安全)