0x01 题目链接
https://buuoj.cn/challenges#[HCTF%202018]WarmUphttps://buuoj.cn/challenges#%5BHCTF%202018%5DWarmUp
0x02 知识点
isset($name):判断变量是否存在
is_string($name):判断变量是否为字符串
in_array($search,$array):判$search是否在$array数组里
mb_strops($name,start,length):截取$name字符串中的从start开始的length 长度
mb_strops(haystack,needle):返回索引;needle指要被搜索的字符串,haystack指要被检查的字符串
启动靶机,发现了一张滑稽图。如下
F12发现提示source.php,访问
0x03 代码审计
首先分析最后的if语句
可以看出,接收file里的参数来调用checkFile函数;并且当函数为true的时候执行include
接下来分析checkFile函数的内容
class emmm
{
public static function checkFile(&$page)
{
//白名单列表
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
//isset()判断变量是否存在
//is_string()判断变量是否是字符串
if (! isset($page) || !is_string($page)) {
echo "you can't see it A";
return false;
}
//检测传进来的值是否匹配白名单列表$whitelist
if (in_array($page, $whitelist)) {
return true;
}
//过滤问号的函数
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')//返回$page中第一个?的索引
);
//检测传进来的值是否匹配白名单列表$whitelist
if (in_array($_page, $whitelist)) {
return true;
}
//url对$page解码
$_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;
}
}
可分为两块分析
分析:
第一个$whitelist主要是把source.php和hint.php列入白名单列表里
第一个if判断变量是否存在或者是否为字符
第二个if判断变量是否在数组里
之后截取?之前的函数,返回索引,而$page有与?拼接,实际就是$_page=$page
- 在这里出现了一个hint.php,尝试访问 猜测ffffllllaaaagggg可能包含flag
$_page放入白名单里检测,是否存在;之后进行了一次解码,又进行了一次截取放入白名单里检测。
- 总体上checkFile一共查看三次是否在白名单中,截取两次?前的字符,进行一次url解码
整体利用的漏洞就是代码最后的include函数,利用文件包含漏洞
因此,最后的if条件语句是关键,即需要满足if(true && true && true),才会执行include函数,否则输出滑稽图。
emmm::checkFile($_REQUEST['file']满足true,需要执行emmm类中的checkFile函数,使得该函数最终返回true才可以
0x04 构造payload
要想让include函数执行ffffllllaaaagggg文件,就必须让checkFile返回true,让最后一个if语句都为真,才能执行include文件包含
因此构造的语句如下:
?file=hint.php?/ffffllllaaaagggg
分析:当执行到checkFile函数时,第1个if语句绕过,执行第2个if语句,放入白名单里验证,返回false,继续执行下一个语句, 在截取时,虽然在参数后面拼接了?,但mb_strops()函数会从左到右匹配最先匹配到的字符,因此截取后变成
?file=hint.php
带入第三个语句返回为true,跳出checkFile函数,执行include函数
此时接收的语句:
?file=hint.php?/ffffllllaaaagggg
在这里会发现,我们并不知道ffffllllaaaagggg存放的位置,那么我们可以通过找到它的相对位置来访问它,即构造../来完成
因此构造的语句如下:
?file=hint.php?../../../../../ffffllllaaaagggg
flag{45243bf2-55f4-4a06-8c7b-182a819f596e}
【提示:可能很多人会问,为什么?后要加/,其实这样是为了让程序误以为指文件夹,不加也可以】
- 萌新一枚,不对的地方欢迎大佬指点迷题!