PHP序列化(反序列化)处理器

session序列化与序列化(反序列化)处理器

先来看一下php的序列化(反序列化)处理器:

php_binary:存储方式是,键名的长度对应的ASCII字符+键名+经过serialize()函数序列化处理的值
php:存储方式是,键名+竖线+经过serialize()函数序列处理的值
php_serialize(php>5.5.4):存储方式是,经过serialize()函数序列化处理的值

我们来看一段代码enter description here这是一道反序列化的题目,但是仔细一看,这段代码连unserialize函数都没有,那该从哪里突破呢?可以看到,代码的第三行:ini_set('session.serialize_handler', 'php');,这行代码设置了序列化与反序列化时使用的处理器是php,首先我们看一下加个phpinfo参数看一下phpinfoenter description here发现session.upload_progress.enabled被设置为了on,这个非常关键enter description here看一下官方的例子enter description here所以,整个思路是,想办法在SESSION中加入一个变量。这个变量先经过php_serialize储存(默认使用php_serialize),然后在ini_set('session.serialize_handler', 'php');更改处理器,在session_start的时候反序列化,达到利用效果。这里的利用点就是session.upload_progress.enabled=On我们可以通过往SESSION中添加一个符合php处理器格式的字符串,比如,将$_SESSION['test']赋值为|abc,它通过php_serialize存储为a:1:{s:4:"test";s:4:"|123";}enter description here然后由于处理器的更改,|被视为key,value的分界线,也就是123是value,然后session_start进行反序列化,由于123是可控的,所以可被利用。这里修改$_SESSION的方法就是通过上传的时候添加一个<input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />,然后修改filename即可(因为从例子中可以看到,filename会被存在SESSION中)。

利用

首先获取序列化字符串enter description here在最前面加个|,且双引号要转义,扫描这个目录是因为phpinfo有根目录信息enter description here随便传个文件,改filenameenter description here可以看到,列目录成功了,有一个Here_1s_7he_fl4g_buT_You_Cannot_see.php,再构造一下就能读到flag了,这里差点被坑,当前目录并不是网站根目录,因为是用sh跑起来的,当前目录是根目录,所以不能直接读,要加上目录enter description here

Referer

https://chybeta.github.io/2017/06/17/%E6%B5%85%E8%B0%88php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/
https://juejin.im/entry/5a39fe5651882525ab7bebe1