ubuntuusers.de

SQL-Injection

Status: Ungelöst | Ubuntu-Version: Ubuntu 21.04 (Hirsute Hippo)
Antworten |

tomovic

Avatar von tomovic

Anmeldungsdatum:
25. August 2013

Beiträge: 238

hallo, ich möchte gerne meine Webseite auf SQL-Injection absichern, deswegen ziehe ich mir gerade ein paar Tuts rein

1
2
3
4
5
6
7
$stmt = $db->prepare("SELECT username FORM users WHERE username = ? AND passowrd = ?");
   
   $myusername = $_POST['username'];
   
   $mypassword = $_POST['password'];
   
  $stmt->bind_param("ss",$myusername,$mypassword); // geht nicht ?!

... Ist die letzte Zeile veraltet? Mit welche PHP Version kann ich das testen?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$myusername = mysqli_real_escape_string($db,$_POST['username']);
$mypassword = mysqli_real_escape_string($db,$_POST['password']);

    $sql = "SELECT username FROM `pinuser` WHERE username = '".$myusername."' AND pin='".$mypassword."'";
    
    $result = mysqli_query($db,$sql);
    
         $count = mysqli_num_rows($result);
        
        
        if($count >= 1) 
        {
        
            //header("localhost: welcome.php");
            echo("yes man");
            
        }
        else
        {
         
            echo("Your Login Name or PAssword is invald");
            
        }

Password 1234 geht ohne Probleme, andere Passwöter gehen nicht. Mit dem User test und Password Injektion → 1 OR 1 = 1<- Sollte ich zugang bekommen?! Geht aber nicht. Gibts in der PHP Version 7.4 eine Änderung?

Moderiert von sebix:

Thema in einen passenden Forenbereich verschoben. Bitte beachte die als wichtig markierten Themen („Welche Themen gehören hier her und welche nicht?“) in jedem Forenbereich. Danke.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

tomovic schrieb:

hallo, ich möchte gerne meine Webseite auf SQL-Injection absichern, deswegen ziehe ich mir gerade ein paar Tuts rein

1
2
3
4
5
6
7
$stmt = $db->prepare("SELECT username FORM users WHERE username = ? AND passowrd = ?");
   
   $myusername = $_POST['username'];
   
   $mypassword = $_POST['password'];
   
  $stmt->bind_param("ss",$myusername,$mypassword); // geht nicht ?!

Da sind Buchstabendreher im SQL-Statement FORM statt FROM und passorwd statt password... - aber falls es nicht daran liegt:

Führst du das Prepared Statement denn auch noch irgendwann aus und warum lässt du die Anzahl der Treffer nicht direkt von der Datenbank zählen? Ich würde mal sowas in der Art versuchen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
   $stmt = $db->prepare("SELECT COUNT(username) FROM users WHERE username = ? AND passowrd = ?");
   
   $myusername = $_POST['username'];
   $mypassword = $_POST['password'];
   
   $stmt->bind_param("ss", $myusername, $mypassword);
   $stmt->execute();
   $stmt->bind_result($n_matches);
   $stmt->fetch();
   echo 'Number of matches for given username and password: '.$n_matches;
   $stmt->close();

PS: Ein ungehashtes Passwort ohne Salz und Pfeffer klingt nach einem Rezept für ein Disaster...

tomovic

(Themenstarter)
Avatar von tomovic

Anmeldungsdatum:
25. August 2013

Beiträge: 238

thx, ja, da sind Tippfehler drin.Ich habe Sie korigiert und es läuft.

Quell Teil 2, Der Author demonstriert, Zeichen werden unterdrückt für SQL Injektion.Deswegen gibt er als Password ein: 1 OR 1 = 1 ... und es kommt Password richtig ?! Geht das vielleicht mit einer alten PHP Version?

DJKUhpisse Team-Icon

Supporter, Wikiteam
Avatar von DJKUhpisse

Anmeldungsdatum:
18. Oktober 2016

Beiträge: 18222

Wohnort: in deinem Browser, hier auf dem Bildschirm

Das Konzept von SQL-Injection ist, dass ein Teil deiner SQL-Abfragen aus Daten besteht, die der Benutzer selbst eingibt (z.B. in ein Feld) und die dann zu einer SQL-Abfrage zusammengesetzt werden. Einfaches Beispiel Suche nach einem Benutzer in einer Tabelle mit einem Feld. Dann wird bei dir der Befehl zusammengebastelt.

1
SELECT * FROM benutzer WHERE vorname like <Feldinhalt>;

Der Inhalt kann jetzt so aussehen: Franz

1
Franz; DROP table benutzer;

Im letzteren Fall würde der dann unterm Strich 2 Befehle ausführen. Daher gibt es da 2 wichtige Dinge zur Eingrenzung von sowas: Mehrerer DB-User, die jeweils nur die wirklich notwendigen Rechte auf die DB haben (eine Abfrage muss z.B. nichts schrieben können, der drop würde dann schon nicht gehen). Dann, ggf. selbst bauen oder fremde Software für nutzen, um die Eingabe zu prüfen. Ggf. auf Serverseite (nicht per JS beim Client!) nur bestimmte Zeichen im Feld erlauben, dann wird das mit der Verkettung schwieriger.

Bearbeitet von rklm:

Codeblock repariert. Bitte nutze die Vorschaufunktion!

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

tomovic schrieb:

Quell Teil 2, Der Author demonstriert,

Wer demonstriert da was wo und womit?

Schau dir doch einfach an, wie die zusammengesetzte SQL-Abfrage aussieht, bevor sie an die Datenbank geht - in deinem Fall wird der Inhalt von $mypassword mit Singlequotes umschlossen, so dass da so etwas dabei raus kommen dürfte:

1
SELECT username FROM `pinuser` WHERE WHERE username = 'foo' AND password='1 OR 1=1'

Die nächste Idee wäre dann als Passwort 1' OR 1 nutzen, was wegen mysqli_real_escape_string() ebenfalls nicht klappt, weil der Singlequote escaped wird:

1
SELECT username FROM `pinuser` WHERE username = 'foo' AND password='1\' OR 1=1'

Früher (so bis PHP5.3) gab es da wohl mal einigen Unsinn mit möglichen Konfigurationen für magic_quotes (https://durak.org/sean/pubs/software/php-7.0.0/info.configuration.html#ini.magic-quotes-gpc, https://durak.org/sean/pubs/software/php-7.0.0/sybase.configuration.html#ini.magic-quotes-sybase), was aber bei neueren Versionen wohl ersatzlos gestrichen wurde, weil es zu mehr Angriffsfläche führt.

Antworten |