反序列化之魔术方法的浅学习

PHP反序列化漏洞之魔术方法 PHP魔术方法(Magic Methods)是一组特殊的方法,它们在特定的情况下会被自动调用,用于实现对象的特殊行为或提供额外功能。本文详细介绍每一个魔术方法的触发时机、功能、参数以及返回值。这一点是在学习 PHP 反序列化漏洞中最重要的。 阅读详情
AI摘要

本文详细解读PHP中的反序列化魔术方法,包括__construct、__destruct、__sleep、__wakeup、__toString和__invoke等,并通过实例演示如何在对象创建、销毁、序列化和反序列化过程中利用这些方法。

前言

学习反序列化,那么就需要首先掌握魔术方法的使用,本篇文章将尽可能详细的讲解反序列化的魔术方法,博主只是小白,如有问题还请各位师傅多多指点!

魔术方法

常见魔术方法有以下几种

__construct()   当一个对象创建时被调用,
__destruct()   当一个对象销毁时被调用,
__toString()   当一个对象被当作一个字符串被调用。
__wakeup()   使用unserialize时触发
__sleep()    使用serialize时触发
__destruct()    对象被销毁时触发
__call()    在对象上下文中调用不可访问的方法时触发
__callStatic()    在静态上下文中调用不可访问的方法时触发
__get()    用于从不可访问的属性读取数据
__set()    用于将数据写入不可访问的属性
__isset()    在不可访问的属性上调用isset()或empty()触发
__unset()     在不可访问的属性上使用unset()时触发
__toString()    把类当作字符串使用时触发,返回值需要为字符串
__invoke()   当脚本尝试将对象调用为函数时触发

这是整体的,但这样看似乎显得过于抽象,因此我们将其进行分类,依次进行举例讲解

__construct()与__destruct()

__construct : 在创建对象时候初始化对象,一般用于对变量赋初值。
__destruct : 和构造函数相反,当对象所在函数调用完毕后执行。
<?php
class bai{
	public $name;
	public $age;
	public function __construct()
    {
		echo "__construct()初始化<br>";
		$this->name;
		$this->age;
	}
    public function __destruct()
    {
        echo "__destruct()执行结束";
    }		
 }
 $a=new bai(); //创建一个对象命名为a
 /*
 赋值
 $a->name='quan9i'; //给对象a里的name赋值为quan9i
 $a->age=19; //给对象a里的age赋值为19
 echo(serialize($a)); //输出序列化后的$a
 */

在这里插入图片描述
但这是一种,__destruct还有一种利用方式,就是__destruct() 对象被销毁时触发,它的栗子如下

<?php
class bai{
	public $name;
	public $age;
	public function __construct($name,$age)
    {
		echo "__construct()初始化<br>";
		$this->name=$name;//将传入的第一个参数赋值给name变量
		$this->age=$age;
	}
    public function __destruct()
    {
        echo "__destruct()执行结束<br>";
    }		
 }
 //主动销毁
 $a=new bai('quan9i',19);
 unset ($a);//主动销毁对象,此时先触发destruct魔法函数再echo
 echo"777<br>";
 echo "------------分隔符----------------<br>";
 //自动销毁
 $b=new bai('quan9i',19);
 echo "123<br>";
 //此时先echo再触发destruct函数
?>

执行结果
在这里插入图片描述

__sleep()

__sleep()    serialize 之前被调用,可以指定要序列化的对象属性。
<?php
class bai{
	public $name;
	public $age;
	public function __construct($name,$age)
    {
		echo "__construct()初始化<br>";
		$this->name=$name;
		$this->age=$age;
	}
    public function __sleep()
    {
        echo "当使用serialize时触发此方法<br>";
        return array('name','age');
    }   
}
$a=new bai('quan9i',19);
echo serialize($a);
?>

在这里插入图片描述

__wakeup()

__wakeup()   反序列化恢复对象之前调用该方法

实例如下

<?php
class bai{
	public $name;
	public $age;
	public function __construct($name,$age)
    {
		echo "__construct()初始化<br>";
		$this->name=$name;
		$this->age=$age;
	}
    public function __wakeup()
    {
        echo "当使用unserialize时触发此方法<br>";
        $this->age=1000;//更改$age的值为1000
    }
}
$a=new bai('quan9i',19);
$b= serialize($a);
var_dump(unserialize($b));
?>

在这里插入图片描述

__toString()

__toString() :在对象当做字符串的时候会被调用。

实例如下

<?php

class Test
{
    public $a = 'This is a string';

    public function good(){
        echo $this->a.'<br />';
    }

    // 在对象当做字符串的时候会被调用
    public function __toString()
    {
        return '__toString方法被调用 <br>';
    }
}

$a = new Test();
$a->good();
echo $a;
?>

在这里插入图片描述

__invoke()

__invoke() :将对象当作函数来使用时执行此方法。

示例如下

<?php

class Test{
    public $data ="调用正常方法<br>";

    public function __invoke()
    {
        echo"调用__invoke()方法";
    }
}
$a= new test();
echo $a();
?>

在这里插入图片描述

__get

__get() 访问不存在的成员变量时调用的

实例如下

<?php

class Test {
    public $n=123;
    public function __get($name){
        echo '__get方法被调用,其中不存在变量'.$name.'<br>';
    }
}
$a = new Test();
echo $a->quan9i;//调用对象a中的变量quan9i,由于不存在quan9i这个变量,这时候就会调用__get魔术方法
?>

在这里插入图片描述

set

__set() :设置不存在的成员变量时调用的;
<?php

class xg{
    public $data = 100;
    protected $test=0;

    public function __set($name,$value){
        echo '__set 不存在成员变量 '.$name.'<br>';
        $this->test=$value;
    }

    public function show(){
        echo $this->test;
    }
}

$a = new xg();
$a->show(); //调用Get方法,这里就是输出test的值
echo '<br>';
$a->test= 777; // 给私有变量test赋值为777,但此时它是私有变量,就会调用__set,此时就会更改
$a->show();
echo '<br>';
$a->quan9i = 566;// 设置对象不存在的属性
$a->show();// 经过__set方法的设置值为566
?>

在这里插入图片描述

在这里插入图片描述

不理解的话可以进行调试,可以看见这里在调用私有变量test后走向了__set魔术方法,然后$name就是我们调用的变量,$value就是我们设置的值777
再看这个本来不存在的变量,它也是会调用这个__set魔术方法的,你可以在这里打断点,调试一下会发现此时这里设置了$name=quan9i,$value=566
在这里插入图片描述

__call()

__call :当调用对象中不存在的方法会自动调用该方法

示例如下

<?php

class Test{
    public $data ="调用正常方法<br>";
    public function __call($name,$value){
        echo "__call被调用,Test类中不存在方法".$name.'<br>';
        var_dump($value);
    }
    public function show(){
        echo $this->data;
    }
}
$a= new test();
$a->show(); //调用正常方法
echo"--------------------分隔符----------------<br>";
$a->quan9i('quan9i',123); //调用一个不存在的方法,此时就调用了__call魔术方法

?>

在这里插入图片描述

isset()

__isset() : 检测对象的某个属性是否存在时执行此函数。

实例如下

<?php

class test{
    public $name;
    private $age;

    public function __construct($name, $age){
        $this->name = $name;
        $this->age = $age;
    }

    // __isset():当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
    public function __isset($content){
        echo "当使用isset()函数,自动调用<br>";
        return isset($this->$content);
    }
}

$a = new test("quan9i", 19);
// public 成员
echo ($a->name),"<br>";
// private 成员
echo isset($a->name);
echo "-----------分隔符--------------<br>";
echo isset($a->age);
?>

可以发现私有属性时会调用issset魔术方法(调用protect的属性也会调用)
在这里插入图片描述

__unset()

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

实例如下

<?php

class test{
    public $name;
    private $age;

    public function __construct($name, $age){
        $this->name = $name;
        $this->age = $age;
    }

    
    public function __unset($content){
        echo "当使用unset()函数,自动调用<br>";
        echo "quan9i will be the best";
    }
}

$a = new test("quan9i", 19);
// public 成员
unset($a->name);
echo "<br>";
// private 成员
echo "-----------分隔符--------------<br>";
unset($a->age);
echo "<br>";
?>

在这里插入图片描述

可以发现当对一个公有属性进行unset的时候,会删除它,而私有变量则会调用unset函数

常用魔术函数汇总例子

<?php
class test{
 public $varr1="abc";
 public $varr2="123";
 public function echoP(){
  echo $this->varr1."<br>";
 }
 public function __construct(){
  echo "__construct<br>";
 }
 public function __destruct(){
  echo "__destruct<br>";
 }
 public function __toString(){
  return "__toString<br>";
 }
 public function __sleep(){
  echo "__sleep<br>";
  return array('varr1','varr2');
 }
 public function __wakeup(){
  echo "__wakeup<br>";
 }
}

$obj = new test();  //实例化对象,调用__construct()方法,输出__construct
$obj->echoP();   //调用echoP()方法,输出"abc"
echo $obj;    //obj对象被当做字符串输出,调用__toString()方法,输出__toString
$s =serialize($obj);  //obj对象被序列化,调用__sleep()方法,输出__sleep
echo $s.'<br>';//sleep返回的信息此时被输出
echo unserialize($s);  //$s首先会被反序列化,会调用__wake()方法,被反序列化出来的对象又被当做字符串,就会调用_toString()方法。后面这个是一个对象,因此会执行一次__destruct方法
// 结束又会调用__destruct()方法,输出__destruct
?>

在这里插入图片描述
参考文章
原理加实践掌握反序列化
https://spaceman-911.gitee.io/2021/06/30/PHP反序列化/

PCL 读取和保存点云 PCL (Point Cloud Library) 是一个用于处理 3D 点云数据的开源库。在处理点云数据时,常见的任务包括点云的读写和可视化。PCL 提供了强大的 IO 模块来读取和写入各种格式的点云文件,并且提供了可视化模块来对点云进行渲染和显示。点云的读写与显示是很多 3D 数据处理任务的基础步骤,通过这些步骤,可以对点云进行预处理、分析和操作。 阅读详情

相关推荐

从零开始:DJI-F450无人机硬件组装全流程解析

本文详细解析了DJI-F450无人机的硬件组装全流程,从开箱清点到焊接、机械组装、飞控系统搭建、电路整合及调试试飞。重点介绍了电调焊接、机臂安装、飞控校准等关键步骤的实用技巧和常见问题解决方案,帮助无人机爱好者从零开始完成专业级组装。

weixin_29210759的博客 622

Python反序列化漏洞及魔术方法详细全解(链构造、自动审计工具bandit)

魔术方法执行调用下面的代码,如果下面的代码可控的话,就可能存在反序列化漏洞。pickle.dump(obj, file) :将对象序列化后保存到文件。 pickle.load(file) :读取文件, 将文件中的序列化内容反序列化为对象。 pickle.dumps(obj) :将对象序列化成字符串格式的字节流。 pickle.loads(bytes_obj) :将字符串格式的字节流反序列化为对象。寻找LV6 -> 购买修改支付逻辑 -> 绕过admin限制需修改jwt值 -> 爆破jwt密匙 -> 重组jw

ranzi. 4795

UART全功能测试指南:环路/DMA/RS485/硬件流控实战

UART(通用异步收发器)是嵌入式系统中最基础的串行通信接口,其核心原理基于起始位、数据位、校验位与停止位的异步帧结构,依赖精确的波特率时钟同步与采样重建机制。在工业与物联网场景中,UART不仅需保障基本通信可靠性,更需支持DMA卸载、RS485半双工自动方向控制、RTS/CTS硬件流控等进阶能力,以提升实时性、抗干扰性与系统资源效率。典型应用涵盖调试日志输出、传感器数据采集、Modbus RTU总线通信及固件空中升级。本指南聚焦UART外设测试实践,覆盖环路自检、DMA吞吐验证、RS485时序对齐、硬件流

weixin_42599908的博客 133

php反序列化原理&常见的魔术方法

php反序列化原理及常用魔术方法总结

每天一小步,进步一大截 2118

基于淘宝商城用户购物行为数据分析系统

本文使用HIve+superset技术对阿里云天池提供的淘宝用户购物数据进行处理分析,得到有价值的信息并对平台提出有建设性意义的意见。

m0_51388399的博客 2821

STM32F103+LAN9252实战:从站代码迁移中的5个硬件坑与解决方案

本文分享了将EtherCAT从站代码从STM32F767迁移至STM32F103平台时,搭配LAN9252遇到的五个典型硬件问题及解决方案。核心挑战包括时钟源不匹配、FSMC时序配置、中断映射错误、片选资源不足以及Flash烧录异常。文章通过实战经验,强调了硬件差异对代码迁移的关键影响,并提供了具体的调试思路与配置方法。

p5l2m9n4o6q的博客 698

魔术方法总结

__construct(),类的构造函数 __destruct(),类的析构函数 __call(),在对象中调用一个不可访问方法时调用 __callStatic(),用静态方式中调用一个不可访问方法时调用 __get(),获得一个类的成员变量时调用 __set(),设置一个类的成员变量时调用 __isset(),当对不可访问属性调用isset()或empty()时调用 __unset(

梦里不知身是客 9999

思科路由器、交换机组网实验报告

通过思科模拟器搭建路由交换网络

ghj528的博客 1335

php反序列化常见魔术方法整理

整理php反序列化代码审计中常见的可用魔术方法

2302_79590880的博客 979

23 RAG 为什么答不准:召回、分块、排序的常见坑

RAG 答不准时,不要先怪模型。本文把常见失败拆成召回不到、召回不准、分块不完整、排序靠后、上下文污染和生成不忠实六类,并给出从 Top-K 检查到评估集的排查流程。

老于的笔记的专栏 247

【MTK平台】【wpa_supplicant】关于wpa_supplicant/p2p_supplicant.c文件的介绍

本文主要介绍external/wpa_supplicant_8/wpa_supplicant/p2p_supplicant.c 这个文件这个文件里面有个核心的方法就是。

专业开发者的博客,一个从事Android WiFi和蓝牙的工程师 725

PHP反序列化魔术方法

php反序列化漏洞魔术方法

qq_60463414的博客 2911

Arcgis加载在线地图(内涵各种在线地图)

这三个在线地图是最常用的在线地图,其他几个类型的在线地图请自行查看。,加载出在线图层说明连接成功,点击。1、首先打开Arcgis,找到。

爱吃雪糕的小布丁的博客 1万+

php反序列化魔术方法

_sleep()__wakeup()__invoke()__clone触发时机实例化对象对象引用完成或对象被销毁;反序列化之后序列化之前反序列化之前把对象当成字符串调用(使用echo或print)把对象当成函数调用当使用clone关键字拷贝完成一个对象功能提前清理不必要内容对象被序列化之前触发,返回需要被序列化储存的成员属性,删除不必要的属性参数返回值需要被序列化的成员属性__call()__get()__set()__isset()__unset()

2301_80913334的博客 2211

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

PHP之魔术方法

ctf常用的魔术方法

errorr0 7442

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

php反序列化 && 触发的魔术方法&& 原理 &&pop链构造 && ctfshow 练习

序列化和反序列化 是一种数据的传输方式 就如同 我们的主机的运输 我们为了方便会把主机的配件进行 拆分分类 (序列化) 运输到需要的人的那里他在组装起来(反序列) 这样的目的就是为了减少 空间的占用php的反序列化漏洞的成因就是因为 序列化之后的数据 在服务器被反序列化之前 数据被窃取伪造为 pop链 导致 反序列化执行了一些恶意的被篡改的数据。

2301_81155391的博客 1457

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

PHP反序列化&魔术方法

php反序列化

weixin_54882883的博客 1108

【反序列化漏洞02】PHP反序列化漏洞原理测试及魔术方法总结

1. 理解PHP反序列化漏洞的触发原理; 2. 了解PHP相关的魔术方法及调用情况。

Fighting_hawk的博客 3364

反序列化漏洞2-魔术方法介绍与演示

PHP魔术方法是面向对象编程中特殊的内置方法,以双下划线开头,在特定条件下自动触发执行。常用魔术方法包括__construct(对象创建时调用)、__destruct(对象销毁时调用)、__toString(对象作为字符串使用时调用)等。通过示例代码演示了这些方法的触发时机和执行效果,如对象实例化、序列化/反序列化等操作会自动调用对应魔术方法。这些方法需要开发者预先定义,为面向对象编程提供了更灵活的控制流程。

2401_89464052的博客 1110

Web攻防10_PHP反序列化_概念&魔术方法&POP链构造

PHP反序列化概念,为什么要反序列化,魔术方法与序列化的关系,反序列化漏洞原理与危害,漏洞利用POP链构造

学废了的阿串的博客 1100

php反序列化--session反序列化、phar反序列化、绕过wake_up魔术方法

摘要:本文分析了三种PHP反序列化漏洞:1. session反序列化漏洞,通过不同序列化引擎切换实现恶意代码执行;2. phar反序列化漏洞,利用phar文件的元数据反序列化特性触发攻击;3. __wakeup绕过漏洞(CVE-2016-7124),通过修改属性数量绕过保护机制。每种漏洞均配有实现原理、示例代码和攻击流程说明,涉及session引擎切换、phar文件操作和属性数量修改等技术要点,展示了PHP反序列化的常见攻击面和安全风险。

m0_75233418的博客 1135

PHP反序列化&魔术方法详细解析及实例&公私有属性对比

2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。2.将代码执行后可以看到下面的执行结果。1.实验代码部分如下。1.实验代码部分如下。1.实验代码部分如下。1.实验代码部分如下。1.实验代码部分如下。

ranzi. 2868

WEB攻防-PHP反序列化&POP链构造&魔术方法流程&漏洞触发条件&属性修改

是将对象转换为可存储/传输格式(字符串/字节流)的过程,则是将序列化后的数据还原为对象的过程。这种机制常见于:pickle模块序列化serialize():对象转换为数组或字符串等格式反序列化unserialize():将数组或字符串等格式转换成对象在 PHP 中,serialize()函数仅对对象属性进行序列化,而不处理对象方法。它把对象属性转为字符串存入序列化结果,方便对象在文件存储、网络传输或不同请求间传递。

weixin_45534587的博客 1572

php反序列化之魔术方法详解

由于User​类中定义了__toString()​方法,PHP将自动调用这个方法,并将返回的字符串输出。代码从$_GET['benben']​获取一个值,赋给$user_ser​,然后调用unserialize($user_ser)​。​__construct($username, $nickname, $password)​:构造函数,用于初始化对象的属性。echo $test()->benben 首先调用对象作为函数(执行__invoke()​方法),然后尝试访问属性。在实例化一个对象的时候自动触发。

2401_84893440的博客 731

php反序列化基础知识之魔术方法

php魔术方法

qq_42077227的博客 1356

php反序列化漏洞——魔术方法

一个预定义好的,在特定情况下自动触发的行为方法。

m0_73756016的博客 614
上一篇: 对SSRF的一次浅学习(CTF-hub)
下一篇: ctf刷题小结
quan9i
博客等级 码龄5年 468粉丝 129原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值