How MySQL Servers Can Attack YOU

Alexander Rubin (Red Team Lead · Amazon Web Services), Martin Rakhmanov (Amazon Web Services)

HITBSecConf2023 - Amsterdam · Day 2 · Track 1

Overview

In a groundbreaking presentation at HITB Amsterdam, Alexander Rubin and Martin Rakhmanov from Amazon Web Services' Relational Database as a Service Red Team unveiled a critical client-side remote code execution (RCE) vulnerability affecting MySQL clients. Titled "How MySQL Servers Can Attack YOU," the talk inverted the traditional security paradigm: instead of an attacker compromising a client to gain access to a server, this research demonstrated how a compromised or malicious MySQL server could actively exploit a connecting client workstation, leading to arbitrary code execution on the client.

Watch on YouTube

Visual summary for How MySQL Servers Can Attack YOU by Alexander Rubin, Martin Rakhmanov
Visual summary for How MySQL Servers Can Attack YOU by Alexander Rubin, Martin Rakhmanov

Key moments

  1. 0:00 Introduction: MySQL server hacks the client
  2. 10:50 Server dictates client plugin to load
  3. 13:40 2019 vulnerability: Arbitrary code execution via directory traversal
  4. 24:30 Length overflow bypasses shared library extension
  5. 30:40 Live demo: Calculator launched on client workstation
  6. 37:50 2023 bypass: UTF-16 character set trick
  7. 46:00 Affected MySQL/MariaDB client versions and fixes
  8. 50:00 Q&A: UNC paths and Windows client limitations

How MySQL Servers Can Attack YOU

Speakers: Alexander Rubin (Red Team Lead, Amazon Web Services); Martin Rakhmanov (Amazon Web Services)

Conference: HITB Amsterdam

YouTube: https://www.youtube.com/watch?v=Qz92QTo9yr8

Overview

In a groundbreaking presentation at HITB Amsterdam, Alexander Rubin and Martin Rakhmanov from Amazon Web Services' Relational Database as a Service Red Team unveiled a critical client-side remote code execution (RCE) vulnerability affecting MySQL clients. Titled "How MySQL Servers Can Attack YOU," the talk inverted the traditional security paradigm: instead of an attacker compromising a client to gain access to a server, this research demonstrated how a compromised or malicious MySQL server could actively exploit a connecting client workstation, leading to arbitrary code execution on the client.

The talk detailed a sophisticated bypass of a previously "silently" fixed vulnerability from 2019, which allowed for directory traversal and arbitrary shared library loading on the client. The newly discovered bypass, affecting Oracle MySQL clients, leveraged an obscure interaction between multi-byte character sets and a legacy string comparison function, rendering the prior fix ineffective. This research highlights the inherent dangers of connecting to untrusted database servers and the long-tail impact of vulnerabilities in widely used client libraries and tools, posing a significant risk to DBAs, developers, and anyone connecting to potentially compromised MySQL instances.

The implications of this vulnerability are far-reaching. Given the pervasive use of MySQL across web applications, enterprise systems, and development environments, a successful exploit could allow attackers to pivot from a compromised database server directly into a DBA's workstation, potentially gaining access to sensitive credentials, internal networks, or further systems. The detailed technical breakdown and live demonstrations underscored the severity of the issue, which has now been officially addressed by Oracle with a new patch and assigned a CVE.

Background

▶ Watch: Introduction: MySQL server hacks the client (0:00)

To fully grasp the intricate nature of this vulnerability, it's essential to understand the historical and architectural foundations of MySQL. The database server, initially released in 1996 by Monty Widenius (who named it after his daughter, My), became a cornerstone of web infrastructure. After Oracle acquired Sun Microsystems, which owned MySQL, Monty Widenius forked the project to create MariaDB, ensuring its continued open-source development. Both MySQL and MariaDB share a significant amount of historical code, some dating back to the 1980s, which occasionally introduces unexpected security challenges.

A key architectural feature of MySQL is its pluggable architecture. This design allows for custom storage engines (like InnoDB, originally developed by Hiki Tuuri, which introduced transactions to MySQL) and, critically for this vulnerability, pluggable authentication methods. Authentication plugins are implemented as shared libraries (or DLLs on Windows) that reside on both the server and client. This allows for flexible authentication mechanisms beyond the default mysql_native_password, such as Kerberos or custom implementations.

The MySQL authentication protocol is central to the exploit. When a client initiates a connection, it proposes an authentication plugin name to the server. If the server supports this plugin, it proceeds with authentication. However, if the server does not support the client's proposed plugin, it can suggest an alternative plugin name to the client. The critical aspect here is that the client, upon receiving a plugin name from the server, will attempt to dynamically load this shared library from its local disk. This loading process uses functions like dlopen() on Linux/macOS or LoadLibrary() on Windows. The client trusts the server's instruction regarding which shared library to load, assuming it will be a legitimate authentication plugin located in a designated plugin_dir on the client's machine. This inherent trust mechanism, combined with insufficient input validation, laid the groundwork for the RCE.

Key Findings

▶ Watch: 2019 vulnerability: Arbitrary code execution via directory traversal (13:40)

The talk meticulously detailed two major security findings: the original client-side RCE via directory traversal and the subsequent bypass.

  1. The 2019 Client-Side RCE via Directory Traversal:
  • The vulnerability was initially reported against MariaDB via HackerOne in 2019. It revealed that a malicious MySQL server could instruct a connecting client to load an arbitrary shared library by exploiting a directory traversal weakness.
  • By crafting a plugin name like ../../../../tmp/evil.so, the server could bypass the intended plugin_dir restriction and cause the client to load a shared library from any arbitrary path on its local filesystem.
  • Once loaded, the shared library's constructor (_init) function would execute, allowing for arbitrary code execution on the client machine. This meant that even if the loaded file wasn't a valid MySQL plugin, its initialization code would still run.
  • MariaDB promptly fixed this issue in August 2019 by implementing input sanitization for plugin names, explicitly checking for and rejecting directory traversal symbols like ../.
  • Oracle MySQL also implemented a fix in November 2019, but it was "silently" applied with minimal public disclosure, using an internal bug ID and a commit message that, while verbose, was not widely publicized as a critical security patch. This fix relied on a different mechanism involving the my_str_cspn function.
  1. The 2023 Bypass of the 2019 Fix:
  • In February 2023, the AWS Red Team discovered a critical bypass for Oracle MySQL's 2019 fix. This bypass re-enabled the client-side RCE.
  • The core of the bypass exploited how the my_str_cspn function, used in Oracle's fix to detect directory separators (/ or \), interacted with multi-byte character sets.
  • By appending an extended connection setting, character set, and setting it to a non-default, multi-byte value like utf-16 (instead of utf-8), the vulnerability was re-activated.
  • When my_str_cspn was called with a utf-16 character set and an input string that was actually single-byte ASCII (containing the directory traversal characters), the function would incorrectly process the string, effectively skipping the checks for directory separators. This allowed the malicious plugin name with ../ to pass validation.
  • This bypass was reported to Oracle MySQL, which subsequently released a patch on April 18, 2023, as part of their CPU (Critical Patch Update). The fix is available in MySQL versions 8.0.33 and 5.7.42 and has been assigned an official CVE.

Technical Deep Dive

▶ Watch: Live demo: Calculator launched on client workstation (30:40)

The technical foundation of this vulnerability lies in the client's trust in the server and the dynamic loading of shared libraries. The relevant client-side code component is SQL_COMPANIES_CLIENT_PLUGIN, which is part of the libmysqlclient library used by many MySQL utilities and GUI tools.

When a server suggests a plugin name, the client constructs a full path to the shared library. This path is typically plugin_dir + plugin_name + .so (or .dll). The client then calls dlopen() (on Unix-like systems) or LoadLibrary() (on Windows) with this constructed path. For instance, if plugin_dir is /usr/local/mysql/lib/plugin/ and the server sends auth_my_plugin, the client attempts to load /usr/local/mysql/lib/plugin/auth_my_plugin.so.

The 2019 directory traversal vulnerability arose because the client did not adequately validate the plugin_name provided by the server. An attacker could send ../../../../tmp/evil_plugin, causing the client to attempt to load /usr/local/mysql/lib/plugin/../../../../tmp/evil_plugin.so, which resolves to /tmp/evil_plugin.so. Since dlopen() executes the _init (constructor) function of any loaded shared library, this provided a direct arbitrary code execution vector.

Oracle's 2019 fix attempted to mitigate this by introducing a check using the my_str_cspn function. This function was intended to identify if the plugin_name contained any directory separators (/ or \). If such characters were found, the connection would be rejected, preventing the traversal. However, the critical flaw in this fix, discovered in 2023, lay in the my_str_cspn function's handling of character sets.

The my_str_cspn function takes a character set parameter. When a client connects and specifies an extended setting like character set=utf16, this setting influences how my_str_cspn interprets strings. If the actual plugin_name string (e.g., ../../../../tmp/evil_plugin) is encoded in single-byte ASCII but my_str_cspn is told to expect a two-byte character set like utf-16, its internal logic for finding directory separators breaks down. It might misinterpret bytes, skip over the actual separator characters, or perform incorrect length calculations, effectively bypassing the intended check. The result is that the crafted malicious plugin name, despite containing directory traversal characters, passes the my_str_cspn validation.

Beyond directory traversal, the researchers also highlighted a length overflow vulnerability (a "length overflow" rather than a traditional buffer overflow) within the my_str_copy_fixed function, which concatenates the plugin_dir, plugin_name, and .so extension. The function uses a fixed-size buffer, typically 512 bytes, for the full path. If an attacker crafts a plugin_name that, when combined with the plugin_dir, exceeds this 512-byte limit, the .so extension (or .dll on Windows) can be effectively truncated or "cut off." This is significant because it allows the attacker to load an arbitrary file without a .so or .dll extension, enabling social engineering tactics like renaming a malicious shared library to resume.pdf. The client would then attempt to dlopen() resume.pdf as a shared library, executing its constructor.

Demo / Proof of Concept

▶ Watch: 2023 bypass: UTF-16 character set trick (37:50)

The talk featured compelling live and recorded demonstrations across both macOS and Windows, illustrating the practical exploitability of the bypass.

The attack chain begins with a Rogue MySQL Server. The speakers used a custom Python script built upon the MySQL mimic library (pip install MySQL mimic). This script was configured to act as a malicious MySQL server, specifically designed to push a crafted plugin_name to connecting clients.

The exploit payload was a simple shared library (.so for macOS/Linux, .dll for Windows). This library contained a _init (constructor) function. For macOS, the _init function executed a system() call to open the Calculator application (/Applications/Calculator.app/Contents/MacOS/Calculator) and create a file on the disk (e.g., /tmp/hacked_file). For Windows, the _init function displayed a MessageBox dialog, confirming code execution. These payloads, though simple, effectively demonstrated arbitrary code execution.

The social engineering aspect was crucial for delivering the shared library to the victim's machine. By leveraging the length overflow vulnerability, the attackers could rename their malicious shared library (e.g., exploit.so) to something innocuous like Martin_resume.pdf. The victim (a DBA, for instance) might receive this "resume" via email or LinkedIn, save it to their Documents folder, and then attempt to connect to the compromised database server using a vulnerable MySQL client (e.g., MySQL Workbench).

The demonstration proceeded as follows:

  1. A malicious actor started the Python rogue server on a controlled Ubuntu VM, configured to push a plugin_name pointing to the Martin_resume.pdf file saved on the victim's macOS workstation. The plugin_name also included the necessary ../ sequences and padding to trigger the length overflow and bypass the my_str_cspn check (by specifying character set=utf16).
  2. On the victim's macOS workstation, an older version of MySQL Workbench (e.g., 8.0.13 or 8.0.18, pre-patch) was used to attempt a connection to the rogue server.
  3. Upon connection, the Workbench client, relying on libmysqlclient, processed the malicious plugin_name from the server. Due to the utf-16 character set trick, the directory traversal was not detected. Due to the length overflow, the .so extension was truncated, allowing Martin_resume.pdf to be loaded as a shared library.
  4. The _init function within Martin_resume.pdf executed, causing the Calculator application to immediately pop up on the DBA's desktop, visibly demonstrating client-side RCE. An error message about the "fake plugin" would also appear in Workbench, but the code had already executed.

A similar demonstration was shown for Windows, where an older Workbench 8.0.18 connecting to the rogue server caused a MessageBox to appear, confirming DLL loading and execution. The speakers verified this with process monitoring tools like S3s, showing Amber.dll being loaded.

Finally, the talk demonstrated the fix in action. When attempting the same exploit with MySQL Workbench connecting to MySQL 8.0.33 (the patched version) and supplying the character set=utf16 trick, the client correctly rejected the connection, stating that "no paths allowed" or that the "utf-16 character set is not supported" in the authentication phase, confirming the successful mitigation.

Defensive Implications

▶ Watch: Q&A: UNC paths and Windows client limitations (50:00)

The findings presented by Rubin and Rakhmanov carry significant defensive implications for anyone interacting with MySQL databases. The primary takeaway is that connecting to an untrusted or potentially compromised MySQL server is inherently dangerous for the client workstation.

  1. Immediate Upgrades: The most critical defensive action is to upgrade all MySQL client libraries and GUI tools to the latest patched versions. For Oracle MySQL, this means upgrading to MySQL 8.0.33, 5.7.42, or later. For MariaDB, versions released after August 2019 already contain the fix for the initial directory traversal. This applies to libmysqlclient (C/C++ client library), ODBC drivers based on libmysqlclient, and popular GUI tools like MySQL Workbench, Navicat, and SQL Pro.
  2. Untrusted Server Awareness: Database administrators and developers must exercise extreme caution when connecting to any MySQL server whose integrity cannot be guaranteed. This includes servers in unfamiliar environments, development/test servers that might be less secure, or any server suspected of being compromised. The traditional assumption that the client is safe from server-side exploits is shattered by this vulnerability.
  3. SSL/TLS Limitations: While SSL/TLS is crucial for protecting data in transit, it does not protect against this particular RCE. If a server is compromised, an attacker can control the server's behavior, including its certificates and the malicious plugin name it pushes. Connecting via SSL/TLS only encrypts the malicious communication; it doesn't prevent the server from instructing the client to load a malicious library.
  4. Client-Side Software Supply Chain: The vulnerability highlights the broad impact of issues in foundational client libraries. Many applications and tools embed libmysqlclient or are built upon it, meaning they are indirectly vulnerable. Organizations should inventory their software that connects to MySQL and ensure all components are updated.
  5. Java/JDBC Exemption: It's important to note that clients using native implementations, such as Java's JDBC driver, are generally not affected by this specific vulnerability. They typically do not rely on libmysqlclient for dynamic plugin loading in the same manner.
  6. Social Engineering Vigilance: The use of the length overflow to disguise a malicious shared library as a PDF (e.g., resume.pdf) underscores the importance of user education against social engineering. DBAs and other users should be wary of unexpected files, even if they appear benign, and follow best practices for handling attachments from unknown or suspicious sources.
  7. Legacy Code Review: The root cause of the bypass—a legacy my_str_cspn function from 1984 failing with modern multi-byte character sets—serves as a stark reminder for developers. Organizations should regularly audit their codebases for old functions, especially those dealing with string manipulation and input validation, and ensure they are robust against modern encoding complexities and attack vectors.

Key Takeaways

  • Rogue Servers Can Attack Clients: A compromised or malicious MySQL server can initiate a client-side Remote Code Execution (RCE) attack, turning the client workstation into a victim.
  • Bypass of Prior Fix: A clever technique involving the character set=utf16 extended connection setting bypassed Oracle MySQL's 2019 fix for directory traversal, re-enabling the RCE.
  • Widespread Client-Side Impact: The vulnerability impacts a broad range of MySQL clients and tools built upon the libmysqlclient C/C++ library, including MySQL Workbench, Navicat, SQL Pro, and various ODBC drivers.
  • Urgent Patching Required: All MySQL client software, especially MySQL Workbench and libmysqlclient installations, must be upgraded to MySQL 8.0.33, 5.7.42, or newer versions to mitigate this risk.
  • Legacy Code Dangers: The exploit's success hinged on a 1984 string comparison function (my_str_cspn) failing to account for multi-byte character sets, highlighting the risks of unreviewed legacy code in modern contexts.
  • Social Engineering as a Delivery Vector: The ability to load arbitrary file types (e.g., a malicious .pdf file) through a length overflow vulnerability enables effective social engineering attacks to deliver exploit payloads.

About the Speaker(s)

Alexander Rubin is a Red Team Lead at Amazon Web Services (AWS). With a long history of working with MySQL, he was formerly part of the MySQL AB company (the original creators of MySQL). Over the years, his interest gravitated towards security, leading him to participate in Capture the Flag games. At AWS, he leads the relational database as a service Red Team, focusing on security research and penetration testing against AWS's own database services.

Martin Rakhmanov is a security expert at Amazon Web Services, also part of the Red Team. He brings over 17 years of experience in the database security space. Martin joined the AWS Red Team in 2022 and has been actively involved in penetration testing against various AWS services, contributing significantly to the discovery and analysis of the bypass vulnerability discussed in this talk.

Reviews

Dr. Zero (Offensive Security Researcher) — STRONG ACCEPT

Solid client-side RCE research with a clever bypass of a silently-patched 2019 fix. The utf-16 charset trick to defeat mystrcspn validation is genuinely novel, and the length overflow for extension truncation adds a nice social engineering angle. Not groundbreaking exploitation technique, but real work that resulted in a real CVE and affects a massive attack surface.

Heather Calloway (CISO) — STRONG ACCEPT

This is real, consequential research that flips the client-server trust model. Any organization with DBAs connecting to MySQL instances they don't fully control—dev environments, vendor databases, acquired infrastructure—has a material exposure here. Worth your security leadership's attention.

→ Top-rated talks at HITBSecConf2023 - Amsterdam

All talks from HITBSecConf2023 - Amsterdam