SQL Injection Beispiel und Verhindern – SQL / PHP im Login

SQL-Injection Beispiele- Steffen Lippke

Was ist eine SQL Injection?

Kann ich mich mit dieser Methode in jeden Account einloggen?

Ich zeige Dir, was eine SQL Injection ist und wie Du Schwachstellen im Login finden und ausbessern kannst.

Starten wir!

Was ist eine SQL Injection?

PHP ist Ursachen allen Übels
PHP ist die Ursachen allen Übels

Eine SQL Injection ist ein Teil einer SQL-Abfrage, die ein Krimineller in eine bestehende SQL-Abfrage über einwn Parameter einfügt. Die bestehende Abfrage ist in der Regel in einer PHP-Datei gespeichert und das ausgeführte Ergebnis bzw. die Auswirkungen sind für den Angreifer sichtbar.

Durch spezielle SQL-Abfragen kann ein Angreifer eine lesende SELECT-Anfrage in eine ändernde UPDATE oder DELETE Abfrage umwandeln, sodass der Angreifer jegliche Operationen auf der Datenbank ausführen kann, solange der technische SQL-Nutzer genügend Rechte hat.

Steffen Lippke

Die speziellen Abfrage Injections sehen auf den ersten Blick nicht aus wie ein normaler SQL-Befehl, weil diese die bestehende SQL adaptieren müssen. Dieses Tutorial zeigt Dir eine Variante, wie man Sicherheitslücken (Vulnerabilites) in einem Login finden kann und sich davor schützen kann.

Wie relevant ist die SQL Injection?

Bei den meisten, modernen Content Management Systemen (CMS) wie die kostenlose Blogsoftware WordPress oder Foren ist SQL-Injektion nicht mehr möglich, weil die notwendigen Schutzmechanismen in den PHP-Code standardmäßig implementiert sind.

Injections in WordPress gab es früher - heute fast nur noch in Plugins
Injections in WordPress gab es früher

Viele PHP-Programmier-Anfänger (und schlafende Profis) vergessen diese Sicherheitsmechanismen nicht und programmieren eine funktionale, aber ungeschützte Software.

Tipp: Tutorial Hacken lernen für Anfänger: In diesem Tutorial zeige ich Dir nicht nur, wie Du diese Sicherheitslücke findest, sondern auch, wie Du Dich als Webhoster gegen eine solche Attacke absichern kannst.

Steffen Lippke

Die dramatischen Auswirkungen einer Injektion

Angreifer können unter der Verwendung einer Kontonummer oder einer Nutzernummer in jedes Bankkonto bzw. Nutzerkonto mit dieser Technik einloggen. Unbemerkt kann der Angreifer Geld bewegen, ohne dass die Bank davon etwas mitbekommt.

In 2012 hat die Bank Barclays ermittelt, dass 97 % der IT-Sicherheitsvorfälle von SQL-Injektionen stammen. Die Betrugskosten belaufen sich auf 2,7 Milliarden Euro (2012, Sophie Curtis. Diese zahlen solltest Du nicht 100 % ernst nehmen, weil die Definition eines IT-Sicherheitsvorfalls nicht genormt ist. Trotzdem handelt es sich um einen beliebten Weg, wie Kriminelle in ein Unternehmen einbrechen (Angriffsvektor).

Login = Super einfach? Oder nicht?

Ein Login auf einer Webseite funktioniert nach dem folgenden Schema:

  1. Der Nutzer gibt seine / Ihre Anmeldedaten (Passwort und Benutzername) in die HTML-Eingabe-Felder ein
  2. Das Formular übergibt die Anmeldedaten an ein Anmelde-PHP-Skript über GET oder POST Parameter mit dem Klick auf den Button „Anmelden“.
  3. Einen SQL-Befehl vergleicht die Anmeldedaten mit den Passwort Hashs der registrierten Nutzer. Ein Webseitenbetreiber sollte kein Passwort als Klartext gespeichert sein, weil bei einem Hack diese für andere Account wiederverwendet werden könnten.
    1. Die Datenbank hat einen Account und mit dem passenden Passwort gefunden. Der SQL-Befehl war erfolgreich. Das Frontend zeigt dem Nutzer eine positive Rückmeldung an.
    2. Die Datenbank findet den Account nicht oder das Passwort stimmt nicht überein. Der SQL-Befehl liefert keine Ergebnisse und PHP gibt den Fehler bzw. das leere Ergebnis an das Frontend weiter.

Ablauf einer SQL Injection

Ein möglicher SQL-Befehl sieht so aus, wenn ein Login überprüft wird (vereinfachte Form):

SELECT * FROM accounts WHERE benutzername ='loginNutzer' AND password = 'loginPasswort'

Ich zeige Dir im nächsten Schritt ein Beispiel, wie ein normaler Login funktionieren sollte:

Ein Benutzername ist schnell gefunden
Ein Benutzername ist schnell gefunden

Zuerst brauchen wir einen Benutzernamen. Diesen finden wir bei jeden Kommentar auf einer Webseite oder in einem öffentlichen Profil.

Eine Zufällige Login Page
Login Page

Schauen wir uns den Login-Vorgang genauer an, indem wir das Netzwerk mit den Browser-Dev-Tools überwachen lassen. Das Programm Wireshark ermöglicht Dir die Analyse von Internet-Verkehr. Du kannst unverschlüsselte Nachrichten mitlesen oder Fehler finden und schließen. Dazu empfehle ich Dir das Wireshark Tutorial.

So überträgt der Browser Parameter

Mit dem gefundenen Namen melden wir uns an und verwenden irgendein Kennwort. Das Kennwort und der Benutzername überträgt der Browser mit einem POST-Parameter an ein PHP-Skript.

Die Logindaten werden mit Parametern übertragen
Die Logindaten werden mit Parametern übertragen

Wenn Du Deinen Netzwerk-Verkehr beobachten willst, dann habe ich ein Tutorial zur Überwachung von Internet-Traffic mit Wireshark für Anfänger vorbereitet

ATTACKE! – Universalpasswörter

f.loginNutzer und f.passwort sind die Credentials, die das PHP-Skript erhalten hat und fügt diese in den SQL Befehl ein. Der Trick ist es, ein Passwort zu generieren, welches die Prüflogik aushebelt:

  • AND password = 'loginPasswort'
  • loginPasswort => ' OR ' '='
  • benutzername => 'loginNutzer' AND password = '' OR ' '=' '

Der eingefügte String erzeugt eine neue Bedingung, die immer erfüllt sein wird. Die Verzweigung mit OR ermöglicht, dass nur 1 Bedingung erfüllt sein muss: ' '=' '

Werfen wir einen Blick auf einen ungeschützten Login, der „veraltet“ ist.

Ein ungeschützer normaler Login der anföllig auf SQL Injection ist
Ein ungeschützter normaler Login der anfällig auf SQL Injektion ist
Mit eine universal Login kann man die Login Page umgehen
Mit universalen Credential kann man den Login austricksen

So einfach kann man in ein Konto eindringen, welches einem nicht gehört.

Erfolg wir sind in dem Account
Erfolg wir sind in dem Account

Jetzt könnte der Kriminelle das Passwort ändern und sich ein eigenes aussuchen, sodass der wahre Besitzer auf das Konto nicht mehr zugreifen kann. Ändert der Nutzer noch die E-Mail-Adresse, ist der Account für immer weg.

Probiere mal diesen ungeschützten Login auf SQLzoon aus.

SQLZoons ist ein Muss
SQLZoons ist ein Muss

Hier kannst Du in den Login oben rechts Dich mit dem Nutzername „jake“ und als Universalpasswort ' OR ''='anmelden. Wenn Dir kein Nutzername bekannt ist, kannst Du das Universalpasswort als Nutzernamen verwenden.

Nicht immer funktioniert das Universalpasswort. Je nach Syntax und SQL-Variante brauchst Du ein anderes Universalpasswort. Ein erfahrener Hacker probiert bei manchen Logins 1000nde verschiedene Varianten aus. Dieses erfolgt automatisch über Skripts. Die Burp Suite bietet eine solche Option.

Sicherung vor Injections

Unser Ziel ist es, die Parameter zu schützen.

Die präparierten Strings kann ein Skript mit einer If-Anweisung auffangen, aber der Hacker kann auch kreativer sein und mehr OR Iterationen einbauen.

Was ist die Lösung für das Problem?

Sicherungsmaßnahme: Encoding!

Verbiete bei der Auswahl des Passworts Zeichen wie Anführungszeichen oder alle Sonderzeichen. Damit der Nutzer in Zukunft sichere Passwörter mit Sonderzeichen wählen kann, nutze eine Encodierung.

Fügt jemand etwas HTML in das Login-Eingabefeld ein, sieht das nach der Konvertierung so aus:

$new = htmlspecialchars("<a href='inject'>Best</a>", ENT_QUOTES);
echo $new; // &lt;a href=&#039;inject&#039;&gt;Best&lt;/a&gt;

Prepared Statements helfen Dir bei der Einfügung von Parametern:

$stmt = $dbh->prepare("INSERT INTO users (name, passwordhash) VALUES (?, ?)");
$stmt->bindParam(1, $name);

und dann ein execute:

$name = 'one';
$stmt->execute();

Zum Härten der PDO-Verbindung empfehle ich noch:

$conn= new PDO('mysql:dbname=dbtest;host=232.232.231;charset=utf8', 'user23423', 'password');

$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Moderne PHP-Frameworks wie Laravel erlauben kein Injections mehr, wenn diese nach den Best-Practices verwendet werden. Das Prinzip ist immer gleich:

Ein Hilfsfunktion encodiert Eingaben, sodass der Computer diese nie als gültiger SQL-Code interpretieren kann.

Steffen Lippke

Das Blocken von Injections ist der erste Teil. Eine API soll die Inhalte auf Länge, Typ, zulässige Werte und Format prüfen (Regex). Wenn der Angreifer 1.000.000.000 in die Orderanzahl einfügt, dann soll die Shop-Software nicht abstürzen oder die Finazsoftware Selbstmord begehn lassen. Hackbar ist das System jetzt nicht mehr, aber es fällt aus und andere Kunden können nicht mehr einkaufen (Schutzziel Verfügbarkeit)

Kommentare 4

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Jeden Monat teile ich mit Mitgliedern
4 neue praxisnahe Tutorials (je 1000+ Wörter).


Trage Deine Mail, damit Du
Deine Coding + Hacking Skills erweitern kannst!

Die Webseite nutzt nur technisch notwendige Cookies.