进入题目环境,只有一个表情:
ctrl + u 查看源代码:
源代码提示我们访问 /source.php。访问结果如下:
我们进行代码审计,发现解题的关键点 include &_REQUEST['file']。但是题目使用了白名单进行了过滤。我们发现白名单中有 hint.php,尝试访问:
通过访问 hint.php 可知,flag在ffffllllaaaagggg中,读取ffffllllaaaagggg为我们现在的主要目的。
我们继续审计过滤函数 checkFIle():
首先利用 in_array函数检查 $page 是否在 白名单中,以此返回 true or false。
然后利用 mb_substr() 函数 与 mb_strops()函数来截取 $page 字符串中 第一个字符到第一个 "?" 的位置中间的字符串,并检查所截取字符串是否在白名单中,以此返回 true or false。
mb_substr() 函数:
第一个参数 $page : 所要截取的目标字符串。
第二个参数 0 :开始截取的初始位置。
第三个参数 :结束截取的位置。
mb_strpos() 函数:
第一个参数:目标查询字符串。
第二个参数:要查找的字符。
第三个参数:规定开始搜索的位置。若未提供此参数,将从字符串头开始搜索。
最终函数返回要查找字符第一次出现的位置。
根据过滤函数的过滤特性,我们可以构造payload:
?file=source.php?/ffffllllaaaagggg
为什么要使用 ?/ 的格式。
如果include的文件名中含有“/”,那么它会识别其为一个带目录的文件,只有最后一个“/”后的字符串对应的文件会被包含,而前面的字符串都只是在指定目录。
故我们可以利用 ../ 来回到上一级目录中,通过不断回溯找到 ffffllllaaaagggg 文件并读取。
构造 payload 并提交,页面如下: