记录一次CTF经典PHP反序列化
PHP反序列化
序列化通俗来讲就是将对象转化为可以存储、传输的字符串,反序列化就是把字符串再变回对象的过程。
例如:
<?php
class chybate {
var $test = '123456';
}
$cless1 = new chybate;
// 序列化
$cless1_ser = serialize($cless1);
echo $cless1_ser . '\n';
// 反序列化
$cless1_user = unserialize($cless1_ser);
print_r($cless1_user);
?>
O:7:"chybate":1:{s:4:"test";s:6:"123456";}
chybate Object
(
[test] => 123456
)
这里序列化结果中的O表示object对象,数字7表示对象类名长度为7,对象类名为"chybate"。数字1表示对象有一个变量,大括号里的s代表的是string类型,数字4表示变量名的长度,后面接着就是变量的值。
题目分析
题目给出了一个类xctf,其中包含一个变量flag和一个魔术函数__wakeup()。并且提示用code接收一个序列化后的字符串。

其中魔术函数__wakeup()是一个突破点,当使用unserialize()函数反序列化一个对象时,如果该对象类中定义了__wakeup()函数,则会自动调用该方法。
关于serialize()和unserialize()对魔术函数的处理:
serialize()函数序列化对象时,如果对象类中定义了__sleep()魔术函数,将会调用该方法来确定哪些属性需要被序列化。如果对象类没有定义__sleep()函数,将会序列化对象的所有属性。
unserialize() 函数反序列化对象时,如果对象中定义了__wakeup()魔术函数,将会在对象反序列化后调用该方法__wakeup()函数用于初始化反序列化后的对象状态,通常用于重新建立对象和其相关资源之间的联系。
那么如何利用__wakeup()魔术函数呢?
__wakeup()的一个绕过点:一个对象被序列化后,如果它的属性被修改,那么它在反序列化的过程中则不会执行__wakeup()函数。
解题
解题思路就是,修改序列化后中的属性值来绕过__wakeup()。
<?php
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
$c = new xctf;
print(serialize($c));
?>
xctf序列化字符串:
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
当被反序列化的字符串中对应的对象的属性个数发生变化时,会导致反序列化失败而同时使得__wakeup()函数失效。
构造payload /?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";},这里将变量的个数改为2,属性个数发生变化,这样__wakeup()在初始化反序列化后的对象状态时就会失效,从而阻止了exit()函数的执行。

get flag!
总结
PHP反序列化漏洞原理就是,在反序列化该对象时触发魔术方法从而执行命令或代码。
PHP序列化需注意以下几点:
序列化只序列属性,不序列方法。
能控制的只有类的属性,攻击就是寻找合适能被控制的属性,利用作用域本身存在的方法,基于属性发起攻击。
若有错误,欢迎指正!o( ̄▽ ̄)ブ
记录一次CTF经典PHP反序列化的更多相关文章
- ctf经典好题复习
WEB200-2 这是swpu-ctf的一道题. <?php if(isset($_GET['user'])){ $login = @unserialize(base64_decode($_GE ...
- 从一道ctf看php反序列化漏洞的应用场景
目录 0x00 first 前几天joomla爆出个反序列化漏洞,原因是因为对序列化后的字符进行过滤,导致用户可控字符溢出,从而控制序列化内容,配合对象注入导致RCE.刚好今天刷CTF题时遇到了一个类 ...
- 【CTF WEB】反序列化
反序列化 漏洞代码 <?php error_reporting(0); if(empty($_GET['code'])) die(show_source(__FILE__)); class ex ...
- CTF中PHP反序列化和命令注入的一次简单利用
代码来自第六届防灾科技学院网络安全技能大赛,侵删. 目标 获取Linux服务器根目录下的flag 代码 /*home.php*/ class home{ private $method; privat ...
- php反序列化(昨天的补充)
魔术方法 在对PHP反序列化进行利用时,经常需要通过反序列化中的魔术方法,检查方法里是否有敏感操作来进行利用. 常见方法: 创建对象时触发:__construct() 对象被销毁时触发:__destr ...
- ISCTF2022WP
ISCTF2022改名叫套CTF吧(bushi),博主菜鸡一个,套题太多,挑一些题写下wp,勿喷. MISC 可爱的emoji 下载下来是个加密压缩包,根据hint掩码爆破密码 得到密码:KEYI ...
- 「2014-2-23」Note on Preliminary Introduction to Distributed System
今天读了几篇分布式相关的内容,记录一下.非经典论文,非系统化阅读,非严谨思考和总结.主要的着眼点在于分布式存储:好处是,跨越单台物理机器的计算和存储能力的限制,防止单点故障(single point ...
- Google Analytics:为链接点击设定事件追踪的方法
在 Google Analytics 中,可以使用 Event Tracking 功能跟踪自定义的事件.但是,如果你要跟踪的是一个链接点击,那么单纯这样写则很有可能导致漏掉许多事件: <a hr ...
- CSharpGL(44)用ShadowMapping方式画物体的影子
CSharpGL(44)用ShadowMapping方式画物体的影子 在(前文)已经实现了渲染到纹理(Render To Texture)的功能,在此基础上,本文记录画物体的影子的方式之一——shad ...
- Mybatis基本用法--上
Mybatis基本用法--上 本文只是为自己查漏补缺.全面的请看官方文档,支持中英文 原理参考:http://blog.csdn.net/luanlouis/article/details/40422 ...
随机推荐
- 关于SQLServer数据库的READ_COMMITTED_SNAPSHOT隔离级别
默认情况下,SQL Server的事务隔离级别是READ COMMITED.刚开始我理解这个模式就是读已经提交的,那也就是说并发一个事务去更新,一个事务查询同一条数据应该是像Mysql.Oracle不 ...
- Redis实战之session共享
当线上集群时候,会出现session共享问题. 虽然Tomcat提供了session copy的功能,但是缺点比较明显: 1:当Tomcat多的时候,session需要大量同步到多台集群上,占用内网宽 ...
- el-submenu 设定title不显示
原因为 插槽中有空格 slot=" title" 修改为 slot="title"即可
- 总结篇4:redis 核心数据存储结构及核心业务模型实现应用场景
总结篇4:redis 核心数据存储结构及核心业务模型实现应用场景 redis 和memcached 有什么区别?为什么在高并发下,单线程的redis 比多线程的效率高? mc 可以缓存图片和视频,re ...
- C++创建与调用dll动态链接库(MinGW64 Dev-C++)
本文使用的是dev-c++,如果涉及到VC++中不一样的操作,也会适当进行区分. 项目一:创建DLL 1.创建一个DLL类型的项目,当前命名为dlltest,并选择合适的路径进行保存. 2.在生成的 ...
- Rounding
前言 以前写过一篇关于 Rouding 的 decimal, double, float, 但有点杂乱, 这篇做一个整理. Why need rouding? 除法会诞生小数. 甚至会诞生无限小数 ( ...
- 【VMware VCF】使用 VCF Import Tool 将现有 vSphere 环境转换为管理域。
VMware Cloud Foundation 5.2 发布并引入了一个新的功能,借助 VCF Import Tool 工具可以将现有 vSphere 环境直接转换(Convert)为管理工作负载域或 ...
- C++ STL set/multiset容器
set/multiset容器 简介 Set的特性是,所有元素都会根据元素的值自动被排序.Set不允许两个元素有相同的值. Set的迭代器iterator是一种const_iterator,不能通过迭代 ...
- Listener——监听器
Listener
- GPT-SoVITS语音合成模型实践
1.概述 GPT-SoVITS是一款开源的语音合成模型,结合了深度学习和声学技术,能够实现高质量的语音生成.其独特之处在于支持使用参考音频进行零样本语音合成,即使没有直接的训练数据,模型仍能生成相似风 ...