导语

PHP反序列化是PHP代码审计中非常重要且有必要的一部分,今天由我来总结整合一下~

PHP反序列化漏洞

PHP反序列化漏洞是PHP在反序列化过程中对输入的数据处理不当造成的。在PHP反序列化的过程中,类中或许会有一些魔术方法(magic methods),在反序列化操作执行的时候会自动执行,而其中如果有包含参数的危险操作,就会引起PHP反序列化漏洞。

序列化与反序列化

做过一些网络编程的同学们应该都有过这样的体验,比如客户端和服务端都需要使用某个对象,而通过网络流发送对象首先就是要将他们变成流,这个过程就是序列化,从流中还原出原本的对象的过程就是反序列化。当然,转为json和xml的传输也是序列化。在PHP中,分别用serialize()和unserialize()函数实现序列化和反序列化。

魔术方法

在PHP中内置了一些以两个下划线开头的函数,他们会在特定的操作时自动的执行。php内置的魔术方法见手册
例如__construct()函数在我们新建一个类的对象时自动执行。

出现问题的地方

unserialize()函数中,比较需要特别注意的魔术方法是destruct()和wakeup()函数。
通过手册,我们可以知道,destruct()函数在对象被销毁时自动执行,而wakeup()函数在反序列化操作开始时自动执行,用以预先准备对象需要的资源。可以说这两个函数在反序列化过程中必被执行,如果这两个函数中有危险的动作,后果不堪设想。

危险的动作

我们在仔细逐层检查__wakeup()函数的过程中,如果看到这些函数的调用中有反序列化出的参数,那么就基本可以断定是存在反序列化漏洞了。
第一类:命令执行
exec() 执行一个外部程序
passthru() 执行外部程序并且显示原始输出
popen() 打开进程文件指针
system() 执行外部程序,并且显示输出
第二类:文件访问
file_put_contents() 将一个字符串写入文件
file_get_contents() 将整个文件读入一个字符串
unlink() 删除文件

有了以上的基础,可以去看看bugbank的这个视频
https://www.bilibili.com/video/BV1Ft41187ZX

进阶PHP反序列化漏洞

CVE-2016-7124(绕过__wakeup()函数)

影响PHP版本:before 5.6.25 and 7.x before 7.0.10
bug内容:反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过wakeup( )的执行
成因:这些版本的ext/standard/var_unserializer.c函数对无效的对象处理有误。对象属性个数的值大于真实的属性个数就是一个无效对象,而这会使
wakeup()函数被跳过。
危害:导致服务器拒绝或其他影响。

注入对象构造方法

反序列化可以控制类属性,private会加上%00A%00,而protected会加上%00*%00。
由此,我们可以构造pop链进行同名方法的利用。
具体可以看这篇
https://www.cnblogs.com/zpchcbd/p/12531997.html

Session反序列化漏洞

PHP中的Session经序列化后存储,读取时再进行反序列化。
PHP中有三种序列化处理器

处理器 存储方式
php 键名+竖线+serialize()函数反序列后的值
php_binary 键名长度对应的ASCII字符+键名+serialize()函数反序列后的值
php_serialize() serialize()函数反序列后的值

不同处理器的格式不同,当不同页面使用了不同的处理器时,由于处理的Session序列化格式不同,就可能产生反序列化漏洞。

PHAR利用

PHAR简介

PHAR (“Php ARchive”) 是PHP里类似于JAR的一种打包文件,在PHP 5.3 或更高版本中默认开启,这个特性使得 PHP也可以像 Java 一样方便地实现应用程序打包和组件化。一个应用程序可以打成一个 Phar 包,直接放到 PHP-FPM 中运行。

PHAR文件结构

PHAR文件由3或4个部分组成:
(1)stub就是一个简单的php文件,最简文件头为:
是可有可无的,若使用?>,则;与?>间至多一个空格。
文件头中必须包含__HALT_COMPILER();除此之外没有限制。(PHP通过stub识别一个文件为PHAR文件,可以利用这点绕过文件上传检测)

(2)manifest describing the contents //PHAR文件描述该部分存储文件名、文件大小等信息

(3)the file contents //PHAR文件内容

(4)[optional] a signature for verifying Phar integrity (phar file format only) //可选的签名部分,支持MD5和SHA1

攻击方法

PHAR文件的Meta-data可以是任何能够序列化的PHP对象,当PHAR文件被任何文件系统函数首次通过phar://协议解析时Meta-data部分会被反序列化,这个反序列化过程就是我们的攻击点,Meta-data部分填充payload。

上面几种的复现都可以在这里找到
https://www.cnblogs.com/ichunqiu/p/10484832.html

参考:
https://www.cnblogs.com/ichunqiu/p/10484832.html
https://www.cnblogs.com/ssooking/articles/6082457.html
https://www.cnblogs.com/zpchcbd/p/12531997.html