PHP反序列化
学习视频:橘子科技工作室
序列化:是将对象的状态信息转换为可以存储或传输的形式
在php中使用serialize()来进行序列化
序列化演示
1 |
|
数组序列化
1 |
|
对象序列化
1 |
|
私有修饰符序列化
私有属性在序列化之后的格式
private私有属性序列化时,在变量名前加”%00类名%00”
1 |
|
为什么是testpub:
为了再还原时,能把类名还原回去,所以类名+属性名(确切来说%00+类名+%00+属性名)
为什么是9:
%00test%00pub
保护修饰符序列化
保护属性修饰符在序列化之后的格式
1 |
|
在属性名前加一个*
*pub
为什么是6:
%00+*+%00+pub
成员属性调用对象
1 |
|
反序列化漏洞
- 反序列化生成的对象里的值,由反序列化里的值提供,与原有类预定义的值无关
反序列化漏洞的成因:反序列化过程中,unserialize()接收的值(字符串)可控,通过更改这个值,得到所需要的代码,即生成的对象的属性值
- 反序列化不改变类的成员方法,需要调用方法才能触发
例题:
1 |
|
魔术方法
一个预定义好的,在特定情况下自动触发的行为方法
魔术方法在特定条件下自动调用相关方法,最终导致触发代码
- 魔术方法相关机制
触发时机、功能、参数、返回值
__construct()
构造函数,在实例化一个对象时,首先会自动执行的一个执行方法
1 |
|
| 触发时机 | 功能 | 参数 | 返回值 |
|---|---|---|---|
| 实例化对象 | 提前清理不必要的内容 | 非必要 |
- 在序列化和反序列化中不会触发
__destruct()
析构函数,在对象的所有引用被删除或者当对象被显示销毁时执行的魔术方法
1 |
|
创建对象不触发析构函数,当用完对象,销毁时触发析构函数
| 触发时机 | 功能 | 参数 | 返回值 |
|---|---|---|---|
| 对象被引用完成或对象被销毁 |
- 在序列化过程中不会触发
- 在反序列化过程中会触发
- 反序列化得到的是对象,用完会销毁
例题:
1 |
|
__sleep()
序列化serialize()函数会检查类中是否存在一个魔术方法__sleep(),如果存在,该方法会先被调用,然后才执行序列化操作。
此功能可用于清理对象
1 |
|
__sleep()执行返回需要序列化的变量名,过滤掉password变量
serialize()只序列化sleep返回的变量
| 触发时机 | 功能 | 参数 | 返回值 |
|---|---|---|---|
| 序列化serialize()之前 | 返回需要被序列化存储的成员属性,删除不必要的属性 | 成员属性 | 需要被序列化存储的成员属性 |
例题:
1 |
|
序列化函数之前会先执行sleep函数,从而执行system指令
__wakeup()
unserialize()会检查是否存在一个__wakeup()方法,如果存在,则会先调用__wakeup()方法,预先准备对象需要的资源,返回void,常用于反序列化操作中重新建立数据库连接或执行其他初始化操作
- __wakeup()在反序列化之前
- __destruct()在反序列化之后
1 |
|
| 触发时机 | 功能 | 参数 | 返回值 |
|---|---|---|---|
| 反序列化unserialize()之前 |
例题:
1 |
|
__toString()
表达方式错误导致魔术方法触发
1 |
|
| 触发时机 | 功能 | 参数 | 返回值 |
|---|---|---|---|
| 把对象当成字符串调用 |
__invoke()
格式表达错误导致魔术方法触发
把对象当成函数调用
1 |
|
| 触发时机 | 功能 | 参数 | 返回值 |
|---|---|---|---|
| 把对象当成函数调用 |
错误调用相关魔术方法
pop链前置知识
1 |
|
分析:

构造序列化:

构造序列化:
1 |
|
输出的序列化字符串,将test参数更改为private参数的格式
1 | O:5:"index":1:{s:11:"%00index%00test";O:4:"evil":1:{s:5:"test2";s:19:"system('ipconfig');";}} |
pop链前置知识魔术方法触发规则
魔术方法触发前提:魔术方法所在类(或对象)被调用

1 |
|
echo 把反序列化生成的对象当成字符串输出触发所在类的tostring()方法
反序列化触发$b所调用的类fast()里包含了wakeup()
POC构造:

POP链构造 POC编写
POP链
- 在反序列化中,我们能控制的数据就是对象中的属性值(成员变量),所以在PHP反序列化中有一种漏洞利用方法叫”面向属性编程”,即POP( Property Oriented Programming)。
- POP链就是利用魔法方法在里面进行多次跳转然后获取敏感数据的一种payload。
POC
- POC(全称:Proofofconcept)中文译作概念验证。在安全界可以理解成漏洞验证程序。POC是一段不完整的程序,仅仅是为了证明提出者的观点的一段代码。
例子
1 |
|
构造POC:
1 |
|