攻防世界-web:warmup
阿新 • • 發佈:2021-10-14
題目描述
暫無
題目截圖
解題思路
訪問標題連結,發現圖片是個大大笑臉。直接看原始碼。
發現提示source.php,訪問source.php,得到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\" />"; } ?>
分析原始碼:
1)接收一個請求引數file。
2)判斷請求引數是否為空,是否為字串,然後利用checkFile函式進行檢測。
3)檢測通過後,對file引數進行檔案包含。
該題主要是分析checkFile函式。經過分析checkFile函式,發現邏輯如下:
1)設定了一個白名單陣列,陣列內容為source.php,hint.php
2)判斷file引數值是否存在,是否為字串。否則返回false
3)判斷file引數值是否在白名單裡,如果在直接返回true
4)利用mb_substr、mb_strpos函式是對目標字串進行擷取操作,將擷取結果賦值給$_page
引數。
5)判斷$_page
引數是否在白名單裡。如果存在直接返回true,否則繼續執行。
6)對file引數進行url解碼賦值給$_page
7)利用mb_substr、mb_strpos函式是對
$_page
引數進行擷取操作,將擷取結果賦值給$_page
引數。8)判斷
$_page
引數是否在白名單裡。如果在就返回true,否則返回false。
基本過程就是上面所述,此題目標就是利用目錄穿越進行檔案包含,獲取flag。核心關鍵是構造的目錄穿越字串要能經過checkFile函式的檢測。
通過file引數賦值hint.php,可以知道flag在ffffllllaaaagggg檔案裡,所以只要能夠包含到此檔案即可獲取flag。
構造包含思路如下:
1)file=/ffffllllaaaagggg
2)file=../../../../ffffllllaaaagggg
但是以上兩個構造都無法通過checkFile函式檢測,直接會返回false。
我們再次分析checkFile函式流程,發現只要$_page
我們發現checkFile函式裡進行了url解碼,我們知道瀏覽器到伺服器會進行一次url解碼,checkFile會再次進行一次url解碼,可以考慮二次url編碼。
我們還發現,字串擷取邏輯是在傳入的file引數字串後面拼接一個"?",然後去查詢"?"在file引數字串中第一次出現的位置,然後從0位置向"?"字元位置進行字串擷取。
例如:
file=hint.php?/../../../../123.php,則經過第一次擷取後的結果為hint.php,直接返回true。則會包含hint.php?/../../../../123.php,但是這個是無法構成目錄穿越的。
如果
file=hint.php%253f/../../../123.php,(其中%253f為"?"經過兩次url編碼的結果),則經過第一次擷取後返回結果為hint.php%3f/../../../123.php,不在白名單裡,則會進行url解碼後進行第二次擷取,url解碼結果為hint.php?/../../../123.php,對這個字串進行擷取後,擷取結果為hint.php,在白名單裡,返回true。則會包含hint.php%3f/../../../123.php,這個字串可以構成目錄穿越,伺服器會將hint.php%3f當作當前目錄下的一個資料夾。經過上級目錄穿越,最終將123.php進行包含。
所以最終payload為:
1)hint.php%253f/../../../../../ffffllllaaaagggg
2)source.php%253f/../../../../../ffffllllaaaagggg
得到flag
總結
1)理解目錄穿越原理
2)理解URL二次編碼後伺服器解析原理
3)能夠分析程式碼邏輯