赞
踩
关于反序列化,我更多的只是针对php和Java,把原理看懂了点,后面还会对反序列化进行详细总结
1.什么是序列化和反序列化?
序列化即将对象转化为字节流,便于保存在文件,内存,数据库中;反序列化即将字节流转化为对象
也就是把数据转化为一种可逆的数据结构,再把这种可逆的数据结构转化回数据,这就是序列化与反序列化
用途:
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
php反序列化:
序列化的函数:string serialize ( mixed $value )
当调用serialize()函数序列化对象时,该函数会检查类中是否存在一个魔术方法__sleep()。
如果存在,该方法会先被调用,然后才执行序列化操作。可以通过重载这个方法,从而自定义序列化行为。
该方法原型如下:
public array __sleep ( void )
该方法返回一个包含对象中所有应被序列化的变量名称的数组
该方法未返回任何内容,则 NULL 被序列化,并产生一个E_NOTICE级别的错误
__sleep()不能返回父类的私有成员的名字。这样做会产生一个E_NOTICE级别的错误。这时只能用Serializable接口来替代。
常用于保存那些大对象时的清理工作,避免保存过多冗余数据
**反序列化的函数:mixed unserialize ( string KaTeX parse error: Expected group after '_' at position 179: …之后,PHP会自动地试图去调用_̲_wakeup()成员函数(如…this->username的值不为空
反序列化时,会尽量将变量值进行匹配并复制给序列化后的对象
php的魔法函数:
_construct() 当一个对象被创建时调用
_destruct() 当一个对象被销毁时调用
_toString() 当一个对象被当作一个字符串使用
_sleep() 在对象再别序列化之前运行
_wakeup() 将在序列化之后调用
对象注入
当用户的请求在传给反序列化函数unserialize()之前没有被正确的过滤时就会产生漏洞。
因为PHP允许对象序列化,攻击者就可以提交特定的序列化的字符串给一个具有该漏洞的unserialize函数,最终导致一个在该应用范围内的任意PHP对象注入。
对象漏洞出现得满足两个前提:
一、unserialize的参数可控。
二、 代码里有定义一个含有魔术方法的类,并且该方法里出现一些使用类成员变量作为参数的存在安全问题的函数。
例子:
比如这个列子,直接是用户生成的内容传递给unserialize()函数,那就可以构造这样的语句
?test=O:1:“A”:1:{s:4:“test”;s:5:“lemon”;}
在脚本运行结束后便会调用_destruct函数,同时会覆盖test变量输出lemon。
java反序列化:
Java中的API实现:
位置: Java.io.ObjectOutputStream java.io.ObjectInputStream
序列化: ObjectOutputStream类 --> writeObject()
注:该方法对参数指定的obj对象进行序列化,把字节序列写到一个目标输出流中
按Java的标准约定是给文件一个.ser扩展名
反序列化: ObjectInputStream类 --> readObject()
注:该方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
1****.漏洞触发场景****
在java编写的web应用与web服务器间java通常会发送大量的序列化对象例如以下场景:
1)HTTP请求中的参数,cookies以及Parameters。
2)RMI协议,被广泛使用的RMI协议完全基于序列化
4)JMX 同样用于处理序列化对象
5)自定义协议 用来接收与发送原始的java对象
如何发现java反序列化漏洞
通过检索源码中对反序列化函数的调用来静态寻找反序列化的输入点
可以搜索以下函数:
ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject
在实战过程中,我们可以通过抓包来检测请求中可能存在的序列化数据。
序列化数据通常以AC ED开始,之后的两个字节是版本号,版本号一般是00 05但在某些情况下可能是更高的数字。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。