Vorwort
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 Problems
Im Jahr 2011 entdeckte das offizielle PHP-Fehlerverfolgungssystem, dass beim Vergleich von Zeichenfolgen und Zahlen im Programm einige sehr seltsame Phänomene auftraten. Aus Sicherheitsgründen handelt es sich bei diesem Problem eigentlich nicht um ein Sicherheitsproblem. Sie können beispielsweise den folgenden Code sehen:
Tatsä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.
Gynvael hat einen klassischen Artikel zu diesem Thema geschrieben. Die vom PHP-Gleichheitszeichenoperator „==" abgedeckten Datentypen sind sehr umfangreich und enthalten einige Beispiele. wie folgt:
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:
Betrachten Sie dieses Problem aus der Perspektive des „Black-Box-Tests“
Aus der Perspektive der statischen Analyse erscheinen diese Sicherheitsprobleme etwas gewöhnlich. Wenn wir diese Probleme jedoch aus der Black-Box-Perspektive betrachten, welche Erkenntnisse können wir für jedes Benutzerkonto in der Anwendung gewinnen, wenn die Anwendung den gängigsten Hashing-Algorithmus (wie SHA1 und MD5) zur Verarbeitung von Passwörtern verwendet und Sie ihn verwenden? Der lose Vergleich von PHP bei der Überprüfung von Passwort-Hashes kann zu diesem Zeitpunkt zu Sicherheitsproblemen führen. Wir können nun einen typischen Penetrationstest betrachten. Sie können ein normales Konto erstellen, das Passwort auf eines der Passwörter mit einem ähnlichen Hashwert festlegen und sich dann mit dem anderen Passwort anmelden. Offensichtlich hängt die Sicherheit Ihres Systems vollständig vom verwendeten Hashing-Algorithmus ab. Vorausgesetzt, Sie verwenden in Ihrem Hashing-Algorithmus keinen „Salt“-Wert, müssen Sie für Ihre Passwörter mindestens zwei verschiedene Hashing-Algorithmen verwenden.
Bevor wir uns nun mit diesen Passwortkombinationen befassen, sollten wir auch eines bedenken – die Passwortanforderungen. Denn bevor wir diese Passwörter und Hash-Algorithmen analysieren, müssen wir zunächst sicherstellen, dass das von uns festgelegte Anfangspasswort die Anforderungen an die Passwortkomplexität erfüllt, andernfalls sind unsere Analysen und Recherchen bedeutungslos. Deshalb müssen wir sicherstellen, dass unser Passwort mindestens acht Zeichen lang ist und Groß- und Kleinbuchstaben, Zahlen und mindestens ein Sonderzeichen enthält: Die Details sind wie folgt:
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)
Nach dem Login kopieren
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.
Analyseergebnisse
Nach mehr als einer Stunde Analyse habe ich die SHA1-Werte der vier Passwörter erhalten. Zu meiner Überraschung dauerte es weniger Zeit, die MD5-Werte der vier Passwörter zu erhalten.
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.
Lösung
PHP bietet uns eine Lösung. Wenn Sie Hash-Werte vergleichen möchten, sollten Sie die Funktionen „password_verify()“ oder „hash_equals()“ verwenden. Sie führen strenge Datenvergleiche durch und eliminieren einige andere Störfaktoren. Bitte beachten Sie jedoch, dass die Funktion hash_equals() auch zum String-Vergleich verwendet werden kann.
Analyse-Schlussfolgerung
Obwohl unsere Analyseschritte etwas zu kompliziert in der Ausführung sind, kann Ihnen die von uns beschriebene Methode aus Sicht des Black-Box-Tests möglicherweise einige wertvolle Informationen liefern Informationen. Wenn das Passwort in einer Anwendung einen solchen Überprüfungsmechanismus verwendet, gehen die damit verbundenen Sicherheitsprobleme über die Probleme der PHP-Datentypkonvertierung selbst hinaus.
Das Problem geht weit darüber hinaus
Die Auswirkungen dieses Problems auf uns gehen weit darüber hinaus. Ein Angreifer kann diese Passwörter zu einer Wörterbuchdatei hinzufügen und dann einen Brute-Force-Angriff gegen alle Benutzer in der Anwendung durchführen. Wenn der Passwortwiederherstellungsmechanismus der Anwendung unsichere Faktoren aufweist, kann der Angreifer darüber hinaus unbegrenzte Angriffe auf das Zielkonto durchführen, bis der Angriff erfolgreich ist.