SQL-Injection

Hi,

ich betätige mich seit einigen Tagen als "penetration tester" und teste alle möglichen webseiten auf ihre sicherheit (natürlich nur brav wo ich das darf, z.b. hackthissite.org), ohne gefundene sicherheitslücken auszunutzen. dabei suche ich unter anderem nach lücken die die sog. SQL-Injection ermöglichen.

Bei Seiten mit Microsoft SQL Server (.asp) funktioniert das prima - ich footprinte durch anhängen von HAVING 1=1 an die url, und krieg dann brav spaltennamen geliefert, und meistens gibts tabellennamen gratis dazu. Wenn ich so gefootprintet habe, könnte ich alles machen - einträge verändern, löschen, einfügen, computer abstürzen lassen, c formatieren (naja dazu brauchts shell code). Man glaubt gar nicht was für Seiten dagegen anfällig sind! man muss nur mal in google nach ("Microsoft OLE DB Provider for ODBC Drivers error '80040e07'" -forum -"message board" -"SQL injection") oder so suchen, sehen und staunen.

Jetzt hab ich mir gedacht mal meinen localhorst (haha sparwitz der local Horst ist der sohn von der heißen brünette Ruth/root) zu checken (MYSQL und PHP), und ein mini-php-script aufgesetzt das eine eintrag auswählt und anzeigt. leider ist MYSQL nicht so sehr kommunikativ; gebe ich jetzt HAVING 1=1 ein, so krieg ich nur die meldung ich hätte einen fehler im SQL und solle mein handbuch checken. weis jemand wie man da trotzdem footprinten kann?

vielen dank, ZK
 
Hallo,
PHP ist die erste Programmiersprache, die intern eine Engine gegen solche Angriff hat.

1 Es wird immer nur 1 SQL Befehl ausgeführt.
Also SELECT * FROM tb WHERE id = '1';DELETE FROM tb;'

Dort würde nur SELECT funktionieren

2 Wenn magic_quotes_gpc auf ON steht, dann werden alle Daten die von dem Benutzer stammen, also $_POST, $_GET, $_COOKIE etc. werden diese Daten entsprechend maskiert, so wie es addslashes() es machen würde.

So würde aus der SELECT Abrage:
SELECT * FROM tb WHERE id = '1\';DELETE FROM tb;'
Und diese würde nur das Feld id= 1\';DELETE FROM tb; abfragen, da das eine einfache Anführungszeichen maskiert wurde.

Am besten du postest hier mal den gesamten SQL/PHP Code, denn sonst kann man dir nich wirklich weiter helfen ;)
 
@Elderan: kann man also pauschal sagen dass man bei PHP sicher ist vor MySQL-Codeinjections wenn magic_quotes_gpc auf on steht?
Dann hab ich noch ne Frage: ist es möglich mit einem PHP-File das durch eine ungesicherte Include Funktion eingebaut wurde in die Seite die Variablen auszulesen?
Meine bisherigen Versuche auf der eigenen HP die MySQL Daten auszulesen scheiterten zwar, aber das muss ja net heissen dass es net möglich ist...
Imrahil
 
Hallo,
kann man also pauschal sagen dass man bei PHP sicher ist vor MySQL-Codeinjections wenn magic_quotes_gpc auf on steht?

Nicht direkt.
Falls man es schafft, in die DB eine SQL Injection zu speichern (z.B. als Username), und aus der DB wird dann der Wert in einen SQL Befehl geschrieben, z.B. WHERE username = '$row->username', dann könnte man so den SQL Befehl manipulieren.

Also man speichert als username: 'OR 1#

Dann steht dort:
SELECT * FROM tb WHERE username =' ' OR 1#'

Allerdings kann man so keinen zweiten SQL Befehl ausführen.

Aber es ist natürlich viel Aufwendiger.
 
Naja tolle Abfragen die eigentlich nicht zulässig sind kann ich immerhin ausführen... und der Moral von der Geschichte ist mal wieder:

Das unsicherste Produkt (Microsoft SQL Server) ist das teuerst und das microsoftigste :D :D
 
Original von Zaireking
Das unsicherste Produkt (Microsoft SQL Server) ist das teuerst und das microsoftigste :D :D

LoL
Die Programmierer haben eben einen sehr guten Lohn bei MS. Irgendwie muss man diese Kosten ja abdecken. :D

Zum Thema.
Ich finde es ehrlich gesagt Mist das überhaupt SQL-Injections möglich sind und man nachhinein sein gecodetes Projekt danach absichern sollte.

Zum Thema habe ich hier noch sehr interessante Artikel gefunden:
http://www.heise.de/security/result.xhtml?url=/security/artikel/43175/0&burl=/security/artikel/43175
http://de.wikipedia.org/wiki/SQL-Injection
oder
http://www.google.de/search?hl=de&q=SQL-Injection&btnG=Google-Suche&meta=

Ich selbst arbeite mit einem MySQL-Server und sehe bei Wikipedia speziell die Angriffsform für ein CGI oder aspx, wo im Prinzip der SQL-Befehl in eine Variabel übergeben wird.
Jemand im Forum hatte hier glaube ich mal geschrieben, das er alle SQL-Zeichen abprüfen würde und sie per PHP herausfiltert. Wenn dann noch Befehel wie Update, Exec, Select usw. herausgefiltert werden ist es doch schon fast sicher. Oder?

Die Variabeln, die SQL-Abfragen oder andere Befehle beinhalten sind doch im PHP-Code versteckt und sollten meiner Meinung nach andere Variabeln(die nicht den selben Namen wie Spaltennamen tragen), das Postverfahren nutzen oder die Weitergabe per URL (?blabla=1234).

Für Leute die sich gerne als andere Nutzer ausgeben, gibt es doch schon eine Abhilfe mit Sessioncodes, die man z.B. im phpbb findet. Jede Session wird in einer Tabelle gespeichert und bekommt einen Zufallsgenerierten Sessioncode hinzugefügt, dazu steht dann noch die jeweilige IP. Mit dem Sessioncode werden dann die Weitergaben in der URL vorgenommen(?blabla=123gasdfe23fag), so erkennt der Server um welchen User es sich handelt und kann dementsprechend die Datenbankabfragen vornehmen. Dazu sollte man aber noch die IP prüfen und evtl. das Cookie.

Ansonsten sollte man bei Open-Source Anwendungen die SQL nutzen, die Möglichkeit für Prefixe/Präfixe(Vorsilben) nutzen. Diese werden dann vor Datenbankennamen/Tabellennamen/-Spalten gesetzt und machen es den Angreifer schwerer herauszufinden wie die Namen heißen. Aber wenn, dann sollten alle so eine Vorsilbe erhalten. Es bringt ja nichts, wenn man nur Tabellennamen damit kennzeichnet, denn wenn er den Namen der Datenbank kennt, kann er Drop Database machen und die Datenbank ist weg.

Wenn man das alles beachtet, kann doch kaum etwas schiefgehen - oder?
Außer natürlich der Angreifer nimmt sich ein Serverseitiges Sicherheitsleck vor - hackt z.B. den FTP-Server - wenn vorhanden.
 
Hallo,


Original von Zaireking
Das unsicherste Produkt (Microsoft SQL Server) ist das teuerst und das microsoftigste :D :D
Mal wieder eine total unqualifizierte Aussage
Microsoft sicherer als Oracle



man nachhinein sein gecodetes Projekt danach absichern sollte.
Eigentlich sollte man schon zu Beginn des Projectes bestimmte Aspekte beachten, denn im Nachhinein wirst du nie alle Lücken finden.

Jemand im Forum hatte hier glaube ich mal geschrieben, das er alle SQL-Zeichen abprüfen würde und sie per PHP herausfiltert. Wenn dann noch Befehel wie Update, Exec, Select usw. herausgefiltert werden ist es doch schon fast sicher. Oder?
Super Idee, und dann darf ich nicht mehr den Text 'MySQL hat ein neues UPDATE herrausgebracht' schreiben, da dies ja einen SQL Befehl beinhaltet.

Die Variabeln, die SQL-Abfragen oder andere Befehle beinhalten sind doch im PHP-Code versteckt und sollten meiner Meinung nach andere Variabeln(die nicht den selben Namen wie Spaltennamen tragen), das Postverfahren nutzen oder die Weitergabe per URL (?blabla=1234).
Trotz mehrmaligen lesens habe ich den Absatz nicht verstanden. Sätze in Klammer sollte etwas nur ergänzen und der Satz sollte grammatikalisch Sinnmachen, auch wenn man die Klammer entfernt.

"sollten meiner Meinung nach andere Variabeln, das Postverfahren nutzen ..." ?(




Ansonsten sollte man bei Open-Source Anwendungen die SQL nutzen, die Möglichkeit für Prefixe/Präfixe(Vorsilben) nutzen. [...] machen es den Angreifer schwerer herauszufinden wie die Namen heißen
"Security by Obscurity"
Erst selber über Mircosoft lästern, und dann selber solche Methoden vorschlagen....
Wie wäre es denn mit: "Secruity by Design"?




Wenn man das alles beachtet, kann doch kaum etwas schiefgehen - oder?
Du hast dann in etwa den gleichen Sicherheitsstand wie zuvor. Denn an das Prefix kommt man i.d.R. recht schnell dran, bzw. meistens muss man gar nicht wissen, wie die Tabellen heißen um sich per SQL Injection als Admin einzuloggen.

Außerdem kennst du ja bestimmt das Tool 'phpMyAdmin'? Wie kann denn das Tool bitte ermitteln, wie die Struktur der gesamten Datenbank ist, also welche DBs es gibt, welche Tabelle diesen enthalten und wie die Tabellen aufgebaut sind? Mit ganz normalen SQL Befehlen!
Und genau diese SQL Befehle kann man verwenden, um an die benötigten Informationen der Struktur zu gelangen.

denn wenn er den Namen der Datenbank kennt
Leider hat man meists nur auf Root Servern einfluss darauf, wie die Datenbank heißt.


Was wirklich hilft:
Vertraue keinen User-Eingaben.

Jede User-Eingabe muss maskiert werden, sprich ein ' muss zu ein \'.


Konkret kann das so aussiehen:
SELECT * FROM posts WHERE postid = '".mysql_escape_string($_GET['postid'])."'

Auch muss man aufpassen, dass man abgespeicherte Usereingaben richtig maskiert, z.B. den Username aus einer Tabelle:
SELECT * FROM posts WHERE username LIKE '$user_table->username'; (FALSCH)

Hier kann man die Funktionen mysql_escape_string oder addslashes verwenden. Aufpassen muss man aber, ob magic_quotes auf On oder Off steht, da dann die Eingabe ggf. doppelt maskiert wird. Dies muss man dann Softwaretechnisch lösen.

Eine weitere, sinnvolle Richtlinie ist, bei Variablen, wo man eine Zahl erwartet, z.B. bei postid, auch nur Zahlen zuzulassen.

Möglich könnte das so aussehen:
if(!is_numeric($postid = $_GET['postid'])) $postid = 0;
SELECT * FROM posts ....
 
Eigentlich sollte man schon zu Beginn des Projectes bestimmte Aspekte beachten, denn im Nachhinein wirst du nie alle Lücken finden.

Zu Beginn eines solchen Open-Source Projektes steht ja eine gründliche und übersichtliche Programmierung. Man kann z.B. Funktionen nutzen um nicht alles mehrmals zu schreiben usw.
So kannst du auch im nachhinein deine Security-Funktionen aufbauen. Aber es kommt immer darauf an was du Programmieren willst, da hilft es schon an manchen Stellen am Anfang etwas auf die Sicherheit zu achten.

Super Idee, und dann darf ich nicht mehr den Text 'MySQL hat ein neues UPDATE herrausgebracht' schreiben, da dies ja einen SQL Befehl beinhaltet.

Das was du meinst sind noch weitere Programmierfehler die auf einem zukommen können. Du musst ja nicht gleich jedes "Update" zensieren. Es kommt immer darauf an in welchen Zusammenhang es steht. Z.B. wer würde schreiben "Update+" oder Zusammen mit den SQL-Zeichen? Wenn du vielleicht meintest: "Es gibt ein neues Update+Bugfixes", dann kannst du das "+" auch durch ein "und" ersetzen. Solltest natürlich aufpassen, das du nicht bei Rechenoperationen das + herausfilterst. :D
Der Zusammenhang macht es. Also "Update" und "+" z.B.

Trotz mehrmaligen lesens habe ich den Absatz nicht verstanden. Sätze in Klammer sollte etwas nur ergänzen und der Satz sollte grammatikalisch Sinnmachen, auch wenn man die Klammer entfernt.

"sollten meiner Meinung nach andere Variabeln, das Postverfahren nutzen ..." ?(

Das was in den Klammern steht sollte dir ja auch helfen.
Was ich meinte, ist das Variabeln die Abfragen beinhalten nicht dazu genutzt werden sollten um in andere Dokumente - über das in Klammern genannte Übergabeverfahren- übergeben werden sollten. So das der Benutzer nicht sehen kann was in der Abfrage gemacht wird und diese schelcht beeinflussen kann. Das man somit mit Bausteinen arbeitet, die dann unter ein Prüfverfahren die Werte über die Urleingabe checken.


"Security by Obscurity"
Erst selber über Mircosoft lästern, und dann selber solche Methoden vorschlagen....
Wie wäre es denn mit: "Secruity by Design"?

Warum denn lästern, ich habe nur geschrieben das die Entwickler ein hohes Gehalt bekommen und die Kosten irgendwie abgedeckt werden.
 
Hallo,
Original von Prometheus
So kannst du auch im nachhinein deine Security-Funktionen aufbauen.
Das ist vollkommen der falsche Ansatz.

Das ist in etwa wie: Wozu brauche ich ein sicheres Betriebssytem, ich kauf mir eine schöne Desktop Firewall und dann ist der Rechner sicher.
Lieber schon direkt am Anfang bestimmte Sicherheitsrichtlinien definieren, und befolgen, damit die Software auch in der Tiefe sicher ist (bsp. OpenBSD).
Denn eine Sicherheitsfunktion lässt sich immer umgehen, denn diese setzt ja nur auf deine Software aus, kann sie an sich aber selber nicht verändern.


Aber es kommt immer darauf an was du Programmieren willst
Sobald andere Personen zugriff auf deine Anwendung bekommen, sollte man wie gesagt, bestimmte Sicherheitsrichtlinien befolgen.
Wenn du sie nur lokal verwendest, kannst du Programmieren wie du willst, sonst nicht.



Z.B. wer würde schreiben "Update+" oder Zusammen mit den SQL-Zeichen?
Also in diesem Thread finde ich jede Menge SQL Anweisungen, dennoch führten sie nicht zu einer SQL Injection.
Wenn jetzt jeder dieser Beiträge ausgefiltert worden wäre...


Wenn du vielleicht meintest: "Es gibt ein neues Update+Bugfixes", dann kannst du das "+" auch durch ein "und" ersetzen.
Super in einem Programmier-Forum wo soetwas durchaus vorkommt:
Code:
int changes = update+bugfixes+patches;
printf("Es gab %d Änderungen", changes);

Mit einem 'und' statt einem + werden sich alle fragen, was der Code soll.
Vorallem in englischen Foren sind Wörter wie update, delete, select, drop, alter, where etc. keine Seltenheit.

Und in welchem SQL Kommando kommt denn bitte ein + vor? Oder meinst du das + als Platzhalter für ein Space in der URL? Sollte man dann jedes Space durch ein 'und' ersetzen?


Desweiteren würde das überprüfen eines Textes auf solche Merkmale sehr lange dauern, welches deine Software schon bei wenigen Besuchern unbrauchbar macht. Außerdem wirst du es garantiert nicht hinbekommen, Texte so zu filtern, dass diese keine SQL Kommandos mehr enthalten können.

Viel besser ist das Maskieren von Anführungszeichen, so dass ein Value auch wirklich ein Value bleibt und nicht zu SQL Kommandos mutiert.
 
Hm, ja die Verarbeitungszeit ist auch so eine Sache.
Zu deinen Code. Ich wollte eher auf PHP aus und nicht auf C++, denoch weiß ich was du meintest.

Ich lasse es jetzt mal deinen Beitrag zu quoten und stelle mal folgende Frage:
Hast du evtl. noch weitere Vorschläge um mögliche Sicherheitslücken in SQL/PHP Scripten auszuschließen?
 
Das Escapen von Quotes reicht vollkommen aus, um alle möglichen SQL-Injections zu verhindern. Umständliches Filtern von Schlüsselworten ist ein Overhead, der keinerlei Sicherheitsgewinn bringt.


Ansonsten sollte man bei Open-Source Anwendungen die SQL nutzen, die Möglichkeit für Prefixe/Präfixe(Vorsilben) nutzen. Diese werden dann vor Datenbankennamen/Tabellennamen/-Spalten gesetzt und machen es den Angreifer schwerer herauszufinden wie die Namen heißen.
Präfixe sind eher dazu gedacht, dass es keine Namenskollisionen bei den Tabellen gibt, falls jemand beispielsweise auf einem Webspace nur eine einzige Datenbank zur Verfügung hat, damit aber gern mehrere Webanwendungen darauf anbieten möchte, die alle auf voneinander unabhängigen Tabellen operieren. Wenn man nun ein Board und ein Gästebuch hätte, und beide hätten eine Tabelle "user", dann könnte man ansonsten ja nur eins von beidem installieren. Hat man aber "board_user" und "gb_user" (und die Anwendungen wissen über die Präfixe bescheid), dann klappt das. Präfixe haben aber keinerlei Sicherheitsfunktion.


Zu PHP und SQL-Injections allgemein: Dadurch, dass mysql_query() nur einen einzelnen Query absetzen kann, ist es natürlich schwieriger, da zu manipulieren. Aber die erwähnte Möglichkeit mit "' OR 1 --" funktioniert dennoch, wenn man nicht die Benutzereingaben korrekt filtert. Ein Login wäre in dem Fall reichlich unsicher. Zudem kann man auch beliebige andere Daten aus Tabellen auslesen, denn man muss ja nicht in 2 Abfragen packen, wo auch eine reicht (JOIN und UNION macht's möglich)...


Der Thread gehört BTW eigentlich in "mein" Forum *g
 
Hallo,
also man kann sehr schnell Sicherheitslücken in seinen Script einbauen, und sofern man sich mit dem Thema nicht ausgiebig beschäftigt, finden sich garantiert Lücken in deinem Code.

Klassische Fälle sind Code und SQL Injection und XSS. Aber es ist doch weitaus komplizierter. Deswegen würde ich dir empfehlen, dich in dem Gebiet schlau zu lesen.

Evt. mal nach PHP Security Guide oder so suchen.

Hab mal das hier gefunden:
PHP Sec

Hab es nicht gelesen, aber evt. hilft es schon
 
Hi Leute,

ich hab folgende Website gefunden, auf der erklärt wird, wie man SQL Injections trotz addslashes & mysql_real_escape_string() nutzen kann.

Bypassing PHP functions

(MySQL 4.1.x before 4.1.20 and 5.0.x)
Bypassing addslashes() with GBK encoding

WHERE x = 0xbf27admin 0xbf27

Bypassing mysql_real_escape_string() with BIG5 or GBK

"injection string"
に関する追加情報:

Quelle

Ich nutze mysql_real_escape_string().

Wie wie kann ich mich dennoch vor diesen BIG5 oder GBK Zeichensätzen & den damit verbundenen SQL-Injection Lücken schützen?

Ich hab folgende kleine Funktion(en) gebastelt, um die Eingaben zu prüfen:

PHP:
<?

//functions.php

function prepare_input($str) {
        $str=trim($str);
	if(empty($str)) { return false; }
	//$str=preg_replace("@[^a-zA-Z0-9]@","",$str);
	// -----
	//Natürlich könnte alles außer 0-9,a-z & A-Z sperren,
	//allerdings sollen html Tags etc. nicht zwangsläufig bei allen Inputs gefiltert werden.
	//Für TinyMCE, meinen WYSIWYG Editor &  z.B. Benutzerpasswörter benötige ich beispielsweise noch Sonderzeichen & html Tags!
	
	$str=mysql_real_escape_string($str);
	return $str;
}

function prepare_http_vars($ary) {
	if(is_array($ary)) {
		while(list($k,$v)=each($ary)) {
			if(is_array($ary[$k])) { while(list($k2,$v2)=each($ary[$k])) { $ary[$k][$k2]=prepare_input($v2); } }
			else { $ary[$k]=prepare_input($v); }
		}
		@reset($ary);
	return $ary;
      }
}

function prepare_output($str,$allow=0) {
	$str=stripslashes($str);
	$str=wordwrap($str,80,"",1);
	if(!$allow) { $str=htmlentities($str); }
	//Javascript rausfiltern
	//JS deaktivieren - ich weiß, schließt noch nicht alle XSS Lücken, muss die Funktion noch erweitern - für Vorschläge bin ich natürlich auch dankbar :D
	if($allow=="html") {
		$str=str_replace("javascript","java script",$str);
		$str=preg_replace("'<script[^>]*?>.*?</script>'si","",$str);
	}
	return $str;
}

?>


<?

//index.php

//Da es magic_quotes in PHP 6 nicht mehr geben wird, sollte man gleich davon ausgehen, dass es nicht existiert
set_magic_quotes_runtime(0);

$_COOKIE=prepare_http_vars($_COOKIE);
$_POST=prepare_http_vars($_POST);
$_GET=prepare_http_vars($_GET);


//Bevor Variablen in DB gespeichert werden:

$test1=$_COOKIE['test1'];
$test2=$_POST['test2'];
$test3=$_GET['test3'];



//Ausgabe der Inhalte aus der DB

//kein html, kein JS für User Eingaben
$test1=prepare_output('test1');

//mit html - ohne JS für Admin Eingaben
$test2=prepare_output('test2',"html");

//allow all - nur bei Admin Eingaben - Achtung, XSS möglich
$test3=prepare_output('test3'"all");

?>


Schonmal Danke im voraus das Ihr euch die Zeit nehmt & den ganzen Codes lest :D Ich denke das Thema wird sicher viele interessieren. :rolleyes:

cya 8)


Edit:
Ich seh grad, dass die BIG5 Sonderzeichen ersetzt werden. Welche php Funktion erledigt dies bzw. wie muss ein solche Funktion aussehen? Dadurch sollte die SQL-Injection Lücke ja geschlossen werden, oder? :rolleyes:
 
Hallo ich habe einige Webseiten zum Themer SQL Injection gelesen, aber ich verstehe es noch nicht so ganz...

Muß ich " ' or 1=1-- " oder " ' or 1=1 --" eingeben? Ich habe als URL immer volgendes eingegeben " www.anysite.com/admin/login.php?id=0 ' or 1=1-- "
Aber es hat sich nie was verändert. Wie erkenne ich ob die HP gegen SQL injection geschützt ist?
 
Sorry Elderan,

aber wie kannst du diesen Heise-Artikel ernst nehmen?

Ein user hat das ganz gut zusammengefasst:

Unglaublicher Artikel.

Schon die Überschrift... eigentlich geht's um zwei Datenbanken, aber
die Überschrift generalisiert das mal eben auf zwei Konzerne.

Dann braucht man scheinbar einen "Experten", um Patches zu zählen.
Zumindest vor Pisa hätte das auch ein Grundschüler geschafft.
Und es werden nicht etwa Löcher gezählt, sondern vorgenommene
Reparaturen und dann behauptet, dass da wo mehr repariert wird, auch
mehr kaputt war, oder unsinniger noch: immer noch kaputt ist.
Genausogut kann ich die Zeilen Sourcecode zählen und einfach mal
behaupten; wo mehr Zeilen sind, sind statistisch auch mehr Bugs.
Macht mich das zum Experten? Wow!

Und ganz nebenbei wird dann erwähnt, dass der besagte Experte bei
einem der Produkte mitgarbeitet hat , von einem der Konzerne Geld
erhalten hat. Ja welch Überraschung. Dass Heise ebenfalls Geld von M$
erhält, sieht man an der vielen Werbung hier.
Naja, wie man an anderen Zeitungen sieht: unterstes Niveau muss sich
nicht schlecht auf die Auflage auswirken.
Nur die kleine Minderheit, die ernsthaft wissen möchte, welche
Datenbank welche Vor- und Nachteile hat, muss sich wohl eine andere
Informationsquelle suchen. Aber die bringen eh nicht genug Geld in
die Kasse.
 
Zurück
Oben