PHP反序列化漏洞是一种常见的漏洞,在本篇文章中,希望能深入简出的让各位即使没有安全背景的读者明白什么是PHP反序列化漏洞,以及如何利用。

如有错误不足之处,请不吝指教。

你需要的前置知识

  1. PHP类与对象
  2. PHP魔术方法
  3. PHP反序列化方法

PHP类与对象

先从最简单的开始。

在PHP中,定义一个类,和定义一个类的方法。

一个简单的例子:

PHP魔术方法

在PHP官方网站中的定义:

__construct()__destruct()__call()__callStatic()__get()__set()__isset()__unset()__sleep()__wakeup()__toString()__invoke()__set_state()__clone()__debugInfo() 等方法在 PHP 中被称为”魔术方法”(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。

咱们来简单讲解几个魔术方法

  1. __construst()
  2. __destruct()
  3. __toString()

__construst() 方法在每次创建新对象时会被自动调用

__destruct() 方法在使用 exit() 终止脚本运行时也会被自动调用

_toString() 方法在一个类被当成字符串时应怎样回应。例如 _echo $obj; 应该显示些什么。

代码:


输出结果:

2018102917599-PHP反序列化漏洞详细教程及实例(上)-4

PHP对象序列化

在PHP网站中的定义:

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。

简单的理解序列化:就是把一个类的实例变成一个字符串。

简单的理解反序列化:把一个特殊的字符串转换成一个实例。

代码:

输出结果:

高亮部分即为序列化后的对象。

反序列化的操作:

2018102918019-PHP反序列化漏洞详细教程及实例(上)-7

代码执行效果:

2018102918026-PHP反序列化漏洞详细教程及实例(上)-8

想要深入了解序列化后的字符的具体意义,请参考这个链接:

1
http://php.net/manual/zh/function.serialize.php

小试牛刀

通过上面的前置知识,相信大家已经对PHP序列化相关的内容有一个初步的认识。下面来开始分析一个简单的例子。

201810291810-PHP反序列化漏洞详细教程及实例(上)-9

这是一个WTFLog 类,调用 loginfo 方法会记录一条记录到access.log文件中,WTF的地方是,当这个类完成它的使命的时候(exit),会删除掉它所记录的文件。

201810291819-PHP反序列化漏洞详细教程及实例(上)-11

这里有一个“正常”的业务,pets.php :

2018102918115-PHP反序列化漏洞详细教程及实例(上)-10

该代码的业务目标是从用户处收集序列化后的数据,并进行一些操作。

该代码段的特点是:直接使用客户端可以控制的输入点($_GET[‘pet_serialized]),在不进行验证的情况下,直接实例化了这段代码!!

看我们如何利用这个危险的输入点:

还记得刚才的WTFLog吧!

先新创建一个新的poc.php,把 log.php 内的WTFLog类引入进来。

2018102918146-PHP反序列化漏洞详细教程及实例(上)-12

index.php 是一个很有用的文件,会输出一句话。

2018102918153-PHP反序列化漏洞详细教程及实例(上)-13

运行 poc.php ,得到我们想要的序列化后的WTFLog 字符串。

201810291822-PHP反序列化漏洞详细教程及实例(上)-15

1
O:6:'WTFLog':1:{s:8:'filename';s:9:'index.php';}

这里利用这个字符串,去调用pets.php

2018102918225-PHP反序列化漏洞详细教程及实例(上)-17

本来要删除掉access.log这个文件,却删除了我们的重要文件index.php。

验证一下:

2018102918229-PHP反序列化漏洞详细教程及实例(上)-18

到了这一步,漏洞已经利用完成。

回顾一下整个漏洞利用的过程:

  1. 需要有一个漏洞触发点 pets.php 内的 $pet = unserialize($_GET[‘pet_serialized’]);
  2. 需要有一个相关联的,有魔术方法(会被自动调用)的类。log.php (WTFLog 内的__destruct函数)
  3. 漏洞的效果取决于__destruct 这个魔术函数内的操作,这里的是可以操控的可以删除的log 的 filename。
  4. 构建poc.php ,利用程序,先序列化后,从可控输入$_GET[‘pet_serialized’]输入进去。
  5. 完成。

结语

大家从上面的过程中对PHP反序列化的方式及危害有了一个比较直观的理解了。那如何利用PHP反序列化这个漏洞来做更多的事情呢,这里需要看更多的魔术方法的自动触发的情景,根据不同的使用情景(代码实现方式),来定制我们的Poc,如果可控代码中,存在call_user_func() 这个函数,可以实现通过PHP反序列化漏洞来进行任意代码执行。

结语的下一步

下一篇文章将会分析一下Typecho 这个很受欢迎的Blog程序的反序列化漏洞的利用。

Thanks for watching.