PHP反序列化

PHP反序列化漏洞

一、基础概念

1. PHP序列化

  • 定义:将复杂数据结构转换为字符串以便传输或存储。
  • 函数serialize()
  • 示例
  $data = ["name" => "test", "age" => 20];
  echo serialize($data); 
  // 输出:a:2:{s:4:"name";s:4:"test";s:3:"age";i:20;}

2. PHP反序列化

  • 定义:将序列化字符串恢复为原始数据结构。
  • 函数unserialize()
  • 风险:若参数可控且未校验,可导致对象注入漏洞。

3. 反序列化漏洞

  • 别名:PHP对象注入(PHP Object Injection)
  • 成因
    • 使用unserialize()且参数可控
    • 类中定义了危险魔术方法(如__wakeup()

二、常见魔术方法

魔术方法 触发条件
__construct() 对象创建时自动调用
__destruct() 对象销毁时自动调用
__wakeup() 调用unserialize()时触发
__sleep() 调用serialize()时触发
__toString() 对象被当作字符串使用时触发
__invoke() 对象被当作函数调用时触发
__call() 调用不存在或不可访问的方法时触发

三、序列化格式解析

示例序列化字符串:
O:10:"ThreeBody":1:{s:4:"name";s:4:"test";}

部分 说明
O 表示对象(Object)
10 类名长度
"ThreeBody" 类名
1 对象属性数量
s:4:"name" 字符串属性名(长度4)
s:4:"test" 字符串属性值(长度4)

四、漏洞实例分析

漏洞代码

class A {
    public $test = "demo";
    
    public function __wakeup() {
        eval($this->test); // 高危操作:执行任意代码
    }
}

// 序列化示例
$b = new A();
echo serialize($b); 
// 输出:O:1:"A":1:{s:4:"test";s:4:"demo";}

// 反序列化触发点
$a = $_GET["test"];
$a_unser = unserialize($a);

攻击Payload

http://target.com/vuln.php?test=O:1:"A":1:{s:4:"test";s:10:"phpinfo();";}

漏洞原理

  1. 攻击者控制$test属性值为phpinfo();
  2. 反序列化时触发__wakeup()执行eval("phpinfo();")

五、防御措施

1. 输入控制

// 禁止直接反序列化用户输入
$allowed_classes = [];
$data = unserialize($_GET['data'], ['allowed_classes' => $allowed_classes]);

2. 使用安全替代方案

// 优先使用JSON
$data = json_decode($_GET['data'], true);

3. 安全配置

; php.ini配置
disable_functions = eval,exec,passthru

六、拓展工具

  • PHPGGC:反序列化Payload生成工具
  • RIPS:静态代码分析工具

最后更新:2024年9月12日

posted @ 2025-12-02 09:23  shinianyunyan  阅读(43)  评论(0)    收藏  举报