悬镜安全丨Java 反序列化任意代码执行漏洞分析与利用

本文首发平台:悬镜官网,如需转载,请联系小编,谢谢。

       2015年的1月28号,Gabriel Lawrence (@gebl)和Chris Frohoff (@frohoff)在AppSecCali上给出了一个报告[3],报告中介绍了Java反序列化漏洞可以利用Apache Commons Collections这个常用的Java库来实现任意代码执行。

       同年11月6日,FoxGlove Security安全团队的@breenmachine在一篇博客中[2]介绍了如何利用Java反序列化漏洞,来攻击最新版的WebLogic、WebSphere、JBoss、Jenkins、OpenNMS这些大名鼎鼎的Java应用,实现远程代码执行。

       距离漏洞发布已经有了一年多的时间,仍然有很多网站仍未修复漏洞。

1.漏洞原理

1.1 Java序列化与反序列化

       简单的说,把对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为对象的过程称为对象的反序列化。

       Java序列化的目的是为了将某些对象存储到磁盘上,从而长期保存,例如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。

       或者当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。

       发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

一个序列化与反序列化的典型场景如下:

```

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class deserial {

public static void main(String args[]) throws Exception {
    String obj = "hello world!";

    // 将序列化对象写入文件object.db中
    FileOutputStream fos = new FileOutputStream("object.db");
    ObjectOutputStream os = new ObjectOutputStream(fos);
    os.writeObject(obj);
    os.close();

    // 从文件object.db中读取数据
    FileInputStream fis = new FileInputStream("object.db");
    ObjectInputStream ois = new ObjectInputStream(fis);

    // 通过反序列化恢复对象obj
    String obj2 = (String)ois.readObject();
    System.out.println(obj2);
    ois.close();
}

} ```

1.2Java 反序列化漏洞

       Java 反序列化漏洞的核心在于,由于Java中的类ObjectInputStream在反序列化时,没有对生成的对象的类型做限制。

       在反序列化的时候不需要指定原来的数据类型即可进行反序列化。如下代码仍可以执行:import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class deserial { public static void main(String args[]) throws Exception { String obj = "hello world!"; // 将序列化对象写入文件object.db中 FileOutputStream fos = new FileOutputStream("object.db"); ObjectOutputStream os = new ObjectOutputStream(fos); os.writeObject(obj); os.close(); // 从文件object.db中读取数据 FileInputStream fis = new FileInputStream("object.db"); ObjectInputStream ois = new ObjectInputStream(fis); // 通过反序列化恢复对象obj Object obj2 = ois.readObject(); System.out.println(obj2); ois.close(); } }       那么对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行。

       反序列漏洞由来已久,PHP 和 Python 中也有同样的问题,而在 Java 中问题比较严重的原因是因为一些公用库,例如Apache Commons Collections中实现的一些类可以被反序列化用来实现任意代码执行。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值