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

目录

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的第二个参数传入。



 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch基础 - 3. torch.utils.tensorboard

目录 1. 简介 2. 基本步骤 3. 示例1 - 可视化单条曲线 4. 示例2 - 可视化多条曲线 5. 示例3 - 可视化网络结构 1. 简介 Tensorboard是Tensorflow的可视化工具&#xff0c;常用来可视化网络的损失函数&#xff0c;网络结构&#xff0c;图像等。后来将Tensorboard集成到了P…

【Linux】认识协议

&#x1f387;Linux&#xff1a; 博客主页&#xff1a;一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 看似不起波澜的日复一日&#xff0c;一定会在某一天让你看见坚持…

QT程序退出还占进程

问题情况 程序运行时的样子&#xff1a; 程序退出时的样子&#xff1a; 其跑到了后台进程里面&#xff1a; 程序退出了&#xff0c;但在任务管理器里查看&#xff0c;其从进程里面转移到后台进程了。 这种问题&#xff0c;怎么办&#xff0c;代码里&#xff0c;应该释放的也都…

【我的创作纪念日】恒川的创作一周年

机缘 大家好&#xff0c;我是热爱跑步的恒川&#xff0c;今天是个特殊的日子&#xff08;我的创作纪念日&#xff09;&#xff0c;在去年的今天&#xff0c;我发了第一篇博文。去年的时候&#xff0c;刚接触到CSDN&#xff0c;只想把他当作一个学习的工具&#xff0c;后来&…

浅析时间复杂度与空间复杂度

时间复杂度 何为时间复杂度 算法的时间复杂度&#xff0c;是一个用于度量一个算法的运算时间的一个描述&#xff0c;本质是一个函数&#xff0c;根据这个函数能在不用具体的测试数据来测试的情况下&#xff0c;粗略地估计算法的执行效率&#xff0c;换句话讲时间复杂度表示的…

UNIX高级编程--管道

管道 管道是 UNIX 系统 IPC 的最高老形式&#xff0c;所有的 UNIX 系统都提供此种通信机制。管道有以下两种局限性。 历史上&#xff0c;它们是半双工&#xff08;既数据只能在一个方向上流动&#xff09;。现在&#xff0c;某些系统提供全双工管道&#xff0c;但是为了最佳的…

代码随想录算法训练营第五十七天 | 647. 回文子串、516. 最长回文子序列、动态规划总结

647. 回文子串 动规五部曲 1、确定dp数组&#xff08;dp table&#xff09;以及下标的含义 在判断字符串S是否为回文时&#xff0c;如果知道 s[1]&#xff0c;s[2]&#xff0c;s[3] 这个子串是回文的&#xff0c;那么只需要比较 s[0]和s[4]这两个元素是否相同&#xff0c;如果…

Motion Planning学习笔记一:配置空间、图、图搜索、图遍历

学习高飞博士的路径规划课程所总结的学习笔记。 目录 1、配置空间&#xff08;Configuration Space, C-space&#xff09; 2、图&#xff08;Graphs&#xff09; 3、图搜索&#xff08;Graph Search Basis&#xff09; 3.1、总体框架 3.2、两种基本的图遍历算法 3.3、启…

【Python】【进阶篇】十七、Python爬虫实现实时翻译

目录十七、Python爬虫实现实时翻译17.1 JS代码slat与sign17.2 Python代码表示参数17.3 完整程序实现十七、Python爬虫实现实时翻译 YD翻译是以异步方式实现数据加载的&#xff0c;要实现数据抓取&#xff0c;其过程极其繁琐。 上一节《Python爬虫的浏览器实现抓包》&#xff…

【hello Linux】Linux开发工具

目录 1. vim&#xff1a;文本编辑器 1.1 各种模式的切换 补充&#xff1a;ctrl r命令 1.2 命令模式的操作 1.3 插入模式的操作 1.4 底行模式的操作 1.5 配置vim环境 1.6 配置亲属关系 2. gcc/g&#xff1a;编译器 2.1 预处理&#xff1a; 2.2 编译&#xff1a; 2.3 汇编&#x…

如何利用ChatGPT辅助优化刷题性能

根据土著刷题共建群里的一个小伙伴反馈&#xff0c;刷题会出现切题卡顿的情况&#xff0c;有时会出现滑不动的情况。 定位问题 为了定位切题卡顿问题的具体原因&#xff0c;测试了高低端手机&#x1f4f1;、切换2G、3G、4G低网络状态等各种影响切题的现实情况&#xff0c;经过借…

STM32F4_定时器精讲(TIM)

目录 1. 什么是定时器&#xff1f; 2. STM32定时器简介 2.1 高级控制定时器 TIM1和TIM8 2.1.1 TIM1和TIM8简介 2.1.2 时基单元 2.1.3 计数器模式 2.1.4 重复计数器 2.1.5 时钟选择 2.1.6 捕获/比较通道 2.1.7 输入捕获模式 2.1.8 其他功能 2.2 通用定时器 TIM2到TI…

Mysql 你还在一个字段一个索引吗

今天看到某系统的mysql在某时段存在thread_running线程数飙高触发告警&#xff0c;挤时间分析了该异常时间段的慢日志记录&#xff0c;并进行了sql优化 慢日志记录主要归为3个慢sql (编号1&#xff0c;2&#xff0c;3) 一、 1号sql原文 select * from feeds where topics_id &…

【MySQL数据库原理】MySQL Community安装与配置

目录 安装成功之后查看版本验证1、介绍、安装与配置数据库2、操作MySQL数据库3、MySQL数据库原理安装成功之后查看版本验证 SELECT VERSION();查看mysql版本号 1、介绍、安装与配置数据库 下载安装包:https://download.csdn.net/download/weixin_41194129/87672588 MySQL…

Visual studio C#中通过nuget安装sqlite库及C#中sliqte的用法

以前在Visual studio 的2017版中讲过如何使用sqlite&#xff0c;这里我们再次说说如何使用sqlite&#xff0c;以前Nuget使用还不是很流行很普及&#xff0c;大多数人不知道&#xff0c;但随着VS的升级&#xff0c;Nuget成为安装插件或者引用库文件标准的获取手段&#xff0c;所…

Qt Quick - TabBar

Qt Quick - TabBar使用总结一、概述二、调整选项卡三、Flickable标签三、定制化一、概述 TabBar其实就是选项卡&#xff0c;TabBar是由TabButton控件填充&#xff0c;TabBar可以与任何提供currentIndex属性的布局或容器控件一起使用&#xff0c;如StackLayout或SwipeView。Tab…

Vector - CAPL - CAN x 总线信息获取

在CAN&CANFD测试中&#xff0c;我们经常需要获取到CAN总线的负载、错误帧、过载帧、发送错误等等CAN总线上面的信息&#xff0c;这些信息如此重要&#xff0c;但是如果真的要写代码去实现也是相当不易的&#xff0c;那我们该如何去获取到的呢&#xff1f;下面我们就来一起看…

Object方法

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版&#xff0c;配图更多&#xff0c;CSDN博文图片需要手动上传&#xff0c;因此文章配图较少&#xff0c;看不懂的可以去菜鸡博客参考一下配图&#xff01; 系列文章目录 前端系列文章——传送门 JavaScript系列文章—…

柔性数组【结构体和动态内存的结合】

全文目录前言柔性数组的定义语法柔性数组的特点柔性数组的使用柔性数组的优势前言 很多人可能没有听过柔性数组这个概念&#xff0c;但是在C99中柔性数组是确实存在的。我个人感觉有点像动态内存和结构体的结合。 柔性数组的定义语法 结构中的最后一个元素允许是未知大小的数…

NumPy 秘籍中文第二版:三、掌握常用函数

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍许多常用函数&#xff1a; sqrt()&#xff0c;log()&#xff0c;arange()&#xff0c;astype()和sum()ceil()&#xff0c;modf()&…