序列化与反序列化是什么
这其实是为了解决 PHP 对象传递的一个问题,因为 PHP 文件在执行结束以后就会将对象销毁,这样当你想用时又没得调用,于是人们就想出了一种能长久保存对象的方法,这就是 PHP 的序列化。
php序列化可以将对象转换成字符串,但只序列化属性,不序列化方法。
序列化的目的是方便数据的传输和存储. json 是为了传递数据的方便性.
关键函数:
- 序列化函数 serialize
- 反序列化函数 unserialize
常见魔术方法:
-
__construct(),类的构造函数,当对象创建时会自动调用(但在unserialize()时是不会自动调用的)。
-
__destruct(),类的析构函数
-
__call(),在对象中调用一个不可访问方法时调用
-
__callStatic(),用静态方式中调用一个不可访问方法时调用
-
__get(),获得一个类的成员变量时调用
-
__set(),设置一个类的成员变量时调用
-
__isset(),当对不可访问属性调用isset()或empty()时调用
-
__unset(),当对不可访问属性调用unset()时被调用。
-
__sleep(),执行serialize()时,先会调用这个函数
-
__wakeup(),执行unserialize()时,先会调用这个函数
-
__toString(),类被当成字符串时的回应方法
-
__invoke(),调用函数的方式调用一个对象时的回应方法
-
__set_state(),调用var_export()导出类时,此静态方法会被调用。
-
__clone(),当对象复制完成时调用
-
__autoload(),尝试加载未定义的类
-
__debugInfo(),打印所需调试信息
php反序列化漏洞必须要两个条件:
-
存在反序列化漏洞的php对象
-
unserialize函数漏洞可控
PHP反序列化利用
__wakeup()绕过
序列化后,当对象的属性(变量)数大于实际的个数时,__wakeup()魔法函数被绕过
只适用于PHP5.6.25之前版本和7.0.10之前的7.x版本
--------例题:[网鼎杯 2020 青龙组]AreUSerialz
对象逃逸
--------例题:[安洵杯 2019]easy_serialize_php
字符串逃逸
--------例题:[0CTF 2016] piapiapia
p.s. 具体差别在哪我也没有分清,上面一道是关键词数减少,
下面这道是关键词数增加,where->hacker,这样词数由五个增加到6个,导致字符串溢出,即尾部字符串逃逸,改变序列化结构。
pop链构造
总结来说,就是从unserialize函数出发,看看有没有我们可控的参数,再寻找类中我们可控的属性,构造pop链,(通常就是出发各种魔术方法),去调用危险函数。详细的话去看下面两篇推荐博客吧,人家写得比我好。
代码审计的时候,除了常见的include,file_get_contents,unlink等函数,还可以关注下面几个命令执行的函数
exec( ),passthru(),popen(),system()
Phar文件反序列化
phar 文件包在 生成时会以序列化的形式存储用户自定义的 meta-data ,配合 phar:// 我们就能在文件系统函数 file_exists() is_dir() 等参数可控的情况下实现自动的反序列化操作,于是就能通过构造精心设计的 phar 包在没有 unserailize() 的情况下实现反序列化攻击,使得 PHP 反序列化漏洞的触发条件大大拓宽了。可以自己去百度一下phar文件结构。
如何伪造phar文件?
注意:要将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件
一个简单的示例–test.php:
class request{
public $filename="phpinfo();";
}
$phar = new Phar("test.phar");//后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER();?>")//设置stub,必写,进行表识phar文件
$o = new request();
$phar->setMetadata($o);//自定义meta-data然后存入mainfest
$phar->addFromString("flag.php","flag");//添加要压缩的文件
$phar->stopBuffering();
将test.php上传到服务器后,访问就可以生成test.phar,再通过phar://test.phar/flag.php 就能拿到flag
参考博客:
从CTF中学习PHP反序列化的各种利用方式
PHP反序列化从初级到高级利用篇
php反序列化|无unserialize函数反序列化漏洞
PHP序列化和反序列化
初探PHP反序列化