分类:[技术分析]
标签:CTF SHOW
刷题
新手
阅读时长:约 [5] 分钟
引言(前言)
日常CTF 做题记录,日常做题分享,希望能积累更多的知识!!!
攻防世界 warmup
1.1 题目及分析
<?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\" />";
}
?>
- 题目分析
- 此题如果直接输入链接,将只会显示一张图片,但是通过查看源代码可以发现有一个提示
source.php
- 此外,经过目录爆破也能发现存在的文件路径:
index.php,source.php,hint.php
- 此题最关键的就是读懂代码后,学会绕过
checkFile函数,同时又要能将包含flag文件的地址给到include
1.2 思路
checkFile
主要是查找输入的字符中是否有?
$page . '?'
在$page
的末尾拼接一个?
符号。
- 若
$page
中原本没有?
(例如$page = "source.php"
),则拼接后为"source.php?"
; - 若
$page
中已有?
(例如$page = "source.php?xxx"
),则拼接后为"source.php?xxx?"
。
mb_strpos(..., '?')
用mb_strpos
查找字符串中第一个?
的位置(返回索引值)。
- 若
$page
无?
:例如$page = "source.php"
,拼接后为"source.php?"
,第一个?
在字符串末尾,位置等于$page
的长度(如source.php
长度为 10,则位置为 10); - 若
$page
有?
:例如$page = "source.php?xxx"
,拼接后为"source.php?xxx?"
,第一个?
在原$page
中source.php
的末尾(位置为 10)。
mb_substr($page, 0, ...)
用mb_substr
截取$page
的子串:
- 起始位置为
0
(从字符串开头开始); - 截取长度为上一步得到的
?
的位置。
- 同时如果截取的字符在白名单中,就可以绕过
checkFile
- 如 file=source.php?xxxx
- 但这题的核心在于怎么通过
include
- 当你输入file=hint.php时可以看到
flag not here, and flag in ffffllllaaaagggg
关键知识点
- 在 PHP 中,
include
处理包含/
的文件名时,会将整个字符串解析为完整路径(目录 + 文件名),其中最后一个/
后面的部分是目标文件名,前面的部分是目录层级(相对路径或绝对路径)。这里注意:仅当服务器开启allow_url_include
、存在路径容错解析、或编码绕过等条件时,?
后面的/../../../../
才可能被当作有效路径解析,从而绕过校验并包含目标文件。
- 因此,我们可以通过相对路径绕过source.php
playload:source.php?/../../../../ffffllllaaaagggg
- 这里有多少个
../
需要自己去试
1.3 结果
大家多多尝试一下有没有更好的方法吧!
互动环节
- 各位大佬们是否有更优的实现方式?欢迎分享代码
- 评论区聊聊吧~