<?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\" />";
}
?>
先看主代码
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\" />";
}
request请求一个变量file 是否为空,是否为字符串,自定义函数 最后会包含这个file展现
checkfile()
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;
}
}
这里有个whitelist变量 看看hint.php  注意ffffllllaaaagggg 叠了4个buff
$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;
}
这里很明白 
 明显这两个php都不是我们想要的
ffffllllaaaagggg?

$_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;
分析得到payload
hint.php?/../../../../ffffllllaaaagggg
这里hint.php的作用比较巧妙 因为我们必须符合whitelist得到true得到include 而include有个致命错误
如果include的文件名中含有“/”,那么它会识别其为一个带目录的文件,只有最后一个“/”后的字符串对应的文件会被包含,而前面的字符串都只是在指定目录,默认从当前目录开始追溯(也就是source.php所在目录)。
那么source.php?其实是一个目录,经过后面几个的…/最终追溯到根目录,ffffllllaaaagggg应该是在根目录。确实目录source.php?这个目录根本不存在, 但是经过我的测试,无论你在其后再多加n个不存在的目录(如sjsvsu/,ajwjhzbd/等),只要再加n个…/补平,就能追溯到根目录。
对于./ , …/ ,/
“./”:代表目前所在的目录。 " . ./"代表上一层目录。 “/”:代表根目录。 路径理解

in_array() mb_substr()按字来分割字符, mb_strpos() 返回字符串在另一字符串中第一次出现的位置(大小写敏感)。
|