[HCTF 2018]WarmUp 小白体验
Wubba lubba dub dub
buu上最简单的web题,攻防世界web进阶区也有。
https://buuoj.cn/challenges#[HCTF%202018]WarmUp
本文记录本小白啃这道题的体验。是实况,做到哪写到哪。
进题,感觉小白在被鄙视:
按F12开启控制台,看元素里有个注释写着source.php
直接访问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 和类外的if语句,类中的内容在那个if语句里被调用。
if语句做的事挺明白的,没学过php也能看懂,满足以下条件执行include:
- file参数存在
- file参数是string
- file参数传如checkFile返回为true
前两个条件只要传了flie就能满足,看第三个条件在干什么:
checkFile($page):
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
上来有个白名单,if语句表明,如果参数page是空的或者不是字符串,那就会返回false。
白名单里给了hint.php了,先访问下看看:
页面变化:
大概意思是说flag在ffffllllaaaagggg这个文件里?结合刚开始看的那个if语句和白名单可以猜想如果能绕过checkFile里的白名单和if语句,那就能包含ffffllllaaaagggg这个文件拿到flag。
通读一下checkFile,这个函数里有4个if语句,在这四个if语句之间还有两次子串截取和一次urlDecode。捋了一下大概做这样的事:
- 先确定参数存在并且是字符串
- 检查参数是否在白名单
- 如果不在白名单,对参数截取子串,截到 “?” 位置
- 再次判断是否在白名单
- 防止是url编码没转换,转码再截取 “?”
- 最后一次判断白名单
如此我的目的就是,构造一个有ffffllllaaaagggg的字符串,并且在ffffllllaaaagggg之前有白名单里的内容和一个问号,比如:
hint.php?ffffllllaaaagggg
就用这个payload测试一下,结果:
底部没有显示任何内容,没有在那几个if里输出 you cant see it也没在外层输出滑稽。所以这个checkFile绕过是可以的。但也没有输出什么跟ffffllllaaaagggg相关的东西,显然,路径是有问题的。而且ffffllllaaaagggg肯定跟当前页面不在一个目录里,不然就可以直接访问了。目测不能是扫描目录,应该就是向前找,也就是用../来向前找。
当前传入include的字符串是:”hint.php?ffffllllaaaagggg”
前面的hint.php和问号可以看做是一个目录,也就是在hint.php?后面加上一个”/”使其作为目录解析,然后用”./”来表示当前路径,再加上”../”向前访问。
最终在第四层输出了正确结果。