buuctf - HCTF2018 WarmUp思路
阿新 • • 發佈:2020-09-16
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}