题目如下:
![](https://i-blog.csdnimg.cn/blog_migrate/2905b919a2df8501929d6de1381f9811.png)
注意这里需要对php有一定的了解,不了解的话,可以网上查下__wakeup函数是干嘛的,我查到的结果如下:
若在对象的魔法函数中存在的__wakeup方法,那么之后再调用 unserilize() 方法进行反序列化之前则会先调用__wakeup方法,但是序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
注意到这里最后一行是?code=,这里提示我们需要构造code参数来绕过__wakeup函数。我们可以简单设置一个code=xxx来进行验证,得到结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/fb8b2609fcb355b58409f9afcb3cd6f5.png)
可以看到参数回显出来了,然后接下来就是如何构造一个字符串来绕过__wakeup函数了,我们可以先写这样一串php代码来得到序列化字符串:
<?php
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
print(serialize(new xctf()));
?>
运行后,我们可以得到结果:O:4:"xctf":1:{s:4:"flag";s:3:"111";},然后将对象属性个数调大即可,这里我们调成2:O:4:"xctf":1:{s:4:"flag";s:3:"111";}。构造如下请求,即可得到答案
![](https://i-blog.csdnimg.cn/blog_migrate/06f570fdae7c2e5e07528f7cc18eb298.png)
总结:这里考察了php语言中反序列化需要优先执行__wakeup这一知识点,已经如何构造序列化字符串可以绕过该函数;与该问题相关的历史漏洞为CVE-2016-7124。