PHP ist eine allgemeine Open-Source-Skriptsprache. Ihre Syntax ist eine Mischung aus der Syntax hervorragender Sprachen wie C, Java und Perl. Darüber hinaus stellt es Entwicklern eine große Anzahl von Funktionsbibliotheken zur Verfügung. Allerdings kann PHP bei unsachgemäßer Verwendung auch sehr große Sicherheitsrisiken für Anwendungen mit sich bringen.
In diesem Artikel führen wir eine eingehende Analyse einiger Probleme durch, die häufig in PHP-Anwendungen auftreten. Insbesondere wenn wir „==" (Vergleichsoperator) zum Durchführen von Zeichenfolgenvergleichen verwenden, können einige Sicherheitsprobleme auftreten . Obwohl dieses Thema in letzter Zeit in vielen Artikeln behandelt wurde, habe ich beschlossen, aus der Perspektive des „Black-Box-Tests“ zu diskutieren, wie dieses Problem genutzt werden kann, um Ziele zu durchdringen und anzugreifen. Zunächst werde ich die Grundursache dieses Problems analysieren, damit wir den Funktionsmechanismus besser verstehen und so sicherstellen können, dass wir dieses Sicherheitsproblem so weit wie möglich vermeiden können.
Beschreibung des ProblemsTatsächlich wird diese Situation angezeigt, wenn für den Betrieb Vergleichsoperatoren wie „==" verwendet werden. Das Problem im obigen Beispiel kann nicht als Sicherheitslücke angesehen werden, da es sich um eine von PHP bereitgestellte Funktion namens „Typkonvertierung“ handelt. Wenn wir zum Betrieb bestimmte Vergleichsoperatoren (z. B. ==, !=, ) verwenden, versucht PHP im Wesentlichen zunächst, den am Vergleich beteiligten Datentyp zu bestimmen. Ein solcher Typkonvertierungsmechanismus kann jedoch dazu führen, dass die Berechnungsergebnisse stark von unseren erwarteten Ergebnissen abweichen und auch sehr schwerwiegende Sicherheitsprobleme verursachen. Sicherheitsforschungsexperten schrieben in einem ausführlichen Offenlegungsbericht zu diesem Problem: Dieser Typkonvertierungsmechanismus kann zu einer Rechteausweitung führen und sogar den Passwortüberprüfungsprozess des Programms unsicher machen.
Wie Sie sehen können, wenn wir „==“ verwenden, um diese numerischen Zeichenfolgen zu vergleichen. Zu diesem Zeitpunkt geht es beim Vergleich um die Tatsächliche Größe der Zahl in der Zeichenfolge. Aus Sicherheitsgründen ist dies ein sehr interessantes Problem. In diesem Fall können Sie eine Zahl in wissenschaftlicher Notation darstellen und in einen String einfügen. PHP behandelt sie dann automatisch als Zahlentyp. Der Grund, warum wir einen solchen Ausgabetyp erhalten, liegt darin, dass PHP zur Verarbeitung einen Hash-Algorithmus (normalerweise dargestellt durch einen Hexadezimalwert) verwendet. Wenn eine Zahl beispielsweise 0 ist, konvertiert PHP beim losen Vergleich automatisch ihren Typ, ihr Wert ist jedoch immer 0. Für einen bestimmten Hashing-Algorithmus kann das Passwort ersetzbar werden. Wenn beispielsweise ein Passwort-Hash in wissenschaftlicher Notation in eine Zahl umgewandelt wird, stimmt er wahrscheinlich mit anderen Passwort-Hashes überein. Auf diese Weise besteht möglicherweise auch ein völlig anderes Passwort die Überprüfung des Systems. Interessant ist jedoch, dass Sie beim Vergleich bestimmter Zahlen in wissenschaftlicher Notation möglicherweise überrascht sind:
import random import hashlib import re import string import sys prof = re.compile("^0+ed*$") # you can also consider: re.compile("^d*e0+$") prefix = string.lower(sys.argv[1])+'!'+string.upper(sys.argv[1])+"%s" num=0 while True: num+=1 b = hashlib.sha256(prefix % num).hexdigest() if (b[0]=='0' and prof.match(b)): print(prefix+str(num),b)Zu diesem Zweck habe ich eigens ein Python-Skript geschrieben Obwohl ich keine großen Anstrengungen unternommen habe, um die Leistung dieses Skripts zu optimieren, läuft dieses gut geschriebene Skript mit Hilfe des PyPy-Compilers stabil auf allen verfügbaren CPU-Kernen meines AMD FX8350. Darüber hinaus habe ich auch die Hash-Funktion in der Hashlib-Bibliothek verwendet. Um das Problem der Prozesssynchronisierung von Python GIL zu vermeiden, habe ich auch einen unabhängigen Prozess zur Verarbeitung der Kennwortdaten generiert. Darüber hinaus habe ich eine sehr ausgefeilte Technik verwendet, um für jedes Passwort ein anderes Präfix zu generieren, wie im obigen Code gezeigt.
Die Berechnungsergebnisse von Passwörtern sind sehr ähnlich, wie unten gezeigt:
Sie können zwei Passwörter zufällig zum Vergleich auswählen Die Ergebnisse lauten wie folgt:
Wenn Sie die oben gezeigten Berechnungsergebnisse nicht erhalten können, können Sie sich glücklich schätzen. Sie könnten versuchen, den Benutzernamen und das Passwort zu bündeln und dann einen Hash-Algorithmus mit einem „Salt“-Wert zur Berechnung zu verwenden. Um dies zu erreichen, müssen Sie nur einen kleinen Teil des Codes ändern. Klicken Sie auf „Hier“, um das geänderte Skript zu erhalten.