题目背景
这个题目主要是考 CVE-2016-7124 这个漏洞
关于漏洞的介绍可以看这篇博客:https://www.cnblogs.com/zy-king-karl/p/11436872.html
出现的原因就是本来 PHP 在将一个字符串反序列化成为一个类的时候,会先检查 __wakeup
函数的存在,如果存在那么就会先执行这个函数。(这一类函数又叫做魔术函数,魔术函数是一种在触发了特殊PHP 事件的时候会优先执行)但是由于 PHP 存在这个漏洞,使得 PHP 的 __wakeup
函数,会被直接绕过。
绕过方法:
只要被反序列化的字符串中表示对象属性个数的值大于真实的属性的个数时,这个函数就会被绕过。
题解
我们回来这个题目,从提示中我们可以看出后台代码定义了一个类
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
然后又有一个 ?code=
不难联想到这是Url中 GET 请求参数的一部分。之后我们来猜想这个后台的工作原理:先读取客户端发送过来的 GET 请求参数,然后将这个参数的字符串反序列化成一个对象,然后执行后续的代码。但是由于在反序列化的时候 __wakeup()
函数执行,调用了 exit() 函数,结果后面的代码没法执行了。所以我们要做的,就是利用上面说的那个漏洞,绕过 __wakeup()
地执行。(想想看后面的代码肯定就是输出 flag 了)
由于只要被反序列化的字符串中表示对象属性个数的值大于真实的属性的个数时,这个函数就会被绕过。所以我们构造如下参数:
O:4:"xctf":5:{S:4:"flag";S:3:"111";} //序列化字符串中不包含类方法
然后用 GET 方法将这个作为 code 的参数传到服务器上,就可以绕过,成功输出flag。