session序列化与序列化(反序列化)处理器
先来看一下php的序列化(反序列化)处理器:
php_binary:存储方式是,键名的长度对应的ASCII字符+键名+经过serialize()函数序列化处理的值
php:存储方式是,键名+竖线+经过serialize()函数序列处理的值
php_serialize(php>5.5.4):存储方式是,经过serialize()函数序列化处理的值
我们来看一段代码这是一道反序列化的题目,但是仔细一看,这段代码连unserialize函数都没有,那该从哪里突破呢?可以看到,代码的第三行:ini_set('session.serialize_handler', 'php');
,这行代码设置了序列化与反序列化时使用的处理器是php,首先我们看一下加个phpinfo参数看一下phpinfo发现session.upload_progress.enabled
被设置为了on,这个非常关键看一下官方的例子所以,整个思路是,想办法在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";}
然后由于处理器的更改,|被视为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中)。
利用
首先获取序列化字符串在最前面加个|,且双引号要转义,扫描这个目录是因为phpinfo有根目录信息随便传个文件,改filename可以看到,列目录成功了,有一个Here_1s_7he_fl4g_buT_You_Cannot_see.php
,再构造一下就能读到flag了,这里差点被坑,当前目录并不是网站根目录,因为是用sh跑起来的,当前目录是根目录,所以不能直接读,要加上目录
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