題目直接給出來代碼

這題考幾個點:
1.$_REQUEST的變量覆蓋
2.編碼繞過
3.PHP數組特性
4.正則繞過
5.file_get_contents函數
首先一步步把題目分析一遍
if($_REQUEST){ foreach ($_REQUEST as $key => $value) { if(preg_match('/[a-zA-Z]/i', $value)) die('waf..'); } }
上述代碼把$_GET,$_POST,$_COOKIE傳進來的值進行了正則匹配,如果包含了A-Z和a-z的字母就返回waf
這里的$_REQUEST有一個特性,就是當GET和POST都存在同一個變量名的時候,只獲取POST中的值,所以可以通過這個特性來繞過正則的匹配

當POST中也有個變量的時候,abc就會輸出,否則就輸出waf
接着往下分析
if($_SERVER){ if(preg_match('/yulige|flag|nctf/i', $_SERVER['QUERY_STRING'])) die('waf..'); }
關於$_SERVER['QUERY_STRING']獲取的值,就是get中變量名和內容
詳細資料可以參考https://blog.csdn.net/fjb2080/article/details/80548431
這個繞過思路沒什么好說的,URL編碼就行

下面的代碼
if(isset($_GET['yulige'])){ if(!(substr($_GET['yulige'], 32) === md5($_GET['yulige']))){ //日爆md5!!!!!! die('waf..'); }else{ if(preg_match('/nctfisfun$/', $_GET['nctf']) && $_GET['nctf'] !== 'nctfisfun'){ $getflag = file_get_contents($_GET['flag']); } if(isset($getflag) && $getflag === 'ccc_liubi'){ include 'flag.php'; echo $flag; }else die('waf..'); } }
if(!(substr($_GET['yulige'], 32) === md5($_GET['yulige'])))這里的繞過思路很簡單,傳進去是個數組的時候,值就為空,自然就相等了

其實這里出題人沙雕了,本應該是出
preg_match('/^nctfisfun$/', $_GET['nctf']) && $_GET['nctf'] !== 'nctfisfun'
所以這個正則繞過也很簡單只要nctf是以nctfisfun結尾,且不等於nctfisfun就行了,我這里用1nctfisfun繞過的
最后就是file_get_contents函數了,從參數里面看就是直接傳入一個遠程的txt就行了,txt的內容為ccc_liubi
官方給出的writeup是利用data://協議
鏈接:http://www.php.net/manual/zh/wrappers.data.php

最終就得到flag
