[HCTF 2018]WarmUp
知识点
- 文件包含类题目
- 首先要去想,如何才能执行下面的include语句,要满足if语句中的3个条件,第三个条件主要就是分析出
mb_substr
函数截取之后
过程
滑稽~,直接查看源代码
提示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\" />";
}
?>
根据code找到页面中有个hint.php
首先,我们传入一个get型的参数file,在if语句中判断并满足三个条件都为True
时,然后才会去包含
传入的参数
- 传参不为空
- 传参是字符串
- 传参要经过emmm类中的checkfile函数
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,接着我们传进来的参数要经过三个if语句
-
第一个if,不能让他返回
false
,所以需要传入的参数需要设置并且是字符串 -
第二个if,如果返回True的话,只能去包含指定的文件:source.php和hint.php,而我们是要想办法去包含刚刚hint.php中提示我们的ffffllllaaaagggg文件
-
第三个if,
mb_substr
函数实际上是substr截取字符的中文版,可以截取中文字符,可以从它设置的参数中发现,它从(0)起始位置截取$page
,截取的长度通过函数mb_strpos(返回第二个参数字符在第一个参数中第一次出现的位置)
来返回,整个这段意思就是截取?之前的字符串,比如hint.php?file=/etc/passwd
,$_page的值会变成hint.php
接着再进行白名单校验,返回True,然后就直接在最后去包含文件了
payload
index.php?file=hint.php?../../../../ffffllllaaaagggg
执行之后,执行到checkfile函数中的三个if时,会变成hint.php
,显然hint.php满足白名单校验,所以返回True,三个if语句这时候都为真,就直接执行include语句,就能看到flag