php反序列化漏洞基础篇

发布于 2020-10-13  84 次阅读


前言:为什么要说基础呢,因为本人php目前是个小白啊,哈哈哈

一、PHP反序列化漏洞

说到反序列化就要先说序列化,反序列化和序列化都伪造着两个函数来弄。它们是serialize()和unserialize()

  • serialize()是用于将类转换为一个字符串
  • unserialize()用于将字符串转换回一个类

serialize()

网页显示

10 300x44 - php反序列化漏洞基础篇

输出结果

输出解读:O代表存储的是对象(Object),4代表名称有4个字符。test表示对象的名称,1表示有一个值,{s:4:"test";s:4:"test";}中,s表示字符串,4表示该变量的名称长度,value:test。5表示变量的值的长度为5,value:test1

unserialize()

与serialize()对应的,unserialize()可以从序列化后的结果中恢复对象(Object)。

307 300x51 - php反序列化漏洞基础篇

输出结果为:

test为对象,[test]=>test1代表$test="test1"

注意:当使用 unserialize() 恢复对象时, 将调用 __wakeup() 成员函数

二、反序列化漏洞产生的原因

当参数传给unserialize()的参数可控时,我们可以通过一个序列化字符串。从而控制对象内部的变量甚至是函数

利用构造函数

Magic function

php中有一类特殊的方法叫做“Magic function”,重点需要关注的

  • 构造函数__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的
  • 析构函数__destruct():当对象被销毁时会自动调用。
  • __wakeup():如前言所提,unserialize()时会自动调用

20 300x111 - php反序列化漏洞基础篇

输出解读:序列化调用函数为_construct()、 _destruct(),反序列化调用函数为_wakeup()。

wakeup() 或destruct()由前可以看到,unserialize()后会导致wakeup() 或destruct()的直接调用,中间无需其他过程。因此最理想的情况就是一些漏洞/危害代码在wakeup() 或destruct()中,从而当我们控制序列化字符串时可以去直接触发它们。

其他Magic function的利用

1.但如果一次unserialize()中并不会直接调用的魔术函数,比如前面提到的construct(),是不是就没有利用价值呢?非也。类似于PWN中的ROP,有时候反序列化一个对象时,由它调用的wakeup()中又去调用了其他的对象,由此可以溯源而上,利用一次次的“gadget”找到漏洞点。

利用普通成员方法

前面谈到的利用都是基于“自动调用”的magic function。但当漏洞/危险代码存在类的普通方法中,就不能指望通过“自动调用”来达到目的了。这时的利用方法如下,寻找相同的函数名,把敏感函数和类联系在一起。


星榆叶叶昼离披,云粉千重凝不飞。