题目直接给出来代码
这题考几个点:
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