Mastering MySQL Reverse Reading: A Comprehensive Guide to Reverse File Access Techniques

Statement

The article was first published on the FreeBuf Community [here](https://www.freebuf.com/articles/web/348248.html) and discusses the topic of MySQL reverse reading.

Introduction

Reverse reading files with MySQL seems quite interesting. After some exploration, I have summarized it as follows in the hope that it might provide some help to those learning about reverse file reading in MySQL.

Prerequisite Knowledge

In MySQL, there exists this statement:

LOAD DATA INFILE

Its role is to read the contents of a file and insert them into the specified table, specifically categorized as follows:

1. load data infile "C:/Windows/win.ini" into table test FIELDS TERMINATED BY '\n';
2. load data local infile "C:/Windows/win.ini" into table test FIELDS TERMINATED BY '\n';

The first statement reads the server local win.ini file and then inserts it into the test table. The second statement reads the client win.ini file and then inserts it into the test table. This is the key to MySQL’s implementation of reverse file reading.

Environment Setup

Environment preparation

Client: Win11 192.168.134.1 Service: Kali 192.168.134.132

An additional precondition is that it needs

The server must enable Load data infile

You can check if Load data infile is enabled with the following command,

As Kali comes with MySQL service, we only need to enable it; the command is as follows:

service mysql start

MySQL reverse reading >

Next, we need to enable remote connections, as by default, MySQL only allows local connections. The specific command is as follows:

1. use mysql  // use the MySQL database
2. GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION // allow any host to log in with the password root, you need to alter the password from root to your password if changed
3. flush privileges // refresh privileges

At this point, the environment is roughly ready.

Demo

MySQL service has already been enabled on the server, so next, we attempt a local connection (open Wireshark to prepare for packet capture), with the command as follows:

mysql -u root -p -h 192.168.134.132

MySQL reverse reading >

Successfully connected, next, using the commands we just learned, to transfer a file:

load data local infile "C:/Windows/win.ini" into table test FIELDS TERMINATED BY '\n';
// Load client win.ini file into the server test table

Next, let’s look at Wireshark

Traffic Analysis

You can see here that it starts with a Server Greeting packet

It returns protocol number, version number, and salt value of the server, let’s look at the second packet

This should be the client login packet, returning the username and hash of the login password

Looking further down

This is the login packet, next is the normal statement query

Then is the result packet of the query statement echo

Next, analyze the file reading traffic packet, executing a statement in the MySQL command line, and after that, receiving the traffic packet

First, the client sends a query

The server returns the required path

Here, it can be seen that the file is successfully read, and it’s noticeable that the file is sent from the client to the server. Can we control this file for the server to maliciously read other files? Let’s first analyze the normal process:

1. Client: Insert the Win.ini file into the test table
2. Server: Read the Win.ini file content
3. Client: Win.ini content is xxx

The flow we want to achieve:

1. Client: I want to view the current database (any command is fine)
2. Server: Read flag.php file content
3. Client: flag.php content is xxx

Can this be done? In truth, it is feasible. Therefore, to realize malicious file reading, we can forge a fake MySQL server. When the client requests a connection, we allow the connection, and no matter what password is entered, it connects. Then, we send a request to read a file to the client, and wait for the client to send the file, as detailed in the following process:

1. Server sends a Greeting packet to the client
2. Client requests server login as root
3. Server allows client login
4. Client sends query version number and other information request to the server
5. Server requests 'C:\windows\system32\drivers\etc\hosts' file content from the client
6. Client sends the file content to the server
7. Server successfully receives, sending a response packet to the client

So, what our fake MySQL server needs to do becomes apparent.

1. Need to craft a Greeting packet and send it to the client
2. Need to allow any user to log in with any password, then give a response
3. Need to craft a TABULAR packet to send to the client (send the desired filename to be read to the client)
4. After receiving the file content, send a response packet

Here, we will not explain how to craft a Greeting packet and a TABULAR packet. If you want to build it yourself, you can refer to the article by master crow https://cloud.tencent.com/developer/article/1856248 which offers a detailed explanation on how to craft them. Here, we’ll try using a script written by a senior developer, with the script link as follows: https://github.com/allyshka/Rogue-MySql-Server/blob/master/rogue_mysql_server.py. First, it is necessary to modify the script to view files, as our client is a Windows environment, while the original script reads files under a Linux environment, so slight modifications are necessary. Change filelist to c:\windows\system32\drivers\etc\hosts

Launch the script

Next, use nmap to check if the port is open:

nmap -sS -p- 192.168.134.132 

We can see the port is open. Next, attempt to connect using Navicat (with an empty password, as this is a non-existent MySQL service—just a malicious server).

Next, we can find a new mysql.log file under the current path of the server, and check

Successfully obtained the text content. Next, let’s analyze the traffic with Wireshark to see if it matches our assumptions

It can be found to be consistent with what we previously thought. Next, attempt a connection with the malicious MySQL service using the MySQL command line and analyze if there is a difference in the traffic

The process turns out to be identical. The difference is that after connecting to the malicious service with the MySQL command line, it requests the version number and other information, while Navicat requests set names utf 8mb4 to obtain fingerprint and other information