奇葩的php反序列化

前言


PHP存在着一个很有趣的漏洞,PHP对象注入,不过我们通常称为反序列化漏洞,虽然对于这个漏洞网上介绍的文章有很多,但是我感觉并没有达到通俗易懂,所以本篇文章将追求介绍最详细的php反序列化漏洞。力求小白也能看懂。

基础知识


再介绍漏洞之前我们先要来了解一下什么是反序列化,所有php里面的值,我们都可以使用函数serialize()来返回一个包含字节流的字符串来表示。见下图:

奇葩的php反序列化

序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。所以对象A和对象B序列化后并没有什么区别。

大家是不是看不懂序列化后是什么意思啊。别急,让我来解释一下。

s:16代表这个是字符串,字符串长度为16,a:2代表这个是数组,有两个数值。O代表对象,A和B是类名,a和b是类实例化后的对象名,i是数值类型。

unserialize()函数能够重新把字符串变回php原来的值。

漏洞产生原因


漏洞的根源在于unserialize()函数的参数可控。如果反序列化对象中存在魔术方法,而且魔术方法中的代码有能够被我们控制,漏洞就这样产生了,根据不同的代码可以导致各种攻击,如代码注入、SQL注入、目录遍历等等。

反序列化之代码注入


我们先来看一段存在漏洞的代码。奇葩的php反序列化

序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。所以对象A和对象B序列化后并没有什么区别。

大家是不是看不懂序列化后是什么意思啊。别急,让我来解释一下。

s:16代表这个是字符串,字符串长度为16,a:2代表这个是数组,有两个数值。O代表对象,A和B是类名,a和b是类实例化后的对象名,i是数值类型。

unserialize()函数能够重新把字符串变回php原来的值。

漏洞产生原因


漏洞的根源在于unserialize()函数的参数可控。如果反序列化对象中存在魔术方法,而且魔术方法中的代码有能够被我们控制,漏洞就这样产生了,根据不同的代码可以导致各种攻击,如代码注入、SQL注入、目录遍历等等。

反序列化之代码注入


我们先来看一段存在漏洞的代码。奇葩的php反序列化得到序列化后的字符串。
将序列化后的字符串提交,注意加上我们注入得代码。奇葩的php反序列化注入成功奇葩的php反序列化

总结


其实漏洞的核心思想还是在于unserialize函数,漏洞利用的核心思路在于控制魔术方法中的代码从而产生代码注入,SQL注入,目录遍历等一系列的漏洞利用。防御本漏洞就要严格控制unserialize函数的参数,对unserialize后的变量内容进行检查,确保绿色输入。

美食家

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: