MySQL Community Server 26.7.0 - Alta - mysqldump --tab path leftover - gravação de arquivo do cliente
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · mysql-mysqldump-tab-path
Classe: Escrita de arquivo (cliente) Alcance: Remoto (UI:R)
MySQL Community Server mysqldump 26.7.0 (06a5c1c) - Oracle
mysqldump --tab=DIR grava um .sql por tabela usando fn_format sem MY_REPLACE_DIR. Um nome hostil em SHOW TABLES com / ou .. mantém esse diretório. DIR é ignorado. O UID do dump faz my_fopen no caminho.
--tab é documentado como modo mesma-máquina porque o .txt passa pelo INTO OUTFILE do servidor. O .sql ainda é uma escrita cliente.
| ID | sem CVE ainda |
| Classe | Escrita de arquivo (cliente --tab .sql) |
| Alcance | Remoto (vítima executa mysqldump --tab contra um MySQL do atacante; UI:R) |
| CWE | CWE-22 |
| CVSS | Alto: 8.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N |
| Produto | MySQL Community Server mysqldump |
| Afetado | 26.7.0 (06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8) |
| Autenticação | vítima executa mysqldump --tab=DIR contra um MySQL do atacante |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1. Testemunha .sql fora de DIR. |
Suba um servidor de protocolo MySQL. Responda SHOW TABLES com /abs/path ou ../outside. O operador que executou mysqldump --tab=/backup testdb grava /abs/path.sql (ou um caminho relativo ao cwd) como o UID do dump.
Sobrescreva qualquer arquivo que esse UID possa criar. Mesma classe de um cliente de backup que confia em um nome de arquivo remoto. O caminho .txt do INTO OUTFILE é FILE do lado do servidor. O que sobra é o .sql do cliente.
Um mysqld real não emitirá um nome de tabela com /. O que sobra é o cliente.
Mesma caçada da 26.7.0 que o mysqldump SHOW TABLES overflow. O daemon padrão estava vazio. As ferramentas cliente ainda confiavam em SHOW TABLES. O overflow foi um resquício. O --tab foi o próximo.
static FILE *open_sql_file_for_table(const char *table, int flags) {
FILE *res;
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
convert_dirname(tmp_path, path, NullS);
res = my_fopen(fn_format(filename, table, tmp_path, ".sql",
MYF(MY_UNPACK_FILENAME | MY_APPEND_EXT)),
flags, MYF(MY_WME));
return res;
}
mysys/mf_format.cc: se dirname_part(name) não for vazio e MY_REPLACE_DIR estiver desligado, o dir fornecido não é usado.
Caminhos errados já registrados: tratar um mysqld real como o oráculo; morrer em SHOW TABLE STATUS antes de SHOW CREATE TABLE (o .sql só abre depois que o CREATE tem sucesso); chamar o .txt do INTO OUTFILE de resquício; um nome de 64KiB que reincide no overflow G1.
Não é o MariaDB CVE-2025-13699 (traversal de nome de view do mariadb-dump). Mesma classe, cópia do MySQL Community.
cd lab
./run.sh
Imagem mysql:26.7.0. --tab=/work/tabdir. Tabela stub de controle t grava work/tabdir/t.sql. Tabela stub de traversal /work/oracle/MYSQL-DUMP-TAB-TRAVERSAL-WITNESS grava work/oracle/MYSQL-DUMP-TAB-TRAVERSAL-WITNESS.sql. Publicado em 127.0.0.1:18610 / 18611. Vincule ao loopback.
control-sql=yes
traversal-outside=yes
SUCCESS mysql-mysqldump-tab-path ... MYSQL-DUMP-TAB-TRAVERSAL-WITNESS
Passe MY_REPLACE_DIR para fn_format nos arquivos cliente de --tab, ou use basename do nome da tabela primeiro. --tab=DIR deveria significar DIR.
06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8)client/mysqldump.cc open_sql_file_for_tablemysys/mf_format.cc