欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

Java反序列化: 基于CommonsCollections4的Gadget分析

来源: 作者: 时间:2019-02-24 21:26 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助

0x1 背景及概要
随着Java应用的推广和普及,Java安全问题越来越被人们重视,纵观近些年来的Java安全漏洞,反序列化漏洞占了很大的比例。就影响程度来说,反序列化漏洞的总体影响也明显高于其他类别的漏洞。
在反序列化漏洞的利用过程中,攻击者会构造一系列的调用链以完成其攻击行为。如何高效的生成符合条件且可以稳定利用的攻击Payload成为了攻击链条中的重要一环,当前已经有很多现成的工具帮助我们完成Payload的生成工作。本文主要以Ysoserial工具为例分析了基于org.apache.commons.collections4类库的Gadget,其通过构造一个特殊的PriorityQueue对象,将其序列化成字节流后,在字节流反序列化的过程中触发代码执行。
更多关于Ysoserial的信息,请参考:https://github.com/frohoff/ysoserial。
本文主要分为两方面,其一是基于PriorityQueue类的序列化对象的构造,另一方面是PriorityQueue对象在反序列化过程中恶意代码的触发原理。下文将从这两方面展开描述一些细节以及实际测试时的一些问题,整体的流程如图1-1所示。

图1-1
0x2 序列化对象的构造
首先,被序列化为字节流的对象实际是一个特殊的PriorityQueue对象,本小节主要分析构造该对象的过程,即图1-1的第一步。图2-1为ysoserial.payloads.CommonsCollections4中getObject方法的代码,是用于构造该PriorityQueue对象的代码:

图2-1
上图中需要注意的有如下两点:
1.通过createTemplatesImpl方法生成templates对象
2.通过PriorityQueue类的比较器将构造的一系列transformer串联起来
0x0A createTemplatesImpl方法生成攻击载荷
通过createTemplatesImpl方法生成templates对象是非常重要的一部分,因为这是实际承载我们恶意代码的对象,详细说一下,跟进分析createTemplatesImpl方法,其代码具体实现和关键点流程分别如下图2-2和图2-3所示:

图2-2

图2-3
首先生成TemplatesImpl实例,然后通过javassist类库修改StubTransletPayload类字节码,在其中插入执行命令的代码(这里是通过java.lang.Runtime.getRuntime().exec()方法执行命令,也可以插入其他利用代码,如反弹shell等),然后将其父类设置为abstTranslet类,最后将修改后的字节码通过反射写入到TemplatesImpl实例的_bytecodes变量中,这里还同时写入了Foo.class的字节码。除此之外,为了后续恶意代码的触发(如作者注释中所写:required to make TemplatesImpl happy),还要修改TemplatesImpl实例的_name和_tfactory变量,否则后面会在命令代码执行前抛出异常。 StubTransletPayload类代码实现如图2-4所示:

图2-4
StubTransletPayload类继承自AbstractTranslet类并实现了Serializable接口,通常我们构造一个恶意类可能会直接在static代码块或构造方法中写入我们想要执行的代码,这一步在上面通过javassist类库实现,关于StubTransletPayload类需要继承AbstractTranslet类的原因会在反序列化恶意代码触发时解释。 以上即为createTemplatesImpl方法的实现,其本质上是构造了一个特定结构的TemplatesImpl类实例,具体变量的值如图2-5所示:

图2-5
0x0B 构造并串联transformer
回到图2-1本段开始处getObject方法的代码中,在35行和40行分别初始化了ConstantTransformer对象和InstantiateTransformer对象,47行将两个对象构造成Transformer数组作为参数初始化了ChainedTransformer对象chain,而在50行,这个ChainedTransformer对象chain又是我们要序列化的对象PriorityQueue中comparator构造方法的参数,comparator可以理解为在PriorityQueue中决定优先次序的比较器,此处用的是TransformingComparator对象。在44-45行、55-57行利用java的反射机制和引用传递的特性修改chain对象中的变量,ConstantTransformer对象中iConstant变量的值设为com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter.class,InstantiateTransformer对象中iParamTypes设为javax.xml.transform.Templates.class,iArgs设为此前构造的templates对象。
51、52行向队列中插入两个1,这里是为了后面堆化时触发一次堆排序。 最终构造了一个用TransformingComparator对象作比较器的PriorityQueue对象,其内存中变量示意图和抽象结构图分别如图2-6和图2-7所示:

图2-6

图2-7
接下来将分析下这个对象序列化后的字节序列如何在反序列化的过程中触发代码执行。
0x3 反序列化过程中恶意代码的触发原理

[1] [2] [3] [4]  下一页

0x1 背景及概要
随着Java应用的推广和普及,Java安全问题越来越被人们重视,纵观近些年来的Java安全漏洞,反序列化漏洞占了很大的比例。就影响程度来说,反序列化漏洞的总体影响也明显高于其他类别的漏洞。
在反序列化漏洞的利用过程中,攻击者会构造一系列的调用链以完成其攻击行为。如何高效的生成符合条件且可以稳定利用的攻击Payload成为了攻击链条中的重要一环,当前已经有很多现成的工具帮助我们完成Payload的生成工作。本文主要以Ysoserial工具为例分析了基于org.apache.commons.collections4类库的Gadget,其通过构造一个特殊的PriorityQueue对象,将其序列化成字节流后,在字节流反序列化的过程中触发代码执行。
更多关于Ysoserial的信息,请参考:https://github.com/frohoff/ysoserial。
本文主要分为两方面,其一是基于PriorityQueue类的序列化对象的构造,另一方面是PriorityQueue对象在反序列化过程中恶意代码的触发原理。下文将从这两方面展开描述一些细节以及实际测试时的一些问题,整体的流程如图1-1所示。

内容来自无奈安全网


图1-1
0x2 序列化对象的构造
首先,被序列化为字节流的对象实际是一个特殊的PriorityQueue对象,本小节主要分析构造该对象的过程,即图1-1的第一步。图2-1为ysoserial.payloads.CommonsCollections4中getObject方法的代码,是用于构造该PriorityQueue对象的代码:

图2-1
上图中需要注意的有如下两点:
1.通过createTemplatesImpl方法生成templates对象
2.通过PriorityQueue类的比较器将构造的一系列transformer串联起来
0x0A createTemplatesImpl方法生成攻击载荷
通过createTemplatesImpl方法生成templates对象是非常重要的一部分,因为这是实际承载我们恶意代码的对象,详细说一下,跟进分析createTemplatesImpl方法,其代码具体实现和关键点流程分别如下图2-2和图2-3所示:
www.wnhack.com
图2-2

图2-3
首先生成TemplatesImpl实例,然后通过javassist类库修改StubTransletPayload类字节码,在其中插入执行命令的代码(这里是通过java.lang.Runtime.getRuntime().exec()方法执行命令,也可以插入其他利用代码,如反弹shell等),然后将其父类设置为abstTranslet类,最后将修改后的字节码通过反射写入到TemplatesImpl实例的_bytecodes变量中,这里还同时写入了Foo.class的字节码。除此之外,为了后续恶意代码的触发(如作者注释中所写:required to make TemplatesImpl happy),还要修改TemplatesImpl实例的_name和_tfactory变量,否则后面会在命令代码执行前抛出异常。 StubTransletPayload类代码实现如图2-4所示:

图2-4
StubTransletPayload类继承自AbstractTranslet类并实现了Serializable接口,通常我们构造一个恶意类可能会直接在static代码块或构造方法中写入我们想要执行的代码,这一步在上面通过javassist类库实现,关于StubTransletPayload类需要继承AbstractTranslet类的原因会在反序列化恶意代码触发时解释。 以上即为createTemplatesImpl方法的实现,其本质上是构造了一个特定结构的TemplatesImpl类实例,具体变量的值如图2-5所示:

本文来自无奈人生安全网



图2-5
0x0B 构造并串联transformer
回到图2-1本段开始处getObject方法的代码中,在35行和40行分别初始化了ConstantTransformer对象和InstantiateTransformer对象,47行将两个对象构造成Transformer数组作为参数初始化了ChainedTransformer对象chain,而在50行,这个ChainedTransformer对象chain又是我们要序列化的对象PriorityQueue中comparator构造方法的参数,comparator可以理解为在PriorityQueue中决定优先次序的比较器,此处用的是TransformingComparator对象。在44-45行、55-57行利用java的反射机制和引用传递的特性修改chain对象中的变量,ConstantTransformer对象中iConstant变量的值设为com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter.class,InstantiateTransformer对象中iParamTypes设为javax.xml.transform.Templates.class,iArgs设为此前构造的templates对象。
51、52行向队列中插入两个1,这里是为了后面堆化时触发一次堆排序。 最终构造了一个用TransformingComparator对象作比较器的PriorityQueue对象,其内存中变量示意图和抽象结构图分别如图2-6和图2-7所示:
内容来自无奈安全网


图2-6

图2-7
接下来将分析下这个对象序列化后的字节序列如何在反序列化的过程中触发代码执行。
0x3 反序列化过程中恶意代码的触发原理
无奈人生安全网

[1] [2] [3] [4]  下一页

内容来自无奈安全网

。 (责任编辑:admin)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。