
MySQL Community Server 26.7.0 - Alta - desbordamiento de pila en mysqldump SHOW TABLES - volcado de fallo UID
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · mysql-mysqldump-show-tables-overflow
Clase: Crash Alcance: Remoto
MySQL Community Server mysqldump 26.7.0 (06a5c1c) - Oracle
El mysqldump por defecto copia los nombres de SHOW TABLES sin límite de NAME_LEN. getTableName devuelve un mysql_fetch_row en bruto. dump_all_tables_in_db hace my_stpcpy de esa cadena en hash_key[2*NAME_LEN+2] y quote_name la escribe en un búfer de pila de 387 bytes sin límite. Un servidor hostil que responde con un nombre de tabla de más de 192 bytes provoca un crash en el UID del dump.
Un mysqld real no emitirá identificadores tan largos. Lo que queda es el cliente confiando en el protocolo.
| ID | sin CVE todavía |
| Clase | Crash (SIGSEGV del cliente; no se demuestra RCE) |
| Alcance | Remoto (la víctima ejecuta mysqldump contra un MySQL atacante; UI:R) |
| CWE | CWE-120, CWE-121 |
| CVSS | Alto: 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| Producto | MySQL Community Server mysqldump |
| Afectado | 26.7.0 (06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8) |
| Auth | la víctima ejecuta el mysqldump por defecto contra un MySQL atacante |
| Licencia | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1. Testigo de crash. Sin payload RIP. |
Levantar un servidor con protocolo MySQL. Completar el handshake. Responder a los SET de sesión. Cuando el cliente envía show tables, devolver una fila cuyo nombre tenga decenas de kilobytes de longitud.
El operador que apuntó mysqldump testdb a ese host desborda un búfer de pila en el proceso de dump. El lab sobre mysqldump Ver 26.7.0 es SIGSEGV. El control fiable del instruction pointer no forma parte de este pack. El crash sí.
Mismo modelo de víctima que un cliente de backup apuntado a un servidor malicioso. lock_tables es por defecto vía --opt. El desbordamiento está en ese primer bucle de SHOW TABLES.
Ejecuté treinta y una búsquedas de código fuente de https://github.com/mysql/mysql-server tag https://github.com/mysql/mysql-server/tree/mysql-26.7.0. Los Crit/High no publicados del mysqld por defecto salieron vacíos. Las filas de CPU High Server de julio de 2026 están cerradas en este pin. Las herramientas de cliente eran la clase sobrante, con la misma forma que PostgreSQL pg_basebackup siguiendo una ruta hostil.
static char *getTableName(int reset) {
static MYSQL_RES *res = nullptr;
MYSQL_ROW row;
if (!res) {
if (!(res = mysql_list_tables(mysql, NullS))) return (nullptr);
}
if ((row = mysql_fetch_row(res))) return ((char *)row[0]);
static char *quote_name(char *name, char *buff, bool force) {
char *to = buff;
const char qtype = ansi_quotes_mode ? '"' : '`';
if (!force && !opt_quoted && !test_if_special_chars(name)) return name;
*to++ = qtype;
while (*name) {
if (*name == qtype) *to++ = qtype;
*to++ = *name++;
}
NAME_LEN es 64 * 3 = 192. hash_key es de 386 bytes. quote_name en dump_table escribe en table_buff[NAME_LEN+3].
Caminos equivocados ya registrados: tratar un mysqld real como el oráculo (no emitirá un identificador de 193 bytes); un nombre de 4KiB absorbido por real_columns[MAX_FIELDS] en el mismo frame que hash_key; compilar ASan desde el árbol completo del servidor; llamar al crash control del instruction pointer.
cd lab
./run.sh
Imagen mysql:26.7.0. Stub hostil en el compose stub:3306 (control, tabla t) y stub:3307 (desbordamiento, nombre de 64KiB más testigo). Publicado en 127.0.0.1:18600 / 18601. Enlázalo a loopback.
control-rc=2 control-signal=0
overflow-rc=139 overflow-signal=SIGSEGV
SUCCESS mysql-mysqldump-show-tables-overflow ... MYSQL-DUMP-SHOW-TABLES-OVERFLOW-WITNESS
El control imprime una cabecera de dump 26.7.0 y sale con 2 en SQL 1146. El desbordamiento muere justo después de show tables. Sin LOCK TABLES en esa conexión.
Limitar getTableName a NAME_LEN. Dar a quote_name una longitud de búfer y negarse a escribir más allá de ella. El my_stpcpy en hash_key debería ser una copia acotada. Un nombre hostil de SHOW TABLES no es una tabla.
06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8)getTableName, quote_name, dump_all_tables_in_dbNAME_LENmysql_list_tables