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

Java反序列化漏洞的原理分析

来源:本站整理 作者:佚名 时间:2018-05-04 TAG: 我要投稿

世界上有三件事最难:
把别人的钱装进自己的口袋里
把自己的想法装进别人的脑袋里
让自己的代码运行在别人的服务器上
前言
Java反序列化漏洞是近一段时间里一直被重点关注的漏洞,自从 Apache Commons-collections 爆出第一个漏洞开始,围绕着Java反序列化漏洞的事件就层出不穷,为了详细了解Java反序列化漏洞的成因和原理,本文将以 ysoserial 项目作为基础,以普通Java工程师的角度来逐步解释这类漏洞的原理。
本文涉及了大量的源码,尽可能保证开发者能够快速搭建实验环境进行漏洞的复现。Java反序列漏洞涉及大量的Java基础,而漏洞利用过程复杂巧妙,为了清晰地表达出其中的原理,粘贴了大量的代码片段。
核心要点
Java反序列化与 ObjectInputStream
在Java中,利用ObjectInputStream的readObject方法进行对象读取时,当目标对象已经重写了readObject方法,则目标对象readObject方法。如下代码所示
public class ReadObject implements Serializable {
  private void readObject(java.io.ObjectInputStream stream)
          throws IOException, ClassNotFoundException{
      System.out.println("read object in ReadObject");
  }
  public static void main(String[] args) throws IOException, ClassNotFoundException {
      byte[] serializeData=serialize(new ReadObject());
      deserialize(serializeData);
  }
  public static byte[] serialize(final Object obj) throws IOException {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      ObjectOutputStream objOut = new ObjectOutputStream(out);
      objOut.writeObject(obj);
      return out.toByteArray();
  }
  public static Object deserialize(final byte[] serialized) throws IOException, ClassNotFoundException {
       ByteArrayInputStream in = new ByteArrayInputStream(serialized);
       ObjectInputStream objIn = new ObjectInputStream(in);
       return objIn.readObject();
  }
}
以上代码将会输出
  read object in ReadObject
可见在反序列化的过程中,如果目标对象的readObject进行了一些更复杂的操作的时候,那么极有可能给恶意代码提供可乘之机。
利用java的反射来执行代码
Java的反射机制提供为Java工程师的开发提供了相当多的便利性,同样也带来了潜在的安全风险。反射机制的存在使得我们可以越过Java本身的静态检查和类型约束,在运行期直接访问和修改目标对象的属性和状态。Java反射的四大核心是 Class,Constructor,Field,Method,如下代码所示。我们将利用Java的反射机制来操纵代码调用本地的计算器
public static void main(String[] args) throws Exception {
      Object runtime=Class.forName("java.lang.Runtime")
              .getMethod("getRuntime",new Class[]{})
              .invoke(null);
      Class.forName("java.lang.Runtime")
              .getMethod("exec", String.class)
              .invoke(runtime,"calc.exe");
  }
以上代码中,我们利用了Java的反射机制把我们的代码意图都利用字符串的形式进行体现,使得原本应该是字符串的属性,变成了代码执行的逻辑,而这个机制也为我们后续的漏洞使用的前提。
从零开始
为了尽可能地将Java反序列化漏洞的原理讲述清楚,在本章节中,我们将站在一个攻击者和漏洞利用者的角度去观察如何使用Java的反序列化漏洞。
环境
要完成实验需要添加如下版本的库
  dependency>
    groupId>org.apache.commonsgroupId>
    artifactId>commons-collections4artifactId>
    version>4.0version>
  dependency>
  dependency>
    groupId>commons-collectionsgroupId>
    artifactId>commons-collectionsartifactId>
    version>3.1version>
  dependency>
 
  dependency>
    groupId>org.javassistgroupId>
    artifactId>javassistartifactId>
    version>3.22.0-GAversion>
  dependency>
靶子
在进行攻击之前,我们需要模拟出一个靶子,靶子代码如下,其主要功能是监听本地端口,并将端口中的数据进行反序列化。
  public static void main(String[] args) throws IOException {
      ServerSocket server = new ServerSocket(10000);
      while (true) {
          Socket socket = server.accept();
          execute(socket);
      }

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14]  下一页

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