解决java反序列化漏洞的建议

 2024-02-28 00:06:38  阅读 0

主要从包来简单分析java反序列漏洞产生的原因。

1.对象序列化

对象序列化是一个用于将对象的状态转换为字节流的过程,该字节流可以保存到磁盘文件或通过网络发送到任何其他程序。 可以通过实现 java.io. 在 Java 类中启用可串行性。

序列化的简单实现示例如下:

班级 {

姓名;

(姓名){

this.name = 名称;

(){

“我的名字是” + 名字;

使用以下代码将其序列化到文件中:

无效主([]参数){

=新的(“”);

文件 file = new File("E:"+ File.+"text.txt");

oos = 空;

输出=新的(文件);

oos = 新的(出);

oos.();

oos.close();

文件中保存的内容如下:

�í�sr�com..demo.ötB&�óO��L�namet�Ljava/lang/;xpt�

上面保存的内容是二进制数据。 保存的文件本身不能直接修改,因为这会破坏其保存的格式。

2.对象反序列化

使用对象输入流读入对象的过程称为反序列化。 简单来说,就是从一组序列化的二进制流中重构出一个对象的过程。

与反序列化密切相关的是对象输入流及其方法()

以下代码的工作原理是将上面序列化的二进制流读取到文件中。

无效主([]参数){

文件 file = new File("E:"+ File.+"text.txt");

ois = 空;

输入=新(文件);

ois = 新(输入);

= ois.();

ois.close();

。出去。(。());

上述代码的输出如下:

{名称=''}

接下来,如果向反序列化的目标对象添加一个方法,如下:

班级 {

姓名;

(姓名){

this.name = 名称;

@

() {

“{”+

"名称='" + 名称 + '\'' +

'}';

空白 ( )

, 在{

.out.("这是,哈哈");

那么上面的反序列化代码将会输出如下结果:

这是,哈哈

{名称='空'}

从上面可以看出,如果在反序列化的目标对象中重写了一个方法,那么反序列化的结果就是不再读取文件中的二进制流,而是直接执行重写的方法。 反序列化漏洞就来自这个地方。

如果目标对象执行一些比较复杂的操作,就很有可能为恶意代码提供可乘之机。 例如,在该方法中实现一个弹出计算器:

空白 ( )

{

=Class.("java.lang.")

.("",新类[]{})

。(无效的);

类.("java.lang.")

.(“执行”,.class)

.(,"calc.exe");

然后执行上面的main方法,就会弹出计算器,如下图:

1.png

3. 反序列化漏洞

反序列化漏洞是指程序传输不安全的反序列化对象,而程序没有对不安全对象进行过滤或限制,导致执行对系统有破坏性的不安全操作。

下面主要分析包中的反序列化漏洞。

4. 反序列化漏洞

此示例使用易受攻击的版本 3.1 进行说明。

4.1. 定义

它到底有什么奇妙的用途,让、、JBoss、、等纷纷对它青睐有加。 为了说明这一点,引用博客中的一段话:

这个包对Java中的集合类做了一些补充,定义了一些全新的集合,当然还实现了接口,比如Bag。 也有原来集合的新版本,eg 最后,更重要的是一系列utils类,为我们提供了常用的集合操作,可以极大方便我们的日常编程。

具体用途我还没有做过深入的研究。 本文主要关注为什么这个包存在反序列化漏洞。 通过一系列排查,发现该包中的反序列化漏洞是由 和 引起的。

4.2. 简要分析

该类用于对Map执行某些转换。 当我们修改Map中的某个值时,无论是key还是value,都会触发我们预定义的某些操作来处理Map。 该对象的实例化是通过其静态方法获得的,如下:

地图 = .(地图, , );

其中,map是一个普通的Map,分别对应key变化和value变化时需要进行的操作,其类型实现了该接口。 接口定义如下:

{

(变量1);

仅定义了一种方法。 当键或值发生变化时,将调用此方法。 如果需要触发一系列操作,可以自己定义。 具体操作如下:

首先定义一个数组:

[] = 新[] {

新的(...),

新的(...),

……

};

第二个实例化:

=新的();

最后传入实例化参数:

地图 = .(地图, 空, );

此时,如果map中的值发生变化,则会调用中定义的方法:

( ) {

for(int i = 0; i < this..; ++i) {

= 这个.[i].();

;

正如你所看到的,该类中的方法会将上一个转换的结果作为下一个转换的输入,直到所有转换完成并返回最终的转换。

现在真正的主角出现了。 如果变换链中有的话,也会调用该方法,其对应的方法实现如下:

(输入) {

如果(输入==空){

无效的;

} 别的 {

尝试 {

类 cls = 输入。();

= cls.(这个.,这个.);

.(输入,this.iArgs);

} catch (n var5) {

throw new (": '" + this.+ "' on '" + input.() + "' 不存在");

} catch(在 var6 上){

throw new (": '" + this.+ "' on '" + input.() + "' be ");

} catch (ption var7) {

throw new (": '" + this.+ "' on '" + input.() + "' 抛出了一个 ", var7);

从这里可以看出,它利用了反射机制来调用相应的方法。 如果输入是可控的,一些非法物体进入,就会带来安全隐患。 那么如何利用这个漏洞呢?

4.3. 利用率

成功使用需要满足的条件如下:

1. 序列化对象不安全

2. 反序列化对象有重写方法

3、外部触发方式

综合上述条件,简单利用该漏洞的序列化对象如下:

com..演示;

蒙斯..;

蒙斯……;

蒙斯……;

蒙斯……;

蒙斯..地图.;

java.io.*;

java.util.;

java.util.Map;

/**

* 反序列化

* @:兴.hang

标签: 序列 漏洞 操作

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码