1. 程式人生 > 實用技巧 >php程式碼審計

php程式碼審計

也是BUUCTF上的一個題
應該是HCTF2018 warmup
進入環境後發現一個滑稽,直接看原始碼,發現有source.php,直接開啟不廢話,上程式碼

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];//白名單,就這些可以作為page傳進來
            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 . '?', '?')//擷取到?之前的page部分,再加上0位之前的那個?,就是兩個?之間的內容
            );
            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\" />";
    }  
?>

首先我們需要知道兩個函式, mb_strpos()和mb_substr()
mb_strpos(haystack,needle)
haystack:要被檢查的字串
needle:要搜尋的字串。
mb_substr(String $str,int $start,int $length)
返回str中從start位開始的length位長度的字串。
所以兩個?之間必須是白名單中的檔案,用file傳進去.
擷取page後就是source.php,被php當做檔案目錄,所以需要../來返回上一級,因為不知道幾層目錄,所以多返回幾個。四個../就可以了
payload最終是

http://656e4f28-de2a-4054-a9b7-6c7b5abbb247.node3.buuoj.cn/?file=source.php?../../../../../ffffllllaaaagggg

關於這個檔案包含漏洞可以參考檔案包含漏洞