Entwickler-Ecke

Programmiersprachen (Server) - MySQL-Injection - proof of concept


Narses - Di 30.06.15 22:21
Titel: MySQL-Injection - proof of concept
Moin!

Ich habe hier mal für unseren Azubi, der gerade mit PHP zu gange ist, eine proof-of-concept MySQL-Injection Demo schrauben wollen - aber, das geht schlicht und ergreifend mit den aktuellen Versionen nicht. :? Oder doch? :gruebel: :nixweiss:

Gegeben ist folgender Code (vom Azubi, von mir natürlich sofort als "gefährdet" bezeichnet):

PHP-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
$link = mysql_connect('localhost''user''pass'or die(": " . mysql_error());
$db_selected = mysql_select_db('demo'$link);

$spieler = $_POST['spieler'];
$id = $_POST['id'];

if ($spieler != "") {
  $result = mysql_query("UPDATE demo SET spieler = '$spieler' WHERE id = '$id'");
}

Ich bastle jetzt verzweifelt an einem Fake-Post-Form, in dem ich versuche ein zweites Kommando in den SQL-String zu injecten. Aber: das klappt nicht. :evil: Nach viel gesuche und Doku wälzen: PHP erlaubt mit mysql_query() schlicht nur ein Kommando. Punkt. :|

Frage: Abgesehen davon, dass man das Query natürlich mit passenden Werten dazu bringen kann, andere, als die beabsichtigten Daten zu ändern, ein klassisches xkcd-like "DROP TABLE" anzuhängen ist damit nicht drin. Mir gelingt´s jedenfalls nicht. :? Ist das tatsächlich (multi-query-)safe? :shock:

cu
Narses


Delete - Mi 01.07.15 10:39

- Nachträglich durch die Entwickler-Ecke gelöscht -


Narses - Mi 01.07.15 15:03

Moin!

Danke für´s Mitdenken. :beer:

Klar würde es damit gehen - das ist aber nicht der Ansatz. :P Du gehst ja auch nicht hin und fragst einen WebApp-Entwickler, ob er nicht mal eine andere Query-Funktion nutzen könnte, weil du seine App sonst nicht gehacked kriegst... 8) :zwinker:

Genau genommen geht es darum, dass es in der Realität mit den aktuellen PHP-"Bordmitteln" bereits keine Query-Injection in Form von Multi-Queries mehr geben kann. Oder doch, und ich mache es nur "nicht richtig"? :nixweiss:

Es läuft natürlich am Ende des Tages darauf hinaus, dass der Azubi sagt "das ist safe" :schmoll: und ich beweisen muss, dass es das nicht ist. :? Oder zugeben, dass es doch "safe" ist... :( (brech ich mir keinen aus der Krone bei ab, aber das gibt der ganzen "SQL-Injection"-Diskussion eine andere Dimension, weil es dann "nur noch" akademisch ist)

cu
Narses


FinnO - Mi 01.07.15 19:57

Moin,

man kann das UPDATE ... SET nicht besonders gut attackieren, aber es geht ;)

Ich habe das Beispiel leicht modifiziert, damit ich besser probieren kann (GET-Parameter, keine Anführungszeichen um ID), aber es ist quasi original:


PHP-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
<?php
$link = mysql_connect('localhost''root'''or die(": " . mysql_error());
$db_selected = mysql_select_db('demo'$link);

$spieler = $_GET['spieler'];
$id = $_GET['id'];

if ($spieler != "") {
  echo $query = "UPDATE `demo` SET `spieler` = '$spieler' WHERE id = $id";
  echo $result = mysql_query($query);
}


Mit den Parametern

Quelltext
1:
2:
3:
4:
spieler: YouGotHacked!' WHERE 1;#'
id: 1

als url: http://localhost/injection.php?spieler=YouGotHacked!%27%20WHERE%201;%23%27&id=1


Erhält man dann das Statement:

SQL-Anweisung
1:
UPDATE `demo` SET `spieler` = 'YouGotHacked!' WHERE 1;#'' WHERE id = 1                    


Und man kann alle Einträge in der Tabelle demo auf einmal ändern.

Gruß
Finn


Narses - Mi 01.07.15 22:17

Moin!

Auch dir danke für´s Mitdenken. :beer:

Dass man das Query selbst modifizieren kann ist klar, das hatte ich oben schon angedeutet. :nixweiss: Der Super-GAU ist aber das Einschleusen von zusätzlichen Queries. :hair:

Es scheint also tatsächlich der PHP-Crew gelungen zu sein, diese System-Lücke soweit abzudichten, dass dämliche PHP-Entwickler zumindest keine Scheunentore mehr offen lassen können. Immerhin. :|

Auch meine weiteren Versuche sind alle daran gescheitert, dass PHP (in dem o.g. Kontext) exakt ein Query akzeptiert (was vermutlich mit einer hart erzwungenen Connection-Option ohne multi-queries realisiert ist, da MySQL alles, was hinten dran hängt, als Syntaxproblem bezeichnet). :nixweiss: Ich gehe dann mal mangels eines funktionsfähigen Ansatzes davon aus, dass hier nur das bereits vorhandene SQL-Kommando als Ziel taugt.

cu
Narses


jfheins - Mi 01.07.15 22:58

Ja, solange du nicht gerade ein

PHP-Quelltext
1:
mysql_query($_GET["query"]);                    

drin hast, kann man keine beliebigen Abfragen ausführen.

Andererseits ist "einfache CRUD" Funktionalität (create, read, update, delete) ja doch oft vorhanden, womit man eigentlich nur die richtige Unterseite vor der Attacke auswählen muss. Nebenbei kann

PHP-Quelltext
1:
... or die(": " . mysql_error());                    

unter Umständen Datenbank-Interna ausplaudern. Oder ist das bei PHP inzwischen auch abgesichert und gibt Details nur an localhost?


Narses - Mi 01.07.15 23:23

Moin!

Danke für die Hinweise. :beer:

user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
kann man keine beliebigen Abfragen ausführen.
Ja, sowohl Doku als auch Recherche und eigene Versuche stützen diese Hypothese, (zumindest) das Loch ist zu (unter den genannten Bedingungen). :nixweiss:

user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Andererseits ist "einfache CRUD" Funktionalität (create, read, update, delete) ja doch oft vorhanden, womit man eigentlich nur die richtige Unterseite vor der Attacke auswählen muss.
Dass der Code ohne Escaping "kaputt" ist brauchen wir nicht diskutieren. :lol: Klar reicht einem pfiffigen Angreifer im schlimmsten Fall Query-Modification bereits voll aus. :P

Der "Witz" an der Sache ist in meinem konkreten didaktischen Rahmen, dass der xkcd-Strip [http://xkcd.com/327/] (leider) nicht mehr so einfach "geht" - was ein schöner Effekt gewesen wäre. :rofl:

user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Oder ist das bei PHP inzwischen auch abgesichert und gibt Details nur an localhost?
Ich gehe davon aus, dass wenn du das genau so hinschreibst, auch der bemängelte Query-Teil in der Ausgabe auftaucht. :nixweiss: Klar, sowas gehört auch in ein (DB-)Log, nicht in den Content.

cu
Narses