HCTF warm up
进入题目发现一个滑稽,按F12发现有线索访问一下
<?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\" />";
}
?>
发现了网页源码,代码审计一下
!empty($_REQUEST[‘file’])要我们的file变量不为空我们先进行分析这段代码 首先看80行第一个要求
is_string($_REQUEST[‘file’])要求我们传进来的值是字符串类型
emmm::checkFile($_REQUEST[‘file’])这里将我们的的值传到emmm类里面的checkFile函数
这三个值通过&&逻辑与运算符连接也就是要求这块函数的返回值要全为真才能执行if里面的文件包含的代码 否则就执行else里面的图片代码
先来熟悉几个函数
//mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置
// mb_strpos (haystack ,needle )
// haystack:要被检查的字符串。
// needle:要搜索的字符串
//mb_substr() 函数返回字符串的一部分。
//str 必需。从该 string 中提取子字符串。
//start 必需。规定在字符串的何处开始。
//ength 可选。规定要返回的字符串长度。默认是直到字符串的结尾。
又发现了一个hint.php文件,访问后的确有一个hint,提示我们flag在ffffllllaaaagggg文件中:
emmm类分析
从代码中发现新的页面hint访问获得flag文件名
可以看到函数代码中有四个if语句第一个if语句对变量进行检验,要求
p
a
g
e
为
字
符
串
,
否
则
返
回
f
a
l
s
e
第
二
个
i
f
语
句
判
断
page为字符串,否则返回false 第二个if语句判断
page为字符串,否则返回false第二个if语句判断page是否存在于
w
h
i
t
e
l
i
s
t
数
组
中
,
存
在
则
返
回
t
r
u
e
第
三
个
i
f
语
句
判
断
截
取
后
的
whitelist数组中,存在则返回true 第三个if语句判断截取后的
whitelist数组中,存在则返回true第三个if语句判断截取后的page是否存在于
w
h
i
t
e
l
i
s
t
数
组
中
,
截
取
whitelist数组中,截取
whitelist数组中,截取page中’?‘前部分,存在则返回true
第四个if语句判断url解码并截取后的
p
a
g
e
是
否
存
在
于
page是否存在于
page是否存在于whitelist中,存在则返回true
若以上四个if语句均未返回值,则返回false有三个if语句可以返回true,第二个语句直接判断$page,不可用
第三个语句截取’?‘前部分,由于?被后部分被解析为get方式提交的参数,也不可利用
第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为’?’,仍可通过第四个if语句校验。
只要这四个if语句有一个为true即可包含file,
关键点在_page 经过截断后返回true.
(’?‘两次编码值为’%253f’),绕过前面的白名单过滤后构造url:
http://:/source.php?file=source.php%253f…/ffffllllaaaagggg
无返回值,由于我们不知道ffffllllaaaagggg文件的具体位置,只能依次增加…/,最终在http://:/source.php?file=source.php%253f…/…/…/…/…/ffffllllaaaagggg中成功回显flag
注:两次url编码,第一次是url传入到服务器时解码了一次,第二次是page传给_page解码了一次