进入靶场后发现只有一个滑稽表情,习惯性的右键查看源码,发现提示source.php
直接访问source.php,接下来进行代码审计
代码审计:
首先最外层if条件判断函数$_REQUEST['file']是否为空并且要满足is_string($_REQUEST['file']中file的值为字符串,之后传入过emmm::类中的checkFile方法,当返回为true时才运行指定文件“file”。
接下来分析emmm类,创建一个类,类里面设置public static function访问权限为公有,重写checkFile方法,参数是&$page,在方法中又定义了一个$whitelist变量,变量里面定义了一个列表"source"=>"source.php","hint"=>"hint.php",前面的source.php我们已经查看了,接下来我们去访问“hint.php”得到“flag not here,and flag in ffffllllaaaagggg”内容。可以猜测ffffllllaaaagggg是文件名,我们需要的flag就可能在这里面。第一个if判断使用isset()变量是否是字符串,第二个if判断利用in_array()检测传进来的值是否有$whitelist里面的内容,若有则返回true。然后又设了一个$_page变量,使用mb_substr()来提取被mb_strpos()返回$page.?里面的?号出现的位置之前的字符串,直接把问号过滤掉了。第三个if判断和第二次if判断相似,然后使用urldecode()来吧$page进行url解码给$_page,之后又过滤掉问号。第四个if又判断传进来的值是否有$whitelist里面的内容
一共经历三次检测,二次过滤,一次解码,参数在传入checkFile方法第一次白名单验证一次问号过滤后就是hint.php在进行一次白名单验证,若返回为真则得到flag。这样就可以构造url为index.php?file=hint.php?../../../../../ffffllllaaaagggg(尝试几次才找到flag)