Ich machte einige Hausaufgaben für meine Sicherheitsklasse mit SQL-Injektionen. Ich fand, dass ich eine kürzere SQL-Injektion als das typische ' OR '1'=1
Beispiel machen könnte. Stattdessen könnte ich '='
machen. Wenn Sie dies in das Passwortfeld einer typischen Login-Box eingeben, erhalten Sie eine SQL-Abfrage wie folgt:
Es stellt sich heraus, dass password=''=''
zu 1
ausgewertet wird und die SQL-Injection funktioniert.
Nachdem ich einige Tests durchgeführt hatte, sah ich, dass, wenn ich teste, ob eine Zeichenkette gleich 0 ist, 1:
zurückgibt %Vor% In meinem Beispiel würde also password=''
zu 0 und 0=''
zu 1 auswerten.
Meine Tests haben mir gezeigt, wie das passiert, aber ich möchte wissen warum das passiert (d. h. warum ist 0='a'
wahr?.
Wie in Typkonvertierung in der Ausdrucksauswertung dokumentiert, werden Vergleiche zwischen einer Zeichenfolge und einer Ganzzahl durchgeführt numerisch durchgeführt werden:
- In allen anderen Fällen werden die Argumente als Fließkommazahlen (reelle Zahlen) verglichen.
Daher werden die Operanden in Fließkommazahlen konvertiert und dann verglichen.
Bei der Konvertierung eines Strings in einen Float werden alle numerischen Zeichen (und die erste Periode oder das erste Exponentialzeichen) berücksichtigt, die bis zum ersten nicht numerischen Zeichen aufgetreten sind. Daher wird 'hello'
oder 'a'
auf ''
gekürzt (und somit auf Null umgewandelt), während '123.45e6foo789'
auf '123.45e6'
(und damit auf 123.450.000) reduziert wird.
So kann man sehen, wie 0='a'
wahr ist: es wird als 0=0
verglichen.
Das password=''=''
ist wahr ( vorausgesetzt, dass password
eine nicht leere Zeichenkette ist, oder eine numerische Zahl ungleich null), weil der erste Vergleich null (false) ergibt, was erzwingt, dass der zweite Vergleich numerisch durchgeführt wird (und somit ''
für den Vergleich mit dem Null-Ergebnis des ersten Vergleichs auf Null setzt).
Für SELECT 0 = 'a', 0 = '';
%Vor%Konvertiere char in int, dann wird 0 = 0 in deinem Fall als wahr ausgewertet 1. In:
%Vor%Alle Spalten sind wahr, aber für:
%Vor%ist falsch, weil CAST ('1a' AS UNSIGNED) 1 ist.
%Vor%Tags und Links sql mysql sql-injection