https://buuoj.cn/challenges#[WUSTCTF2020]%E6%9C%B4%E5%AE%9E%E6%97%A0%E5%8D%8E
之前摸鱼基本都是打派派下午不怎么上的去分,现在这赛季上钻了下赛季风暴点不怎么喜欢玩,所以花在题上的时间可能更多了。可喜可贺。
首先这道题一来遇到过很多次了,f12,robots.txt,没有就去用工具扫或者看请求头这些先,凭经验决定查看到提示的快慢和多少,那么我选择一来抓包看robots.txt,因为他提到了header,用burp看会比较直观方便。


这我f12的时候还没注意看到这个提示,那看到bot首先想到robots.txt,这不给提示也其实应该去看看。

假的flag.php,但是没提示也只能先去看看

果然是假flag,这里我忽视了请求头的东西,回去浪费了些时间,之后才注意到请求头里面有个/fl4g.php,burp打开因为本来就有文字编码问题,burp打开也略微抽象不好做,所以转到火狐上了。
网页可见:

要是嫌乱码不舒服可以在网页按下Alt,在网页上方的查看里面修复文字编码,按键是alt,然后弹出上方选项按v,然后按c,就变成了朱一蛋经典语录,在2022年看来令人感慨。
//level 1 if (isset($_GET['num'])){ $num = $_GET['num']; if(intval($num) < 2020 && intval($num + 1) > 2021){ echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>"; }else{ die("金钱解决不了穷人的本质问题"); } }else{ die("去非洲吧"); } //level 2 if (isset($_GET['md5'])){ $md5=$_GET['md5']; if ($md5==md5($md5)) echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>"; else die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲"); }else{ die("去非洲吧"); } //get flag if (isset($_GET['get_flag'])){ $get_flag = $_GET['get_flag']; if(!strstr($get_flag," ")){ $get_flag = str_ireplace("cat", "wctf2020", $get_flag); echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>"; system($get_flag); }else{ die("快到非洲了"); } }else{ die("去非洲吧"); } ?>
至此开始解题最后三关,经典get三问,首先是
level 1:这里关于intval函数大佬讲的比较详细就直接看大佬的就行了。
if(intval($num) < 2020 && intval($num + 1) > 2021)
https://blog.csdn.net/Lumos427/article/details/115768621
intval() 函数用于获取变量的整数值。 intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer数值。 intval() 不能用于 object,否则会产生 E_NOTICE错误并返回 1。 PHP 4, PHP 5, PHP 7 语法 int intval ( mixed $var [, int $base = 10 ] ) 参数说明: $var:要转换成 integer 的数量值。 $base:转化所使用的进制。 如果 base 是 0,通过检测 var 的格式来决定使用的进制 在第一层中要使用get传参一个num变量,然后他的整数值要小于2020,但是加上1之后又要大于2021,所以我们既要传入num,也要符合题目中的条件 根据intval()函数的使用方法,当函数中用字符串方式表示科学计数法时,函数的返回值是科学计数法前面的一个数,而对于科学计数法加数字则会返回科学计数法的数值 <?php $num='2e4'; echo(intval($num)); echo('<br>'); echo(intval($num+1)); ?> 这里输出值分别是:2,20001
所以我们只需要输入一个科学计数法的值比2020大的数科学计数法数就行了:
?num=1e10
level 2:
大伙都很熟悉的md5绕过:
if (isset($_GET['md5'])){ $md5=$_GET['md5']; if ($md5==md5($md5))
一般的md5绕过是传入0e开头的md5值,因为在弱比较时,弱比较中会截取一个字符串的数字,知道遇到字符截止,对于0e+数字的值只会截取e之前的0,所以这里即便是令传入的md5值等于$md5后还需要等于其自身进行md5的值,我们选取0e或者加密后仍为0e开头的数就行例如:0e215962017、以及这些纯字符串转化后为0e+数字的数:QNKCDZO、s878926199a

这里数组绕过是行不通的,我们都知道,md5绕过原理是因为:md5的参数必须是字符串,两边的md5传入数组会返回false,而false=false,所以弱比较成功,而这里因为数组传上去$md5=数组,而右边因为md5加密后变成了false,数组不等于false,所以比较失败,而这里做题还是最好转个编码看看,不然像我一样做到最后因为中间错了而回头找原因又会比较麻烦;
最后,level 3:
if (isset($_GET['get_flag'])){ $get_flag = $_GET['get_flag']; if(!strstr($get_flag," ")){ $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
strstr这个函数也不是第一次遇到了:strstr函数用来查找字符串的首次出现,这里也就是我们传入的参数不能包含空格,而这里也ban掉了cat,在上次我们在[安洵杯 2019]easy_web里就遇到过ban cat和其他输出类型的题,那时候我们学到了用\和sort 来代替这里其实也可以用tac,而空格绕过也是老生常谈的几个值:
${IFS} 注意不能写成 $IFS
以及 $IFS$9 和 %09
当然 <> 和 < 也是可以的

在ls查看了目录后也是发现了最后的文件

那么最终payload:
有很多,这里除了我自己的ca\t${IFS},more<,tac$IFS$9这些也都行

这里我犯了个错误,忘记加$了,大家自己做的时候一定要记得检查一下自己的payload。