5.HCTF-2018-WarmUp
题目地址:
解题过程:
网页上打开就只有一个大滑稽,网页名是Document,所以是文件包含?提交file参数,一直是:you can’t see it。
题目标签是代码审计,我也没看到代码啊……
查看源代码看到source.php内心毫无波澜,后来查找才知道要访问它……(菜\1)*
好,访问source.php我终于看到代码了:
1 |
|
到目前为止还没有看到过这么长的代码审计(菜\2)*
先看与file有关的代码:
1 | if (! empty($_REQUEST['file']) |
file要求是字符串且不为空,用emmm中的checkFile调用。file中的值传递给了page。checkFile中四个if语句,每个都有return。
第一个if:
1 | $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; |
先设置了一个白名单数组,准许访问source.php和hint.php,hint.php中存放了flag的位置。第一个if语句要求page存在且为字符串,不符合则return false,退出程序。
第二个if:
1 | if (in_array($page, $whitelist)) { |
in_array()函数在page中查找是否有与whitelist中键值对应的字符串。有则return true,退出程序。
第三个if:
1 | $_page = mb_substr( |
mb_strpos为page拼接了一个?,并返回其**第一次出现的位置**。mb_substr从开头显示字符至?所在的位置,处理后page再次进行比对。
那不是只能读source.php了?……$_page啊,那没事了……(菜\3)*
第四个if:
1 | $_page = urldecode($page); |
先对page进行了url编码,再进行读取和对比的操作……
注意:PHP中$_GET、$_POST、$_REQUEST这类函数在提取参数值时会URL解码一次
这位师傅上面写第三个if不能利用,但逻辑理通之后我感觉也是可以利用的。
?一次编码为%3F,二次编码为%253F,那么第三个if的利用需要if的一次编码。
第三个if利用:
payload:?file=source.php%3F../../../../../../ffffllllaaaagggg(服务器找不到source.php%3F,就视为一个文件夹)
成功出flag
第四个if利用:
自然,需要二次编码的’?‘。
payload:?file=source.php%253F../../../../../../ffffllllaaaagggg
总算做了点实在事……
知识点总结:
- 这位师傅不错呦
- in_array() 函数搜索数组中是否存在指定的值
- mb_substr() 函数返回字符串的一部分, substr() 函数只针对英文字符,如果要分割的中文文字则需要使用 mb_substr()。
- mb_strpos() 查找字符串在另一个字符串中首次出现的位置,mb_strpos 按字处理,strpos 按字符处理。
- 关于路径符号的一些知识。
- 服务器找不到XXXXXXX,就视为一个文件夹。