<?php
highlight_file(__FILE__); //这个函数会将当前 PHP 文件的源代码以高亮方式显示出来,便于调试或展示源代码。
class emmm
{
public static function checkFile(&$page) //这个方法接受一个引用类型的参数 $page,用于检查请求的文件是否在允许的文件白名单中。
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //白名单数组,就是一个键值对
if (! isset($page) || !is_string($page)) { // isset检查变量是否为空
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { //in_array函数判断$page是否是数组中键值对的值(注意不是键) ,若存在,返回 true。
return true; //比如url为source.php?param=value,第一次是in_array查询整个url是否在白名单数组中
}
$_page = mb_substr( // mb_substr截取字符串函数
$page, //要截取的字符串
0, //起始位置
mb_strpos($page . '?', '?') // 长度, mb_strpos返回查找子串的开始位置,参数1:原串,参数2:子串 参数3:起始偏移量,$page . '?'表示拼接一个?在字符串末尾
);
if (in_array($_page, $whitelist)) { // 第二次查询,source.php是否在白名单数组中
return true;
}
$_page = urldecode($page); //这个函数对 URL 编码的字符串进行解码,处理例如 %20(空格)等特殊字符,以确保文件名能够正确识别。
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { // 最后一次先对url解码后查询source.php是否在白名单数组中
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\" />";
}
?>
此程序处理的逻辑就是比如输入url为
http://a9f88459-df26-41e1-ac32-aa8eb94ee3ae.node5.buuoj.cn:81/?file=hint.php
此时会通过全局数据$_REQUEST获取file后的值,然后通过if的三个判断
- 值是否为空
- 值是否为字符串
- 值满足在白名单数组中
当都满足的时候就会include hint.php这个路径的文件
此时我们利用两个漏洞进行方向查找flag
- 因为程序的判断逻辑中存在截取从=后第一个字符开始到第一个问好结束的字符串作为include的路径,所以我们在hint.php后加一个?来迎合这个条件
- 中间件服务器在解析url遇到?/会识别为/,比如将
>http://a9f88459-df26-41e1-ac32-aa8eb94ee3ae.node5.buuoj.cn:81/?file=hint.php?/../../../../ffffllllaaaagggg
识别为
http://a9f88459-df26-41e1-ac32-aa8eb94ee3ae.node5.buuoj.cn:81/?file=hint.php/../../../../ffffllllaaaagggg
从而让我们访问到上级目录,最后得到flag
标签:WarmUp,..,hint,mb,HCTF,file,php,page From: https://www.cnblogs.com/gzy-blogs/p/18402071