为了非法读取客户端文件,实现假的 MySQL 服务器。分析 MySQL 协议数据包需要了解 Wireshark 和 MySQL 官方文档。使用 Wireshark 捕捉客户端(192.168.239.129)和服务端(192.168.1.3)之间的 mysql 通信数据包。客户端开启 mysql,注意设置允许外来连接。打开 Wireshark,选择捕获 Vmware 相关网卡,...
Mysql LOAD DATA读取客户端任意文件
MySQL 客户端和服务端通过对话形式进行通信,客户端发送操作请求,服务端根据请求响应。若操作需两步完成,客户端发送第一个请求后不会存储,而是丢弃。第二步根据服务端响应继续,服务端可欺骗客户端进行某些操作。
通常通信中,客户端发送 MySQL 语句,服务器端查询后返回结果。但 MySQL 的 LOAD DATA INFILE 语法可读取文件内容并插入表中。该命令可读取服务端或客户端文件,取决于 LOCAL modifier 是否给定。
读取服务端文件内容的 SQL 语句为:
读取客户端文件内容的 SQL 语句为:
与读取服务端文件内容相比,读取客户端文件内容多了 local 关键字。
此过程可用两人对话表示。正常情况下流程无误,但客户端第二次发送文件完全取决于服务端。若服务端不正常,可能发生以下对话:
这样服务端非法获取了 /etc/passwd 文件内容。接下来进行实验,构建恶意服务端欺骗客户端。编写伪造恶意 MySQL 服务器的 POC 需了解 MySQL 协议,因此分析 MySQL 协议数据包。
为了非法读取客户端文件,实现假的 MySQL 服务器。分析 MySQL 协议数据包需要了解 Wireshark 和 MySQL 官方文档。
使用 Wireshark 捕捉客户端(192.168.239.129)和服务端(192.168.1.3)之间的 mysql 通信数据包。
客户端开启 mysql,注意设置允许外来连接。
打开 Wireshark,选择捕获 Vmware 相关网卡,过滤 MySQL 协议,连接虚拟机。
注意:不要使用 mysql 8.0.12 版本,否则数据包显示不完整,用户名也显示不了,可能是因为加密更严格。
MySQL 协议支持通过 TLS 加密和身份验证。分析捕获的数据包,判断其使用了 TLS 加密。
运行连接命令时捕获到的数据包:
分析数据包结构,与官方文档对照学习。
当客户端连接服务端时,服务端发送初始握手数据包。根据版本和配置选项,服务端发送不同的初始数据包。从 MySQL 3.21.0 版本开始,发送 Protocol::HandshakeV10。
以 MySQL 5.7.26 版本为例,发送 Protocol::HandShakeV10。查看文档定义数据包结构。
分析 Wireshark 中服务端发送的初始数据包,包括协议版本、服务端 MySQL 版本、进程 ID,与文档对应。
Protocol::HandShakeV10 定义数据包的 payload 部分,头部定义在 MySQL Packets。
分析数据包头部,包括 payload_length、sequence_id、payload 等。
客户端支持 SSL 时,发送 Protocol::SSLRequest 数据包,使服务端建立 SSL 层。否则发送 Protocol::HandshakeResponse。
根据分析,客户端发送 Protocol::HandshakeResponse41。
分析客户端 flag、max_packet_size、character_set 等字段。
客户端支持 LOAD DATA LOCAL,这是读取客户端本地文件的根本。
分析 Ok_Packet 和 COM_QUERY 数据包。
选择 security 数据库时,捕获的数据包较多。
执行命令将 /etc/passwd 文件内容写入 users 表时,捕获到的数据包包括 COM_QUERY。
分析数据包结构,找到构造恶意 MySQL 服务器的重点。
根据数据包结构书写 payload,包括伪造数据包首部和 payload 部分。
构造 POC,实现连接过程,修改第二个数据包的响应内容。
从网上抄来的 POC,连接建立过程中发送的数据没有包含数据包首部,发送 payload 时包含首部。
在服务器运行脚本,在客户端连接,接收 /etc/passwd 文件内容。
若要读取 /flag,构造数据包首部和 payload 部分,包括包类型和文件名。
首部包括长度字段和序列号,payload 部分包含包类型和文件名(转换为十六进制)。2024-08-11