Eine Sicherheitslücke in der MySQL-Datenbank hat zur Folge, dass ein entfernter Angreifer den Anmeldemechanismus der SQL-Datenbank umgehen kann.
Der Programmierfehler befindet sich in der Quelltextdatei “sql/password.c”. Funktionen dieser Datei sind Bestandteil des Authentifikationsmechanismus von MySQL. Eine zentrale Rolle hierbei spielt die Funktion “check_scramble()”:
my_bool check_scramble(const char *scramble_arg, const char *message, const uint8 *hash_stage2)
{ ... return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
}
Basierend auf dem Hash-Vergleich am Ende erlaubt diese Funktion den Zugriff auf die Datenbank (Rückgabewert = 0), oder verbietet diesen (Rückgabewert != 0). Wichtig hierbei ist, dass diese Funktion eine Variable des Typs “my_bool” zurückliefert und dieser Typ via
typedef char my_bool
als einfacher “char” definiert ist.
Die Man-Page der Bibliotheksfunktion memcmp() sagt nun aber über das Verhalten und insbesondere den Rückgabewert von memcmp() folgendes:
BEZEICHNUNG
memcmp – vergleicht Speicherbereiche
ÜBERSICHT
#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
BESCHREIBUNG
Die Funktion memcmp() vergleicht die ersten n Bytes der
Speicherbereiche s1 und s2. Sie gibt eine Ganzzahl zurück, die kleiner
als, gleich oder größer als Null ist, wenn s1 kleiner als, gleich oder
größer als s2 ist.
RÜCKGABEWERT
Die Funktion memcmp() gibt eine Ganzzahl zurück, die kleiner als,
gleich oder größer als Null ist, wenn die ersten n Byte von s1 kleiner
als, gleich oder größer als die ersten n Byte von s2 sind.
Wie gewünscht führt diese Funktion einen Speichervergleich zwischen den durch die s1- und s2-Zeiger adressierten Speicherbereichen durch. Problematisch ist allerdings, dass die Funktion einen Integer-Wert zurückliefert. Dies hat zur Folge, dass der Wort von “t_bool” beziehungsweise der “char”-Wert trotz “memcmp()!=0” Null sein kann. Dies passiert genau dann, wenn das letzte Integer-Byte Null ist, wie folgendes einfache Beispiel zeigt:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{ int val1; char val2; //some integer value val1=424242; // clear last byte val1 &= ~255; // cast to char val2=val1; printf("%d %d\n", val1, val2); return 0;
}
Hier wird das letzte Byte durch eine Bit-Operation explizit auf Null gesetzt, wodurch der “char”-Variablen “val2” im Cast Null zugeordet wird. In der Praxis müsste ein solcher Integer dann zufällig die entsprechenden Bits auf Null gesetzt haben, um im “char”-Case Null zu liefern. Genau dies kann nun im MySQL-Code geschehen. In diesem Fall wird ein falsches Passwort akzeptiert, und ein entfernter Angreifer kann den Datenbank-Schutz umgehen. Der Fehler hängt vom Rückgabewert von “memcmp()” ab, und es braucht einige Anläufe um einen Integer mit nicht gesetztem letzten Byte zu erwischen.
Betroffen sind die Versionen 5.1.61, 5.2.11, 5.3.5, 5.5.22 und älter.

