• 序列化与反序列化的原理以及利用和防御


    1、序列化和反序列化的概念

    序列化:把对象转换为字节序列的过程称为对象的序列化。
    反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

    序列化就是把对象转换成字节流,便于保存在内存、文件、数据库中;反序列化即逆过程,由字节流还原成对象。Java中的ObjectOutputStream类的writeObject()方法可以实现序列化,类ObjectInputStream类的readObject()方法用于反序列化。下面是将字符串对象先进行序列化,存储到本地文件,然后再通过反序列化进行恢复

    如果Java应用对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行

    问题的根源在于类ObjectInputStream在反序列化时,没有对生成的对象的类型做限制;假若反序列化可以设置Java类型的白名单

    2、序列化的目的与用到序列化的情况

    当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
    当你想用套接字在网络上传送对象的时候;
    当你想通过RMI传输对象的时候;

    2.1对象序列化的步骤如下

    (1)创建对象输入流,它可以包装一个其他类型的目标输入流,例如:文件输出流。

    (2)通过对象输入流的writeObject()方法写对象。

    2.2.对象的反序列化如下:

     (1)创建对象输入流,同样的,可以包含其他类型的目标输出流,例如:文件输入流。

    (2)通过对象输入流的readObject()方法读取对象。

    3、漏洞挖掘

    基本手段:

    从可控数据的反序列化或间接的反序列化接口入手,在此基础上尝试构造序列化对象。

    首先拿到一个Java应用,需要找到一个接受外部输入的序列化对象的接收点,即反序列化漏洞的触发点。我们可以通过审计源码中对反序列化函数的调用(例如readObject())来寻找,也可以直接通过对应用交互流量进行抓包,查看流量中是否包含java序列化数据来判断,java序列化数据的特征为以标记(ac ed 00 05)开头。

    确定了反序列化输入点后,再考察应用的Class Path中是否包含Apache Commons Collections库(ysoserial所支持的其他库亦可),如果是,就可以使用ysoserial来生成反序列化的payload,指定库名和想要执行的命令即可:

    通过先前找到的传入对象方式进行对象注入,数据中载入payload,触发受影响应用中ObjectInputStream的反序列化操作,随后通过反射调用Runtime.getRunTime.exec即可完成利用。

    4、防御手段

    4.1 weblogic防御

    • 过滤T3协议,限定可连接的IP
    • 设置Nginx反向代理,实现t3协议和http协议隔离
    • JEP290(JDK8u121,7u131,6u141),这个机制主要是在每层反序列化过程中都加了一层黑名单处理

    4.2 原生反序列化防御

    • 不要反序列化不可信的数据
    • 给反序列数据加密签名,并确保解密在反序列之前
    • 给反序列化接口添加认证授权
    • 反序列化服务只允许监听在本地或者开启相应防火墙
    • 升级第三方库
    • 升级JDK,JEP290

  • 相关阅读:
    object-c中NSString与int和float的相互转换
    Keras
    TensorFlow白皮书
    java split进行字符串分割
    Java进行post和get传参数
    MySQL 导出数据
    解析xml并且导入mysql
    MySQL显示中文
    java使用sax解析xml
    mysql connection refused
  • 原文地址:https://www.cnblogs.com/wenyoudo/p/14119174.html
Copyright © 2020-2023  润新知