CC1,3,6回顾
前言
前面陆续学习了CC1,CC3,CC6,以及TemplatesImpl以及改造,有点乱,正所谓温故而知新嘛,所以这篇就回顾一下,捋一捋,解决一些细节问题。
CC1
由于CC1要介绍CC链的几个关键类,所以写了三篇
InvokerTransformer,其transform可以执行任意方法,ConstantTransformer作用是拿到一个危险类,如RunTime等等,ChainedTransformer作用是将几个Transformer串联起来
这三种搭配就可以执行任意方法
TransformedMap:用来修饰Map,被修饰过的Map在添加新的元素时,将可以执⾏⼀个回调,也就是说可以调用其他的tramsformAnnotationInvocationHandler:第四点说了,触发漏洞的核心是向Map加入新的元素,在实际反序列化利用的时候,我们需要找到一个类,它在反序列化的readObject逻辑里有类似的写入操作。这个类刚好符合条件。
到这儿,算是一条完整的CC利用链了。
LazyMap:作用和TransformedMap类似,都是为了执行transform,区别就是TransformedMap是在写入元素的时候执行会transform,而LazyMap是在其get方法中执行的factory.transform- 动态代理:使用了一个动态代理的方法来调用``LazyMap#get
,原因是当我们调用某个动态代理对象的方法时,都会触发代理类的invoke`方法,并传递对应的内容
分析一下利用过程:这里1,2,3,4,5是一条利用链,逻辑很清晰。1,2,3,6,7是一条利用链。这里还是比较绕的,分析一下利用过程:
只需要找到某个地方调用了LazyMap#get方法,并且传递了任意值。
首先在readObject时,会触发AnnotationInvocationHandler#readObject方法,其中调用了this.memberValues.entrySet

而this.memberValues是构造好的proxyMap,由于这是一个代理对象,所以调用其方法时,会去调用其创建代理时设置的handler的invoke方法

proxyMap设置的handler为下面这个handler,同样是InvocationHandler这个类,接着会调用他的invoke方法

InvocationHandler#invoke的78行代码中调用了this.memberValues#get,此时的this.memberValues为之前设置好的lazymap,所以这里调用的是lazymap#get,从而触发后边的rce链。

代理后的对象叫做proxyMap,但我们不能直接对其进行序列化,因为我们入口点是 sun.reflect.annotation.AnnotationInvocationHandler#readObject ,所以我们还需要再用 AnnotationInvocationHandler对这个proxyMap进行包裹:

这里还是比较绕的,因为设置了两个handler,但是第一个handler是为了触发lazymap#get,而第二个handler实际上只是为了触发代理类所设置handler的invoke方法
接着解释一些细节的问题:
为什么这用反射的方式来创建AnnotationInvocationHandler的实例?
因为AnnotationInvocationHandler并不是public类,所以无法直接通过new的方式来创建其实例。

2.为什么创建handler时传入的第一个参数是Retention.class?
因为在创建实例的时候对传入的第一个参数调用了isAnnotation方法来判断其是否为注解类:
public boolean isAnnotation() {
return (getModifiers() & ANNOTATION) != 0;
}
而Retention.class正是java自带的一个注解类,所以这里可以直接用上,当然要是换成其他注解类也是ok的。
CC6
CommonsCollections1利用链,两种方法,LazyMap以及TransformedMap,但是在Java 8u71以后,这个利⽤链不能再利⽤了,主要原因是 sun.reflect.annotation.AnnotationInvocationHandler#readObject的逻辑变化了
所以关注点如何调⽤LazyMap#get()?
找到的类是org.apache.commons.collections.keyvalue.TiedMapEntry ,在其getValue⽅法中调⽤了 this.map.get,⽽其hashCode⽅法调⽤了getValue⽅法
又在 java.util.HashMap#readObject中就可以找到 HashMap#hash()的调⽤
/*
Gadget chain:
java.io.ObjectInputStream.readObject()
java.util.HashMap#readObject
java.util.HashMap#hash()
org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
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()
java.lang.Runtime.exec()
*/
而ysoserial中使用HashSet.readObject()来调用
java.util.HashSet.readObject()
java.util.HashMap.put()
java.util.HashMap.hash()
逻辑也很清晰
这条链是Java7和8高版本通杀
CC3
首先利⽤TemplatesImpl链是可以通过TemplatesImpl#newTransformer()执行代码的。
在一个为了绕过⼀些规则对InvokerTransformer的限制。所以CC3并没有使⽤到InvokerTransformer来调⽤任意⽅法,⽽是⽤到了另⼀个 类, com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter
这个类的构造⽅法中调⽤(TransformerImpl) templates.newTransformer(),免去了我们使⽤InvokerTransformer⼿⼯调⽤newTransformer()⽅法这⼀步
⽤到⼀个新的Transformer,就是 org.apache.commons.collections.functors.InstantiateTransformer 。InstantiateTransformer也是⼀个实现了Transformer接⼝的类,他的作⽤就是调⽤构造⽅法.
利⽤InstantiateTransformer来调⽤到TrAXFilter的构造⽅法,再利⽤其构造⽅法⾥的templates.newTransformer()调⽤到TemplatesImpl⾥的字节码
小结
知识点比较多,每一个都捋清楚后,就可以重分发散思维,各种组合利用
CC1,3,6回顾的更多相关文章
- YsoSerial 工具常用Payload分析之CC1
前文介绍了最简单的反序列化链URLDNS,虽然URLDNS本身不依赖第三方包且调用简单,但不能做到漏洞利用,仅能做漏洞探测,如何才能实现RCE呢,于是就有Common-collections1-7.C ...
- [C#] C# 基础回顾 - 匿名方法
C# 基础回顾 - 匿名方法 目录 简介 匿名方法的参数使用范围 委托示例 简介 在 C# 2.0 之前的版本中,我们创建委托的唯一形式 -- 命名方法. 而 C# 2.0 -- 引进了匿名方法,在 ...
- SQL Server-表表达式基础回顾(二十四)
前言 从这一节开始我们开始进入表表达式章节的学习,Microsoft SQL Server支持4种类型的表表达式:派生表.公用表表达式(CTE).视图.内嵌表值函数(TVF).简短的内容,深入的理解, ...
- [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?
你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...
- [C#] C# 知识回顾 - 学会处理异常
学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...
- [C#] C# 知识回顾 - 学会使用异常
学会使用异常 在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”. 异常通常由错误的代码引发,并由能够更正错误的代码进行 catch. 异常可由 .NET 的 CLR ...
- [C#] C# 知识回顾 - 异常介绍
异常介绍 我们平时在写程序时,无意中(或技术不够),而导致程序运行时出现意外(或异常),对于这个问题, C# 有专门的异常处理程序. 异常处理所涉及到的关键字有 try.catch 和 finally ...
- [.NET] C# 知识回顾 - Event 事件
C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...
- [.NET] C# 知识回顾 - 事件入门
C# 知识回顾 - 事件入门 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6057301.html 序 之前通过<C# 知识回顾 - 委托 de ...
随机推荐
- 【Java】学习路径33-在IDEA中使用junit单元测试运行单个方法
首先在菜单找到 文件-项目结构 项目设置-库-"+" 选择Java 找到IDEA安装目录,打开lib/junit4.jar 的jar包,然后打开即可. 然后选择确定. 然后再项目中 ...
- kingbaseES V8R3数据安全案例之---审计记录清除案例
案例说明: 对于KingbaseES V8R3数据库,默认用户无权限删除审计记录,只有对审计记录做了转储以后会自动清理审计记录. 适用版本: KingbaseES V8R3 本案例数据库版本: S ...
- 字符类数据类型和oracle字符类型的区别
为兼容Oracle的数据类型,KingbaseES扩展了Oracle的NUMBER.VARCHAR2.CHAR(n)和DATE类型.该措施使得移植Oracle的Create Table等DDL语句时, ...
- git rebase合并多个commit总结
git rebase 合并多个commit 方法 在开发过程中,有时一个任务会分几次commit提交,这样可能对于有些分支要cherry pick时会比较麻烦,这是我们可以通过git rebase 将 ...
- 操作系统学习笔记10 | I/O、显示器与键盘
从这一部分开始介绍操作系统的设备驱动,操作系统通过文件系统的抽象驱动设备让用户能够使用显示器.键盘等交互工具.并讲解printf和scanf是如何实现敲下键盘将字符显示到屏幕上的. 参考资料: 课程: ...
- 理解virt、res、shr之间的关系(linux系统篇)
前言 想必在linux上写过程序的同学都有分析进程占用多少内存的经历,或者被问到这样的问题--你的程序在运行时占用了多少内存(物理内存)? 通常我们可以通过top命令查看进程占用了多少内存.这里我们可 ...
- .NET 反向代理-YARP 根据域名转发
前段时间发布过一个关于 YARP 的简单介绍,感兴趣的小伙伴恭请移步看看 .NET 反向代理-YARP - 一事冇诚 - 博客园 (cnblogs.com) 作为反向代理,必不可少的当然是根据域名代理 ...
- Kubernetes里的Service是如何工作的
Service是Kubernetes接入层的一种抽象资源,它为我们提供了一种固定的.统一的访问接口地址和负载均衡能力,这时可能会想到,当时使用docker-compose的时候,不存在Service概 ...
- 安装ceph (快速) 步骤一:预检
官网地址:http://docs.ceph.org.cn/start/ 预检 安装一个 ceph-deploy 管理节点和一个三节点的Ceph 存储集群来研究 Ceph 的基本特性.这篇预检会帮你准备 ...
- Beats: Filebeat和pipleline processors
简要来说: 使用filebeat读取log日志,在filebeat.yml中先一步处理日志中的个别数据,比如丢弃某些数据项,增加某些数据项. 按照之前的文档,是在filebeat.yml中操作的,具体 ...