
MySQL Community Server 26.7.0 - Alta - overflow dello stack in mysqldump SHOW TABLES - crash dump UID
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · mysql-mysqldump-show-tables-overflow
Classe: Crash Portata: Remota
MySQL Community Server mysqldump 26.7.0 (06a5c1c) - Oracle
Il mysqldump predefinito copia i nomi di SHOW TABLES senza alcun limite NAME_LEN. getTableName restituisce un mysql_fetch_row grezzo. dump_all_tables_in_db esegue my_stpcpy di quella stringa in hash_key[2*NAME_LEN+2] e quote_name la scrive in un buffer di stack da 387 byte senza alcun limite. Un server ostile che risponde con un nome di tabella più lungo di 192 byte manda in crash l'UID del dump.
Un mysqld reale non emetterà identificatori così lunghi. Il residuo è il client che si fida del protocollo.
| ID | nessuna CVE al momento |
| Classe | Crash (SIGSEGV del client; RCE non dimostrata) |
| Portata | Remota (la vittima esegue mysqldump contro un MySQL dell'attaccante; 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 |
| Prodotto | MySQL Community Server mysqldump |
| Affetto | 26.7.0 (06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8) |
| Auth | la vittima esegue il mysqldump predefinito contro un MySQL dell'attaccante |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1. Testimone del crash. Nessun payload RIP. |
Mettere in piedi un server con protocollo MySQL. Completare l'handshake. Rispondere ai SET di sessione. Quando il client invia show tables, restituire una riga il cui nome è lungo decine di kilobyte.
L'operatore che ha puntato mysqldump testdb verso quell'host manda in overflow un buffer di stack nel processo di dump. Il lab su mysqldump Ver 26.7.0 è SIGSEGV. Il controllo affidabile dell'instruction pointer non fa parte di questo pacchetto. Il crash sì.
Stesso modello di vittima di un client di backup puntato verso un server malevolo. lock_tables è predefinito tramite --opt. L'overflow è in quel primo ciclo SHOW TABLES.
Ho eseguito trentuno ricerche nel sorgente di https://github.com/mysql/mysql-server tag https://github.com/mysql/mysql-server/tree/mysql-26.7.0. I Crit/High non pubblicati del mysqld predefinito sono risultati vuoti. Le righe CPU High Server di luglio 2026 sono chiuse su questo pin. Gli strumenti client erano la classe residua, stessa forma del PostgreSQL pg_basebackup che segue un percorso ostile.
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 è 64 * 3 = 192. hash_key è 386 byte. quote_name in dump_table scrive in table_buff[NAME_LEN+3].
Vicoli ciechi già registrati: trattare un mysqld reale come oracolo (non emetterà un identificatore da 193 byte); un nome da 4KiB assorbito da real_columns[MAX_FIELDS] sullo stesso frame di hash_key; compilare ASan dall'intero albero del server; chiamare il crash controllo dell'instruction pointer.
cd lab
./run.sh
Immagine mysql:26.7.0. Stub ostile su compose stub:3306 (controllo, tabella t) e stub:3307 (overflow, nome da 64KiB più testimone). Pubblicati 127.0.0.1:18600 / 18601. Associalo al 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
Il controllo stampa un header di dump 26.7.0 ed esce con 2 su SQL 1146. L'overflow muore subito dopo show tables. Nessun LOCK TABLES su quella connessione.
Limitare getTableName a NAME_LEN. Dare a quote_name una lunghezza del buffer e rifiutarsi di scrivere oltre. my_stpcpy in hash_key dovrebbe essere una copia con limiti. Un nome ostile di SHOW TABLES non è una tabella.
06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8)getTableName, quote_name, dump_all_tables_in_dbNAME_LENmysql_list_tables