
MySQL Community Server 26.7.0 - Élevé - mysqlbinlog --raw Rotate path leftover - écriture de fichier client
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · mysql-mysqlbinlog-raw-path
Classe : Écriture de fichier (client) Portée : Distante (UI:R)
MySQL Community Server mysqlbinlog 26.7.0 (06a5c1c) - Oracle
mysqlbinlog --raw --read-from-remote-server copie un identifiant new_log_ident d'un événement Rotate dans log_file_name sans vérification du nom de base. L'événement FORMAT_DESCRIPTION suivant fait un my_fopen sur ce chemin et écrit BINLOG_MAGIC plus l'événement. Un dump hostile qui envoie un identifiant Rotate réel avec un / écrit ce fichier avec l'UID du client.
--raw est la copie de fichier binlog distant documentée. Le reliquat consiste à traiter l'identifiant comme un chemin.
| ID | pas encore de CVE |
| Classe | Écriture de fichier (client --raw BINLOG_MAGIC) |
| Portée | Distante (la victime exécute mysqlbinlog --raw -R contre un dump de l'attaquant ; UI:R) |
| CWE | CWE-22 |
| CVSS | Élevé : 8.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N |
| Produit | MySQL Community Server mysqlbinlog |
| Affecté | 26.7.0 (06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8) |
| Auth | la victime exécute mysqlbinlog --raw -R contre un dump de l'attaquant |
| Licence | GNU Affero GPL v3.0 |
| Labo | 127.0.0.1 uniquement. Fichier témoin avec BINLOG_MAGIC. Écriture de fichier, pas de RCE. |
Monter un serveur au protocole MySQL. Parler COM_BINLOG_DUMP. Envoyer un faux Rotate correspondant (timestamp 0, identifiant égal au nom de log demandé) pour que le dump ne s'arrête pas. Envoyer un Rotate réel (timestamp != 0) dont l'identifiant est /abs/path. Envoyer un événement FORMAT_DESCRIPTION.
L'opérateur qui a exécuté mysqlbinlog --raw -R ... mysql-bin.000001 écrit /abs/path avec l'UID du client. Le contenu est constitué d'octets de binlog (\xfebin plus l'événement FD), pas d'une charge utile arbitraire. Écraser n'importe quel chemin que cet UID peut créer.
Un vrai mysqld n'émettra pas d'identifiant Rotate avec un /. Le reliquat est le client.
Même chasse sur la 26.7.0 que mysqldump SHOW TABLES overflow et mysqldump --tab path. Le démon par défaut était vide. Les outils clients faisaient encore confiance aux noms distants.
if (raw_mode) {
if (output_file != nullptr) {
snprintf(log_file_name, sizeof(log_file_name), "%s%s", output_file,
rev->new_log_ident);
} else {
my_stpcpy(log_file_name, rev->new_log_ident);
}
}
Un faux Rotate (when.tv_sec == 0) dont l'identifiant ne correspond pas au log demandé arrête le dump. Un faux Rotate correspondant est ignoré (continue) après la copie. Un Rotate réel n'arrête pas. FD suivant :
if (!(result_file = my_fopen(
log_file_name, O_WRONLY | MY_FOPEN_BINARY, MYF(MY_WME)))) {
error("Could not create log file '%s'", log_file_name);
Les temporaires LOAD DATA restent SQL_LOAD_MB sous tmpdir. Fermé. La longueur de l'identifiant est plafonnée à FN_REFLEN-1. Le / n'est pas supprimé.
Fausses pistes déjà consignées : envoyer un faux Rotate dont l'identifiant est le chemin (le dump s'arrête) ; utiliser --result-file (l'identifiant devient un préfixe, reliquat différent) ; un vrai mysqld comme oracle ; les checksums laissés activés.
cd lab
./run.sh
Image mysql:26.7.0. Binaire /usr/libexec/mysqlsh/mysqlbinlog Ver 26.7.0 (pas dans le PATH de cette image). Stub de contrôle : faux Rotate mysql-bin.000001 plus FD écrit work/mysql-bin.000001. Stub de traversée : faux Rotate correspondant, Rotate réel identifiant /work/oracle/MYSQL-BINLOG-RAW-WITNESS, FD écrit ce chemin (BINLOG_MAGIC). Publié sur 127.0.0.1:18620 / 18621. Le lier à loopback. Écriture de fichier d'octets de binlog, pas de RCE. Pas de --result-file.
control-basename=yes
traversal-outside=yes
SUCCESS mysql-mysqlbinlog-raw-path ... MYSQL-BINLOG-RAW-WITNESS
Prendre le basename de new_log_ident avant le my_stpcpy / snprintf dans log_file_name. --raw devrait écrire sous le cwd ou le préfixe --result-file, pas dans un identifiant contenant un /.
06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8)client/mysqlbinlog.cc dump_remote_log_entries