反序列化漏洞及PHP魔法函数

news2024/12/28 22:37:26

目录

1、漏洞原理

2、序列化(以PHP语言为例)

3、反序列化

4、PHP魔法函数

(1)__wakeup()

(2)__destruct()

(3)__construct()

(4)__toString()

(5)__get()

(6)__call()


1、漏洞原理

PHP反序列化漏洞也叫PHP对象注入,形成的原因是程序未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行、文件操作、执行数据库操作等参数不可控。反序列化攻击在Java、Python等面向对象语言中均存在。序列化是广泛存在于PHP、Java等编程语言中的一种将有结构的对象/数组转化为无结构的字符串并储存信息的一种技术。

2、序列化(以PHP语言为例)

PHP类都含有的特定元素:类属性、类常量、类方法。

序列化就是将一个类压缩成一个字符串的方法。

eg:

<?php
class userInfo
{
 private $passwd='123456';
 protected $sex = 'male'; //定义了三个属性
 public $name ='Myon';
 public function modifyPasswd($passwd)
{

$this->passwd = $passwd; //将函数传进来的值传给passwd
 }
public function getPasswd()
{
echo $this->$passwd; //输出passwd
 }
}
$Myon = new userInfo(); //创建 userInfo对象实例
$Myon->modifyPasswd('123abc'); //调用modifyPasswd函数并将123abc值传进去
$data = serialize($Myon); //序列化
echo $data;
?>

输出结果:

O:8:"userInfo":3{s:16:"userInfopasswd";s:6:"123abc";s:6:"*sex";s:4:"male";s:4:"name";s:4:"Myon";}

对序列化后的字符串进行解读:

大括号外表示“Object”对象名称是“userInfo”,长度为8,这个对象有3个属性。

(特别注意:在CTF中常有一个对 _wakeup() 函数的绕过,当序列化字符串中表示对象属性个数的值大于实际属性个数时,就会跳过wakeup方法的执行。)

在前面的文章中有对CTF题PHP反序列化及绕过实例的讲解,可以参考

http://t.csdn.cn/Mffji

http://t.csdn.cn/wbtkK

大括号内表示这些属性的具体信息及它们的值

根据属性的权限不同,在序列化中的表示方法也不同

从代码中可以看出,三个属性的权限分别是private,protected和public

(1)private权限是私有权限,只能在本类内使用,子类不能继承。
(2)protected权限是私有权限,即只能在类内部使用,子类可以继承这个变量。
(3)public权限就是正常的变量权限,一般声明的变量权限均为public。

标红的是private,前面加上了本类名称;

标蓝的是protected,前面加上了星号;

标绿的是public,没有任何前缀。

一个类经过序列化之后,存储在字符串的信息只有类名称和类内属性键值对,序列化字符串中没有将类方法一并序列化。

3、反序列化

反序列化与序列化是相对应的,就是将含有类信息的序列化过的字符串“解压缩”还原成类。

反序列化的类想要使用原先的类方必须依托于域,脱离了域的反序列化的类是无法调用序列化之前的类方法的。

<?php
class userInfo
{
 private $passwd='123456';
 protected $sex = 'male'; //定义了三个属性
 public $name ='Myon';
 public function modifyPasswd($passwd)
{

$this->passwd = $passwd; //将函数传进来的值传给passwd
 }
public function getPasswd()
{
echo $this->$passwd; //输出passwd
 }
}
$Myon = new userInfo(); //创建 userInfo对象实例
$Myon->modifyPasswd('123abc'); //调用modifyPasswd函数并将123abc值传进去
$data = serialize($Myon); //序列化

$new_Myon = unserialize($data); //反序列化数据
$new_Myon->getPasswd();
?>

理论上这里类方法应该被成功执行,但是...

不过有一点可以确定,如果我们单独将序列化后的字符串作为输入,在一个新的域下执行代码片段,肯定是会报错的。

<?php
$data = "O:8:\"userInfo\":3{s:16:\"userInfopasswd\";s:6:\"123abc\";s:6:\"*sex\";s:4:\"male\";s:4:\"name\";s:4:\"Myon\";}"
$new_Myon =unserialize($data);//反序列化数据
$new_Myon->getPasswd();
?>

4、PHP魔法函数

(1)__wakeup()

在PHP中如果需要进行反序列化,会先检查类中是否存在_wakeup()函数,如果存在,则会先调用此类方法,预先准备对象需要的资源。

<?php
class example
{
    public $color = 'black';//定义color属性
public function __wakeup()
    {
        $this->color = 'white';//将white赋值给color
    }
    public function printColor()
    { 
        echo $this->color . PHP_EOL; //输出color
    }
}
$my = new example; //实例化对象
$data = serialize($my); //进行序列化
$new_my = unserialize($data); //反序列化
$new_my->printColor(); //调用printColor()函数
?>

 可以看到类属性color已经被__wakeup()函数自动调用并修改了

这种函数被称为PHP魔法函数,它在一定条件下不需要被调用而可以自动调用

(2)__destruct()

在对象的所有引用都被删除或类被销毁时自动调用

<?php
class example
{
    public $color ='black'; //定义color属性
    public function __destruct()
    {
        echo "__destruct()". PHP_EOL; //打印__destruct()
    }
}
echo "initializing...". PHP_EOL; //打印 initializing...
$my = new example; //创建对象实例
echo "serializing..." . PHP_EOL; //打印 serializing... 
$data = serialize($my); // 序列化
?>

 可以看到在序列化类的时候,__destruct()函数自动执行了 。

(3)__construct()

此函数会在创建一个类的实例时自动调用

<?php
class example
{
    public $color='black'; //定义color属性
    public function __construct()
    {
        echo"____construct()". PHP_EOL; //打印__construct()
    }
}
echo "initializing...". PHP_EOL; //打印initializing...
$my = new example; //创建对象实例
echo "serializing...". PHP_EOL; //打印 serializing... 
$data = serialize($my); //序列化
?>

可以看到在序列化之前,实例化时__construct()函数就被调用了。

(4)__toString()

此函数会在类被当作字符串时调用

<?php
class example
{
    public $color='black'; //定义color属性
    public function __toString()
    {
        return"_toString()". PHP_EOL;//打印__toString()
    }
}
echo "initializing...". PHP_EOL; //打印initializing...
$my = new example; //创建对象实例
echo "echo...". PHP_EOL; //打印echo...
echo $my;//输出$my
echo "serializing...". PHP_EOL; // 打印 serializing... 
$data = serialize($my); //序列化
?>

 可以看到当实例化对象被当作字符串使用时,__toString()函数自动调用。

其他触发此函数的情况:

反序列化对象与字符串连接时。
反序列化对象参与格式化字符串时。
反序列化对象与字符串进行==比较时(PHP进行==比较时会转换参数类型)。
反序列化对象参与格式化SQL语句,绑定参数时。
反序列化对象在经过PHP字符串函数,如strlen()、addslashes()时。
在in_array()方法中,第一个参数是反序列化对象,第二个参数的数组中有toString返回的字符串时,toString会被调用。
反序列化的对象作为class_exists()的参数时。

(5)__get()

在读取不可访问的属性值时自动调用

<?php
class example
{
    private $color ='black'; // 定义私有属性 color
    public function __get($color)
    {
        return"__get()". PHP_EOL; //打印__get()
    }
}
$my = new example; //创建对象实例
echo $my->color; //输出 color 属性
?>

因为试图访问私有变量color导致__get()函数自动调用 

(6)__call()

调用未定义的方法时调用

<?php
class example
{
    private $color='black'; //定义私有属性 color
    public function __call($function,$parameters)
    {
        echo $function."('.Sparameters.')".PHP_EOL;//打印两个参数
        return"__call()". PHP_EOL;
    }
}
$my = new example; //创建对象实例
echo $my->notExistFunction("patameters"); //调用未定义方法?>
?>

可以看到__call()函数被调用

也就是说你想让调用方法未定义,那么这个方法名就会作为 __call的第一个参数传入,因此不存在方法的参数会被装进数组中作为 __call的第二个参数传入。



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/429869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Arduino UNO驱动micro SD卡读写模块

目录一、简介二、使用前准备三、测试方法四、实验现象一、简介 Micro SD卡模块TF卡读写卡器板载电平转换电路&#xff0c;即接口电平可为5V或3.3V&#xff0c;支持支持Micro SD卡(≤2G)、Micro SDHC高速卡(≤32G)。供电电源为4.5V~5.5V&#xff0c;板载3.3V稳压电路&#xff0…

甘特图控件DHTMLX Gantt入门使用教程【引入】:dhtmlxGantt与ASP.NET Core(上)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求&#xff0c;具备完善的甘特图图表库&#xff0c;功能强大&#xff0c;价格便宜&#xff0c;提供丰富而灵活的JavaScript API接口&#xff0c;与各种服务器端技术&am…

minio 部署、迁移、使用

一、minio 部署 1、单节点部署 部署IP&#xff1a;192.168.206.10 1.1、下载minio的二进制文件 wget https://dl.min.io/server/minio/release/linux-amd64/minio 1.2、规划磁盘 minio 数据目录一定不能和 跟/ 在一个磁盘上&#xff0c;要单独挂载&#xff0c;比如规划将m…

一文看懂SpringBoot操纵数据库

1.前言 很多同学进入公司就开始参与项目开发&#xff0c;大多数情况是对某个项目进行维护或者需求迭代&#xff0c;能够从0到1参与到项目中的机会很少&#xff0c;因此并没有多少机会了解某些技术的运行机制。换句话说&#xff0c;有的面试官在面试的时候就会探讨深层的技术问题…

【产品设计】那些被迫妥协的产品设计背后的技术原因

刚入门的产品经理经常会听到前辈们说应该懂点技术&#xff0c;却不明白为什么。本文作者分享了几个被迫妥协的产品设计的例子&#xff0c;希望能让不是技术出身的产品经理了解到“产品经理应该懂点技术”在产品设计中有什么指导意义&#xff0c;一起来看一下吧。 刚入门的产品经…

学习C++:C++进阶(六)如何在C++代码中调用python类,实例化python中类的对象,如何将conda中的深度学习环境导入C++项目中

目录 1.应用场景 2.场景&#xff1a;利用maskrcnn深度学习网络实现语义分割 3.CMake配置python解释器 4.C中实现实例化python中的类的对象并调用类内方法 4.1 初始化python环境 4.2 实例化python类的对象 1.应用场景 我们在视觉SLAM以及目标检测和识别中&#xff0c;经常…

AMD GPU安装运行stable diffusion

本文操作环境为Windows10/11AMD AI绘画是一种利用人工智能技术进行绘画的方法。它可以通过机器学习算法来学习艺术家的风格&#xff0c;并生成类似于艺术家的作品。最近&#xff0c;AI绘画技术得到了很大的发展&#xff0c;许多公司和研究机构都在进行相关的研究和开发。例如&…

华为电脑录屏功能在哪?这样做,您可以快速找到

案例&#xff1a;如何在华为电脑上找到电脑录屏功能&#xff1f; “听说电脑有录屏功能&#xff0c;但我在我的华为电脑上找了很久&#xff0c;都没有找到。难道华为电脑没有录屏功能吗&#xff1f;有没有小伙伴可以告诉我华为电脑录屏功能在哪&#xff1f;孩子已经快绝望了&a…

第六章 法律体系

目录 第一节 法律体系与法律部门的概念 一、法律体系的概念 &#xff08;一&#xff09;法律体系的含义和特征 &#xff08;二&#xff09;法律体系与相关概念的区别&#xff08;法律体系与国家&#xff0c;现行有关&#xff09; &#xff08;三&#xff09;法律体系的形成和…

本地存储、自定义事件、全局事件总线、消息订阅与发布【Vue】

Vue 1.1 浏览器的本地存储 存储内容大小一般支持5MB左右&#xff08;不同浏览器可能还不一样&#xff09;浏览器通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制相关API: &#xff08;1&#xff09;xxxxStorage.setItem(key, value); 该方法接受一…

CT前瞻(三):Adobe系列XD软件绘制简单的原型图与交互设计

文章目录&#x1f4cb;前言&#x1f3af;关于原型图绘制&#x1f3af;XD绘制原型图与交互设计&#x1f3af;关于XD软件其他功能&#x1f4dd;最后&#x1f4cb;前言 Adobe XD是一个协作式易用平台&#xff0c;可帮助团队为网站、移动应用程序、语音界面、游戏等创建设计。还可…

每个 Android 开发者都应该知道的有用资源

每个 Android 开发者都应该知道的有用资源 在本文中&#xff0c;我将提到 7 个资源&#xff0c;这些资源对于 Android 开发人员来说非常有益。我亲自使用过其中的每一个几次。他们无数次派上用场。确保您不要忘记为这些资源添加书签/收藏&#xff0c;以便您可以在需要使用它们时…

医院体检PEIS系统源码

一、医院体检系统概述 1. 医院体检系统概述 目前&#xff0c;大多数的体检还停留在手工操作上&#xff0c;如单位体检时手工书写体检人员信息、医生手工书写体检结果、检验报告打印后进行手工粘贴等&#xff0c;这样造成极大的工作量&#xff0c;效率低下&#xff0c;而且极易…

【三十天精通Vue 3】第九天 Vue 3 路由详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录引言一、Vue 3 路由概述1.1 路由的简介1.2 路由的分类1.3 路由的语…

暗讽友商 昆仑万维大模型预告刺激股价

搭上AI风口&#xff0c;上市公司昆仑万维年内股价大涨217.56%&#xff0c;一时名声大噪。火了以后&#xff0c;昆仑万维的野心越来越大&#xff0c;喊出“All in AGI&#xff08;通用人工智能&#xff09;与AIGC”的豪言壮语。 在近期预告旗下大模型“天工”邀测的公告中&…

STL :双端队列容器 Deque

Deque #include<deque> using namesace std; 双端队列容器 &#xff1a;双向开口的连续线性空间&#xff1b; 擅长尾部和头部添加或删除元素&#xff1a;常数阶&#xff1b; 存储元素并不能保证所有元素都存储到连续的内存空间中&#xff1b; deque 是动态的以分段…

TiDB实战篇-TiDB配置

简介 熟系TiDB的配置相关。 TiDB的大体参数 系统配置对应的是TiDB-Server,PD和TiKV和TiDB-Server基本在集群配置里面配置。 系统配置 系统变量 | PingCAP 文档中心 集群配置 PD 配置文件描述 | PingCAP 文档中心 配置的存储位置 系统配置存储在TiKV中的&#xff0c;集…

如何免费恢复电脑上误删除的视频

虽然我们现在可以在单个硬盘驱动器上存储无数大型视频文件是件好事&#xff0c;但这也意味着单个用户错误或硬件/软件故障可能会立即抹去数小时的记忆&#xff0c;而没有任何明显的方法可以恢复它们。在本文中&#xff0c;我们提供了一个快速的分步视频恢复指南&#xff0c;以帮…

【音视频】利用ffmpeg实现:音视频的提取,rtmp推流等

目录 可列出电脑的设备 音频桌面视频&#xff0c;存mp4 录声音 推流到服务器 音频桌面视频&#xff0c;推流到服务器 音频笔记本摄像头&#xff0c;推流到服务器 参考资料 可列出电脑的设备 输入下面的语句即可列出电脑的设备 ffmpeg -list_devices true -f dshow -i dum…

(链表)相交链表(双指针法)

文章目录前言&#xff1a;问题描述&#xff1a;问题解析&#xff1a;代码实现&#xff1a;总结&#xff1a;前言&#xff1a; 此篇是关于链表的经典练习题。 问题描述&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节…