phpMyAdmin是一套開源的、基于Web的MySQL資料庫管理工具,其index.php中存在一處檔案包含邏輯,通過二次編碼即可繞過檢查,造成遠程檔案包含漏洞,
phpmyadmin登錄模式設定
我們通過身份驗證模式的要求,可以有兩種配置方案,一種是HTTP和cookie身份驗證模式,在這兩種模式下,用戶必須先在一個登錄視窗里輸入MySQL資料庫的有效用戶名和密碼,才能使用phpMyAdmin程式,這種做法有兩個明顯的好處:首先,因為MySQL資料庫的密碼沒有出現在config.inc.php檔案里,所以身份驗證程序更加安全;其次,允許以不同的用戶身份登錄對自己的資料庫進行管理,這兩種身份驗證模式尤其適合資料庫中多個用戶賬號的情況,
第二種方案是,config身份驗證模式,這種模式下,密碼以明文形式保存在config.inc.php檔案里,只需要把MySQL用戶名和密碼直接寫入到config.inc.php檔案即可,這樣,在登錄phpMyAdmin時就不會提示輸入用戶名和密碼了,而只直接用config.inc.php檔案里寫入的用戶登錄,如果只是在一個本地測驗系統上使用phpMyAdmin,可以使用這種模式,
漏洞分析
攻擊者必須擁有后臺權限,phpMyAdmin4.8.0 - 4.8.1版本均受漏洞影響,
漏洞的入口在index.php 54-63行:
$target_blacklist = array (
'import.php', 'export.php'
);
// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target'])
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
}
include $_REQUEST['target']; , 這里的target可以直接傳值輸入,我們可以傳入一個本地檔案路徑去讓其包含,就會造成LFI漏洞,
要想成功包含target,需要滿足五個條件:
- 非空
- 必須為字串
- 不能是index開頭
- 不能是黑名單中的檔案名(import.php、export.php)
- 通過函式
Core::checkPageValidity的校驗
進入函式 libraries/classes/Core.php
public static function checkPageValidity(&$page, array $whitelist = [])
{
if (empty($whitelist)) {
$whitelist = self::$goto_whitelist;
}
if (! isset($page) || !is_string($page)) {
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
); //按?分割字串,取前半部分
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
); //按?分割字串,取前半部分
if (in_array($_page, $whitelist)) {
return true;
}
return false;
}
要想使該函式回傳true,包含的檔案必須包含在白名單$whitelist中,
下面是白名單$whitelist的內容:
\libraries\classes\Core.php

第一個回傳true的地方,$page引數必須要在白名單中
第二個回傳ture的地方需要通過 mb_substr()和mb_strpos()`函式處理,
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
); //按?分割字串,取前半部分
if (in_array($_page, $whitelist)) {
return true;
}
mb_substr() 截取字串:

mb_strpos()查找字串在另一字串中的首次出現位置

即判斷?后面的字串是否滿足白名單.
第三處回傳true的地方:
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
); //按?分割字串,取前半部分
if (in_array($_page, $whitelist)) {
return true;
}
此處判斷,先將$page進行urldecode解碼,然后再進行?的分割,取值進行判斷,只要解碼后分割出來的值在$whitelist中即可滿足條件,而在$target 里問號被二次編碼為%253f, db_sql.php%253f也會被認為是一個目錄,可以用../跨越,成功實作包含,因此命名規范里面沒有將%放進去也是該漏洞能在windows下成功利用的一個關鍵點,(windows檔案名不能包含? /\ *等符號,)
這樣我們可以將?進行二次編碼,如果傳入target=db_sql.php%253f,在倒數第二個判斷中進行白名單校驗時,為db_sql.php%3f,不滿足,最后一個判斷的urldecode后,進行校驗時為db_sql.php,符合條件,然后即可成功包含檔案,
漏洞復現

可以利用本地檔案包含漏洞的特點:
- 上傳sql檔案,然后進行包含;
- 開啟webshell日志功能,查詢webshell陳述句后,包含日志;
- 將webshell寫入欄位中,如果資料庫在本地,可以直接通過查詢資料庫檔案位置:select @@datadir;然后得到資料庫檔案存放路徑,而欄位內容則在資料庫名/表名.frm中
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/33729.html
標籤:其他
