3. php反序列化从入门到放弃(入门篇) - bmjoker - 博客园

PHP 反序列化从入门到精通:原理与 POP 链构造详解_php反序列化pop链-CSDN博客

PHP反序列化漏洞从入门到深入8k图文介绍,以及phar伪协议的利用-泷羽Sec

CTFshow web入门web254-257

一、序列化介绍

1、什么是反序列化操作? - 类型转换

序列化:对象转换为数组或字符串等格式
反序列化:将数组或字符串等格式转换成对象

serialize() //将对象转换成一个字符串
unserialize() //将字符串还原成一个对象

2、如传输一个class(方便空格换行等数据传输)

class user{
      public $name='xiaozhu';
      public $sex='man';
      public $age='23';
}

$demo=new user();

$s=serialize($demo);//序列化函数

echo $s.'<br>';

结果为

//序列化
O:4:"user":3:{s:4:"name";s:6:"xiaozhu";s:3:"sex";s:3:"man";s:3:"age";i:23;}

//反序列化
object(user)#2 (3) {["name"]=> string(6) "xiaozhu" ["sex"]=>string(3) "man" ["age"]=> string(23)}

b:1 表示布尔值 true

b:0 表示 false

二、魔术方法介绍

1、介绍

2、为什么要魔术方法

PHP 里一类特殊方法,带两个下划线,框架/类库常用来做自动化处理,但也容易成为利用点(gadget)

数据的初始化、销毁等,在程序运行前先搞好一些事情

3、常见(参照图)

入门

__construct(): //当对象new的时候会自动调用
__destruct()://当对象被销毁时会被自动调用

中等

__toString(): //把类当作字符串使用时触发
__wakeup(): //unserialize()时会被自动调用
__sleep(): //serialize()执行时被自动调用

困难

__set(): //设置对象的属性时,若属性存在,则赋值;若不存在,则调用__set函数
__isset(): //在不可访问的属性上调用isset()或empty()触发
__get(): //读取对象属性时,若存在,则返回属性值;若不存在,则会调用__get函数

特别困难(一起上)

__invoke(): //当尝试以调用函数的方法调用一个对象时会被自动调用

__call(): //调用某个方法,若方法存在,则调用;若不存在,则会去调用__call函数。

__callStatic(): //在静态上下文中调用不可访问的方法时触发

__unset(): //在不可访问的属性上使用unset()时触发

__set_state(),调用var_export()导出类时,此静态方法会被调用

__clone(),当对象复制完成时调用

__autoload(),尝试加载未定义的类

__debugInfo(),打印所需调试信息

三、基础代码概念

1、类

一种“模板”或“类型”。就像描述一台机器的图纸,定义了它有哪些属性(变量)和方法(函数)。
class ctfShowUser {...} 定义类型(属性在类中列出)

class xiaoz{
public $username='xiaozhu';
public $password='xiao';
public $isvip=true;
}

//类名xiaoz

2、对象

根据类“制造”出来的实例。类是蓝图,对象是实物

$c = new ctfShowUser();

表示用 new 根据类创建一个对象 $c,属性有默认值(usernamepasswordisvip

3、属性

publicprotectedprivate 控制属性谁能访问

访问对象属性的语法是 ->,例如:echo $c->username; 会输出 xiaozhu

$this 就是“当前这个对象本身”,$this->username 就是在访问这个对象里的属性 username

$this:我正在操作机器
$this->username:我正在访问机器里的username零件(取这个对象的username属性)

4、new

$c = new ctfShowUser();
按照类 ctfShowUser 的定义造出一个对象

变量 $c 不是字符串,不是数组,而是一整个对象

访问$c的内部属性
$c->username
$c->password
$c->login()

四、漏洞成因

原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。

<?php
class B{
public $cmd='ipconfig';
public function __destruct(){
system($this->cmd);
}
}
//函数引用,无对象创建触发魔术方法
unserialize($_GET['x']);

五、反序列化漏洞如何利用?- POP链构造

POP:面向属性编程(Property-Oriented Programing)常用于上层语言构造特定调用链的方法,序列化攻击都在PHP魔术方法中出现可利用的漏洞,因自动调用触发漏洞,但如关键代码没在魔术方法中,而是在一个类的普通方法中。这时候就可以通过构造POP链寻找相同的函数名将类的属性和敏感函数的属性联系起来。

-反序列化常见起点(见图)

-反序列化常见跳板(见图)

-反序列化常见终点(见图)

#CTFSHOW-训练链构造

254-对象引用执行逻辑

255-反序列化变量修改1

256-反序列化参数修改2

257-反序列化参数修改&对象调用逻辑

258-反序列化参数修改&对象调用逻辑&正则

六、补充

反序列化对象 = 自动触发对象内部隐藏的方法

会触发什么漏洞?一般是RCE,看执行了魔术方法后面的代码是什么漏洞

黑盒中不可能发现漏洞

都是扫描器扫出来的,只问怎么利用,一些框架爆过反序列化漏洞,实战中挖不到

构造pop链过程,代码中需要改的地方留着

如:

<?php
class ctfShowUser{
    public $username='xiaozhu';
    public $password='xiao';
    public $isvip=true;
}
$c=new ctfShowUser();
echo urlencode(serialize($c));
?>

Cookie中传值如果有特殊符号要进行url编码 echo urlencode(serialize($c));

: " { } ;

七、关于oop和pop补充 编程基础

老师说有些学生学了三年,可能连编程语言是面向对象oop还是面向过程pop都不知道

PHP 反序列化漏洞是 OOP 语言特有的“对象生命周期 + 自动调用魔术方法”导致的。

面向对象(OOP)和面向过程(POP)编程区别_oop和面向过程编程-CSDN博客

oop五概念:类、对象、封装、继承、多态

小结

昨日之深渊 今日之浅谈

欢迎来访 这是我的小窝~ 网安弱鸡 健身屌丝 好不容易搭出来的 大佬略过我
最后更新于 2025-12-08