[HCTF 2018]WarmUp PHP审计+任意文件读取
打开页面看到一个滑稽表情,f12发现提示source.php
进入该页面,发现是代码审计,代码如下:
<?php highlight_file(__FILE__); //打印代码 class emmm //定义emmm类 { public static function checkFile(&$page) //将传入参数赋值给$page { $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //申明白名单 if (! isset($page) || !is_string($page)) { //若$page变量不存在或存在非法字符 echo "you can't see it"; return false; //返回false } if (in_array($page, $whitelist)) { $page在数组中 return true; //返回true } $_page = mb_substr( $page, 0, mb_strpos($page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } //截取$page中?前部分,若没有截取整个$page $_page = urldecode($page); //url解码 $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } echo "you can't see it"; return false; } } //-------------------------------------------------------------------------------------------------------------- if (! empty($_REQUEST['file']) && is_string($_REQUEST['file']) && emmm::checkFile($_REQUEST['file']) ) { include $_REQUEST['file']; exit; } else { echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />"; } ?>
- 非空
- 类型为字符串
- 能够通过checkFile()函数校验
看到其中$whitelist数组有两个值分别为source.php和hint.php,进入hint.php页面:
- 第一个if语句对变量进行检验,要求$page为字符串,否则返回false
- 第二个if语句判断$page是否存在于$whitelist数组中,存在则返回true
- 第三个if语句判断截取后的$page是否存在于$whitelist数组中,截取$page中'?'前部分,存在则返回true
- 第四if语句判断url解码并截取后的$page是否存在于$whitelist中,存在则返回true
若以上四个if语句均未返回值,则返回false
有三个if语句可以返回true,第二个语句直接判断$page,不可用
第三个语句截取'?'前部分,由于?被后部分被解析为get方式提交的参数,也不可利用
第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为'?',仍可通过第四个if语句校验。('?'两次编码值为'%253f'),构造url:
http://***:***/source.php?file=source.php%253f../ffffllllaaaagggg
无返回值,由于我们不知道ffffllllaaaagggg文件的具体位置,只能依次增加../,最终在
http://***:***/source.php?file=source.php%253f../../../../../ffffllllaaaagggg中成功回显flag
。