本来想着倒头睡觉的,但是万分愧疚,觉得得再做个题才行,于是点开了这道warm up
先谈谈感受吧,(自己还是懂的太少了),这种用到CVE的题,需要理解的知识点不是单一的,而且要有很缜密的思维,可以说是需要很多的经验积累的。加油吧!
看题,打开是个滑稽标签
f12看源码,提示有source.php,代码:
<?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\" />";
}
?> flag not here, and flag in ffffllllaaaagggg
得安排时间学学代码审计的姿势了
提示代码在ffffllllaaaagggg中
看题,想要访问传入的file需要满足几个条件:
前两个条件没有问题,但第三个没有思路,仔细看了两边代码,去查了下in_array()和mb_substr()
mb_substr ( string $str
, int $start
[, int $length
= NULL [, string $encoding
= mb_internal_encoding() ]] ) : string
根据字符数执行一个多字节安全的 substr() 操作。 位置是从 str
的开始位置进行计数。 第一个字符的位置是 0。第二个字符的位置是 1,以此类推。
in_array ( mixed $needle
, array $haystack
[, bool $strict
= FALSE
] ) : bool
在array中查询needle,有则返回true。如果没有设置 strict
,那么比较时只会比较值,不会比较类型。
补充:in_array()函数的弱类型比较利用:
<?php
// Example array
$array = array(
'egg' => true,
'cheese' => false,
'hair' => 765,
'goblins' => null,
'ogres' => 'no ogres allowed in this array'
);
// Loose checking -- return values are in comments
// First three make sense, last four do not
in_array(null, $array); // true
in_array(false, $array); // true
in_array(765, $array); // true
in_array(763, $array); // true
in_array('egg', $array); // true
in_array('hhh', $array); // true
in_array(array(), $array); // true
// Strict checking
in_array(null, $array, true); // true
in_array(false, $array, true); // true
in_array(765, $array, true); // true
in_array(763, $array, true); // false
in_array('egg', $array, true); // false
in_array('hhh', $array, true); // false
in_array(array(), $array, true); // false
?>
回到题目中,想尝试下in_array()弱类型的漏洞,但无法构造有效的payload,只好放弃,另寻他路。
搜索到一位前辈的wp,记录了解题思路和要点(感谢),也提到了这是CVE-2018-12613
下面是我在读过wp之后的结题思路:
bypass重点在checkFile函数,看函数的代码
这里有个前置的知识点:
传入的参数(比如这里的hint.php)后边加上(可以是两次urlencode)问号和目录,那么服务器会把这个参数当作目录处理
两次urlencode的原因是,服务器接收到数据包后会自动decode一次
既然有了访问目录的法子,就来想下怎么绕过检测函数呢?
这里刚好有问号,而检测函数里会截取file参数里问号之前的内容和白名单比对,所以两次urlencode的问号(一次被服务器decode,一次等函数中的decode)刚好符合情况。
函数中:
payload :
?file=hint.php%253f/../../../../../../ffffllllaaaagggg
(最后一次比对时返回true)?file=hint.php?/../../../../../../ffffllllaaaagggg
(第一次比对时返回true)自己的基础真的还差很多,肝!
原文:https://www.cnblogs.com/R3col/p/12452513.html