Session反序列化漏洞解析

参考文章:PHP session反序列化漏洞超详细讲解_php技巧_脚本之家 (jb51.net)

一、前置基础

1、session请求过程:

当某个用户第一次访问网站时,Session_start()函数会创建一个唯一的SessionID,并通过HTTP响应头,也就是返回包,将SessionID保存在客户端,也就是用户浏览器的Cookie中。与此同时,服务端也会在本地创建一个以SessionID命名的文件,用来保存这个用户的会话信息。当用户再次访问这个网站时,会自动通过HTTP请求头将Cookie中保存的SessionID再次发送给服务端,此时Session_start()函数不会再次分配一个SessionID,而是去寻找和这个SessionID同名的Session文件,将之前存储的信息读出,在当前脚本使用,达到跟踪用户的功能。

2、session配置

在探讨session反序列化漏洞时我们只需要关注存储引擎即可

注:session文件存储路径在php.ini文件中的session.save_path中(Linux默认为/tmp目录下)

PHP:

存储方式:键名+|+经过serialize函数处理后的值;

测试代码:

php 复制代码
<?php
error_reporting(0);
ini_set('session.serialize_handler','php');
session_start();
$_SESSION['username'] = $_GET['user'];
echo "<pre>";
var_dump($_SESSION);
echo "</pre>";

当参数为user=123

输出结果为:

username|s:6:"123123";

PHP_serialize:

存储方式:经过serialize函数处理后的值

测试代码:

php 复制代码
<?php
error_reporting(0);
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['username'] = $_GET['user'];
echo "<pre>";
var_dump($_SESSION);
echo "</pre>";

输出结果为:

a:1:{s:8:"username";s:6:"123123";}

PHP_binary:

存储方式:键名长度所对应的ASCII码+键名+经过serialize函数处理后的值

测试代码:

php 复制代码
<?php
error_reporting(0);
ini_set('session.serialize_handler','php_binary');
session_start();
$_SESSION['username'] = $_GET['user'];
echo "<pre>";
var_dump($_SESSION);
echo "</pre>";

输出结果为:

usernames:6:"123123";

二、session反序列化漏洞

根据上面不同的session存储引擎可知,不同的存储引擎有着不同的解析方式,当存储引擎使用不当则可能会出现反序列化漏洞,如下:

serialize.php

php 复制代码
<?php
error_reporting(0);
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['username'] = $_GET['user'];
echo "<pre>";
var_dump($_SESSION);
echo "</pre>";  

serialize1.php

php 复制代码
<?php
error_reporting(0);
ini_set('session.serialize_handler','php');
session_start();
class user{
    var $name;
    var $age;
    function __wakeup(){
        echo "hello ".$this->name." !";
    }
}

以上两PHP文件在session的存储引擎上采用了不同的方式,因此在解析session文件中的数据时就产生了歧义,如对于php_serialize来说 "|"仅仅只是一个字符,但对于php而言则是分割符,因此对session产生了不同的解析结果,我们通过如下脚本生成payload

makepayload.php

php 复制代码
<?php
class user {
    var $name;
    var $age;
}
$a = new user();
$a ->age="888";
$a ->name="cc";
echo "|".serialize($a);

payload:

|O:4:"user":2:{s:4:"name";s:2:"cc";s:3:"age";s:3:"888";}

通过user传参给serialize.php

php_serialize解析结果:

a:1:{s:8:"username";s:56:"|O:4:"user":2:{s:4:"name";s:2:"cc";s:3:"age";s:3:"888";}";}

此时我们访问serialize1.php,则会发现输出结果hello,cc!

分析:

对于serialize.php文件中的数据是一整条经过serialize函数处理后的结果,其代表的含义仅仅是一个username的键对应|O:4:"user":2:{s:4:"name";s:2:"cc";s:3:"age";s:3:"888";}的值,在php_serialize眼中这仅仅只是个字符串。

但对于serialize1.php文件中的php_serialize而言整条数据是这样的

键名:username

值:O:4:"user":2:{s:4:"name";s:2:"cc";s:3:"age";s:3:"888";}

在php眼中的"|"是分割符因此他直接将后面的数据解析为对象了,从而产生了反序列化漏洞

相关推荐
Suckerbin5 小时前
LAMPSecurity: CTF5靶场渗透
笔记·安全·web安全·网络安全
不老刘6 小时前
行为式验证码技术解析:滑块拼图、语序选词与智能无感知
网络安全·验证码·行为式验证码
悠悠~飘8 小时前
php简介(第一天打卡)
php
房屋安全鉴定检测11 小时前
房屋安全鉴定报告有效期多久
安全·网络安全
久绊A11 小时前
Hydra-SSH 破解安全防范
开发语言·php
黑白世界464811 小时前
开源分享: php-tools php gui的一次尝试
后端·php
房屋安全鉴定检测12 小时前
房屋安全鉴定需要什么条件
安全·网络安全
FLS16814 小时前
Kali搭建sqli-labs靶场
linux·sql·安全·网络安全
不是三毛没有半14 小时前
华为USG6000v2 NAT模式下IPSEC IKE V1 实验
网络·网络安全·华为
2503_9284115615 小时前
9.8 ajax+php基础语法
ajax·okhttp·php