
MySQL Community Server 26.7.0 – Hoch – mysqldump SHOW TABLES Stack Overflow – Crash-Dump-UID
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · mysql-mysqldump-show-tables-overflow
Klasse: Crash Reichweite: Remote
MySQL Community Server mysqldump 26.7.0 (06a5c1c) - Oracle
Das Standard-mysqldump kopiert SHOW TABLES-Namen ohne NAME_LEN-Begrenzung. getTableName gibt eine rohe mysql_fetch_row zurück. dump_all_tables_in_db my_stpcpyt diesen String in hash_key[2*NAME_LEN+2], und quote_name schreibt ihn in einen 387-Byte-Stack-Puffer ohne Begrenzung. Ein feindseliger Server, der einen Tabellennamen länger als 192 Bytes zurückgibt, bringt den Dump-UID zum Absturz.
Ein echtes mysqld wird keine so langen Bezeichner ausgeben. Der Rest ist der Client, der dem Protokoll vertraut.
| ID | noch keine CVE |
| Klasse | Crash (Client SIGSEGV; kein RCE nachgewiesen) |
| Reichweite | Remote (Opfer führt mysqldump gegen einen Angreifer-MySQL aus; UI:R) |
| CWE | CWE-120, CWE-121 |
| CVSS | High: 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| Produkt | MySQL Community Server mysqldump |
| Betroffen | 26.7.0 (06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8) |
| Auth | Opfer führt Standard-mysqldump gegen einen Angreifer-MySQL aus |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1. Crash-Nachweis. Keine RIP-Nutzlast. |
Einen MySQL-Protokoll-Server aufsetzen. Den Handshake abschließen. Die Session-SETs beantworten. Wenn der Client show tables sendet, eine Zeile zurückgeben, deren Name mehrere zehn Kilobyte lang ist.
Der Operator, der mysqldump testdb auf diesen Host gerichtet hat, überläuft einen Stack-Puffer im Dump-Prozess. Das Lab auf mysqldump Ver 26.7.0 ist SIGSEGV. Zuverlässige Instruction-Pointer-Kontrolle ist nicht Teil dieses Pakets. Der Crash schon.
Dasselbe Opfermodell wie ein Backup-Client, der auf einen bösartigen Server gerichtet ist. lock_tables ist Standard über --opt. Der Überlauf liegt in dieser ersten SHOW TABLES-Schleife.
Ich habe einunddreißig Quellcode-Suchen im https://github.com/mysql/mysql-server Tag https://github.com/mysql/mysql-server/tree/mysql-26.7.0 durchgeführt. Standard-mysqld unveröffentlichte Crit/High kamen leer zurück. Die CPU-High-Server-Zeilen vom Juli 2026 sind auf diesem Pin geschlossen. Client-Tools waren die übrig gebliebene Klasse, dieselbe Form wie PostgreSQL pg_basebackup, das einem feindseligen Pfad folgt.
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 ist 64 * 3 = 192. hash_key ist 386 Bytes. quote_name in dump_table schreibt in table_buff[NAME_LEN+3].
Bereits dokumentierte Irrwege: ein echtes mysqld als Orakel behandeln (es wird keinen 193-Byte-Bezeichner ausgeben); ein 4KiB-Name, der von real_columns[MAX_FIELDS] im selben Frame wie hash_key absorbiert wird; ASan aus dem vollständigen Server-Baum kompilieren; den Crash als Instruction-Pointer-Kontrolle bezeichnen.
cd lab
./run.sh
Image mysql:26.7.0. Feindseliger Stub auf Compose stub:3306 (Kontrolle, Tabelle t) und stub:3307 (Überlauf, 64KiB-Name plus Nachweis). Veröffentlicht 127.0.0.1:18600 / 18601. Binde es an 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
Die Kontrolle gibt einen 26.7.0-Dump-Header aus und beendet sich mit 2 bei SQL 1146. Der Überlauf stirbt direkt nach show tables. Kein LOCK TABLES auf dieser Verbindung.
getTableName auf NAME_LEN begrenzen. quote_name eine Pufferlänge geben und das Schreiben darüber hinaus verweigern. my_stpcpy in hash_key sollte eine begrenzte Kopie sein. Ein feindseliger SHOW TABLES-Name ist keine Tabelle.
06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8)getTableName, quote_name, dump_all_tables_in_dbNAME_LENmysql_list_tables