题目环境:
发现除了表情包,再无其他 F12试试
发现source.php文件
访问这个文件,格式如下:
url/source.php
回显如下:
PHP代码审计:
代码语言:javascript复制<?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的类,该类有一个静态方法checkFile。checkFile方法接受一个字符串参数$page,这个参数可能代表一个文件名。
- 定义了一个$whitelist数组,这个数组里面存在两个元素是"source.php"和"hint.php"。
- checkFile方法首先检查$page是否存在且为字符串。如果不满足这些条件,它将输出"you can’t see it"并返回false。
- 然后,checkFile方法检查
whitelist的数组中。这个数组包含两个元素,分别是"source.php"和"hint.php"。如果
whitelist中,方法将返回true。
- 如果
whitelist中,那么checkFile方法将尝试通过以下步骤查找匹配的文件名:
- 首先,它将
page中的位置。这可能是为了检查是否存在一个查询字符串。
- 然后,它对$page进行url解码,再重复之前的步骤。
- 如果以上两种方式都未能找到匹配的文件名,那么方法将输出"you can’t see it"并返回false。
- 在类的定义之外,这段代码检查了一个名为
_REQUEST[‘file’])检查,那么它将包含(include)这个文件并退出。否则,它将显示最初页面的那个滑稽表情包图片。
- 总的来说,给了我们一个参数是file,我们给file参数传值就等于是给page参数传值,传的值需要提前用英文问号(?)连接起来,然后我们就可以找flag,怎么找flag是个问题,但是在代码里面还有一个名为hint.php的文件,不妨去看看,或许有咱们需要的信息。
查看hint.php内容
查看格式:
url/hint.php
回显结果:
这里说flag在ffffllllaaaagggg文件里面
有了目标就好办了,构造下payload:
url/source.php?file=hint.php?/ffffllllaaaagggg
竟然什么都没有显示 分析一下原因:
- 首先我们的payload要在source.php文件下进行,因为参数在这里面。
- flag在ffffllllaaaagggg里面,ffffllllaaaagggg又在hint.php里面,并且$whitelist数组里面也存在hint.php文件,所以说要先进到hint.php文件里面。
- 英文问号(?)连接后面的字符串也没有问题
- 到这里payload构造是没有问题的,那么问题就出在了找flag的位置不对!
- 我们这个payload是在hint.php文件里面找的,但是没有,返回上一级找找看?问题是也不知道flag具体在哪一级,那就构造多一些,溢出的部分没关系,这里只会显示最后一个目录。
- 了解一下:
1、“.”表示当前目录,也可以用“./”表示。
2、“…”表示上一级目录,也可以用“…/”表示。 3、“~” 代表用户自己的宿主目录。 4、“/”处于Linux文件系统树形结构的最顶端,我们称它为Linux文件系统的root,它是Linux文件系统的入口。
继续构造payload:
url/source.php?file=hint.php?../../../../../../ffffllllaaaagggg
这里就是说一直返回上一级查找,直到查找到flag为止,最终返回到/root根目录,因为ffffllllaaaagggg原本是在hint.php文件里面嘛,所以说要一直往上一级目录找它的原始位置,
…/倒不是一定是6个,看你的flag具体在那个上一级目录了