带你走进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工作流程

  1. 会话初始化

    • PHP尝试从请求中查找Session ID(通过Cookie、GET或POST)
    • 如果不存在,创建新Session ID并通过Set-Cookie发送给客户端
  2. 会话数据存储

    • 数据存储在$_SESSION超全局变量中
    • PHP停止时自动序列化$_SESSION内容并保存
  3. 会话保存机制

    • 默认使用文件系统保存(可配置)
    • 文件名格式通常为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 反序列化漏洞原理

漏洞成因

当应用程序混合使用不同的序列化处理器时,可能导致反序列化漏洞:

  1. 使用php_serialize处理器存储Session数据(允许包含特殊字符)
  2. 使用php处理器读取Session数据(将|作为分隔符)

攻击场景

攻击者可以注入包含|字符的恶意序列化数据,当使用不同处理器反序列化时,会将其解析为PHP对象。

漏洞利用条件

  1. 能够控制Session内容
  2. 服务器使用不同的序列化处理器进行读写
  3. 存在可被利用的魔术方法(如__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>

攻击步骤示例

  1. 准备恶意序列化数据

    <?php
    class Exploit {
        public $payload = '恶意代码';
        function __destruct() {
            system($this->payload);
        }
    }
    echo serialize(new Exploit());
    ?>
    
  2. 构造注入数据

    • 使用php_serialize处理器:|O:7:"Exploit":1:{s:7:"payload";s:10:"id";}
  3. 触发反序列化

    • 通过文件上传或其他方式写入Session
    • 当使用php处理器读取时,|后的内容会被反序列化

巅峰极客CTF例题分析

题目关键代码:

  1. 配置不一致

    // config.php
    'ini' => array(
        'session.serialize_handler' => 'php'
    )
    
    // Cache.class.php
    ini_set('session.serialize_handler', 'php_serialize');
    
  2. Session可控点

    $_SESSION['upload_progress_panda'] = 可控数据
    
  3. 利用链

    • 通过文件上传控制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反序列化漏洞是一种由于序列化处理器不一致导致的安全问题,攻击者可以利用该漏洞执行任意代码。防御的关键在于:

  1. 统一序列化处理器配置
  2. 严格控制Session数据来源
  3. 采用安全的会话配置
  4. 避免危险的反序列化操作

通过全面理解Session机制和潜在风险,开发者可以构建更安全的PHP应用程序。

0x09 参考资源

  1. PHP官方文档 - Session安全
  2. PHP Bug #71101 - Session序列化处理器不一致问题
  3. OWASP PHP安全指南
  4. 巅峰极客CTF 2019 lol题目分析
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配置关键项 安全相关配置 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写入: 攻击步骤示例 准备恶意序列化数据 : 构造注入数据 : 使用 php_serialize 处理器: |O:7:"Exploit":1:{s:7:"payload";s:10:"id";} 触发反序列化 : 通过文件上传或其他方式写入Session 当使用 php 处理器读取时, | 后的内容会被反序列化 巅峰极客CTF例题分析 题目关键代码: 配置不一致 : Session可控点 : 利用链 : 通过文件上传控制Session内容 构造恶意序列化数据写入Session 触发反序列化执行任意代码 0x07 防御措施 1. 统一序列化处理器 确保整个应用使用相同的序列化处理器(推荐 php_serialize ) 2. 严格会话配置 3. 限制Session数据 对写入Session的数据进行严格过滤 避免存储用户可控的复杂数据结构 4. 禁用危险功能 5. 安全编码实践 避免在魔术方法中执行危险操作 对反序列化操作进行严格限制 0x08 总结 PHP Session反序列化漏洞是一种由于序列化处理器不一致导致的安全问题,攻击者可以利用该漏洞执行任意代码。防御的关键在于: 统一序列化处理器配置 严格控制Session数据来源 采用安全的会话配置 避免危险的反序列化操作 通过全面理解Session机制和潜在风险,开发者可以构建更安全的PHP应用程序。 0x09 参考资源 PHP官方文档 - Session安全 PHP Bug #71101 - Session序列化处理器不一致问题 OWASP PHP安全指南 巅峰极客CTF 2019 lol题目分析