[HCTF 2018]WarmUp
题目开头是一个滑稽表情 没有任何提示。所以先看下源代码。
给了个提示 source.php
进去后发现了源码。
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return 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;
}
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\" />";
}
?>
拿到源码 就开始分析源码了。
解题的关键就是这个include 文件包含。根据代码分析可以得出。
empty 是判断file是否为空
is_string是判断file是否为字符串类型
checkFile是类中得一个函数。
所以只要empty返回true,is_string返回true,checkFile返回true,就可以进行文件包含。
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
//给了一个数组。hint.php里提示了flag在ffffllllaaaagggg里
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}//isset是判断page是否为空。由于传进来的page为一个字符串且不为空,所以返回false.
if (in_array($page, $whitelist)) {
return true;
}/*in_array的意思是判断page里是否包含白名单里的内容 例如source.php hint.php。
就是page=source.php或者hint.php才行.所以最后返回了false。*/
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);/*这里mb_substr 是个截断,返回0到mb_strpos之间的内容,而mb_strpos 则是查找第一次出现的位置,所以基本可以理解为获取page 两个?之间的字符串,也就是获取file两个?之间的字符串,放到url中就是http://ip/?file=ddd?中的file=ddd*/
if (in_array($_page, $whitelist)) {
return true;
}
/*经过上面的截断代码,page=source.php 所以返回true ,文件可以得到包含,结束,下面的代码就不用在执行了*/
$_page = urldecode($page);
$_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\" />";
}
?>
return 的含义是返回一个东西,但是还有一个含义就是执行的时候代表着函数结束,在其下面的代码不在继续执行。
所以开始构造playload
index.php?file=source.php?../../../../../ffffllllaaaagggg
../的意思是返回上一目录。
为什么这样用呢,就是因为不知道flag在当前目录下还是在根目录下。