code beispiel? ist hier eine javascript code injection möglich

#0
10.07.2007, 16:36
...neu hier

Beiträge: 5
#1 Hallo erstmal...

Ich hätte da eine Frage. Vielleicht kann mir jemand weiterhelfen. Vor kurzer Zeit fand ich auf einer meiner Webseiten ein gehacktes Script. Da diese Seite wirklich nur aus ein paar Zeilen PHP Code bestand, und ebenso in keiner Datei auf der Webseite (mit grep überprüft) eine Datenübergabe sei es POST GET oder REQUEST statt fand, bleibt jetzt meine einzige Hoffnung ein javascript...

Zum Code: Das ganze ist ein stinkeinfache galerie (und in die Jahre gekommen), die der USER über ftp mit jpg-Bilder füllt. In dem Verzeichnis das er befüllt befindet sich ein Verzeichnis thumbs/ das Schreibrechte für php-code besitzt. Das php Script macht nun nichts anderes als alle jpg Dateien aus dem Verzeichnis zu lesen, wenn nicht vorhanden ein thumbnail im Ordner thumbs abspeichert, und einen html code erzeugt, der dann dargestellt wird:

php code - einlesen:
while(false !== ($file = readdir($handle)))
{
if(!is_dir($pfad.$file))
{
if(isjpg($file))
{
array_push($gallery,$file);
if(!is_file($thumbpfad.$file))
{
image_createThumb($pfad.$file,$thumbpfad.$file,110,110,$quality=90);
}
}
}
}


der erzeugte html code mit javascript-inhalten:
<table border="0" align="center" cellpadding="10" cellspacing="0">
<tr>
<td><a href="bilder/bild12.jpg" target="_blank" onclick="return wind('bilder/bild12.jpg',475,600);"><img src="bilder/bild12_small.jpg" width="159" height="223" border="0" /></a></td>
<td><a href="bilder/bild13" target="_blank" onclick="return wind('bilder/bild13.jpg',450,521);"><img src="bilder/bild13_small.jpg" width="166" height="232" border="0" /></a></td>
<td><a href="bilder/bild14.jpg" target="_blank" onclick="return wind('bilder/bild14.jpg',365,550);"><img src="bilder/bild14_small.jpg" width="166" height="232" border="0" /></a></td>

</tr>
</table>:


Das Javascript das hier aufgerufen wird sieht wie folgt aus:
function wind(bild,b,h)
{
b = b + 50;
h = h + 90;
OpenWindow=window.open("", "", "toolbar=no,resizable=yes,scrollbars=yes,menubar=no,height="+h+",width="+b);
OpenWindow.document.open();
OpenWindow.document.write("<html><head><title>TITEL</title></head>")
OpenWindow.document.write("<body bgcolor=black>")
OpenWindow.document.write("<center><img src='"+bild+"'><br>")
OpenWindow.document.write("</center></body>")
OpenWindow.document.write("</html>")
OpenWindow.document.close()
return false;
}


Meine Frage nun:
Ist es nun wirklich möglich ohne die Möglichkeit einer Benutzer-Eingabe diesen Javascript-Befehl:
onclick="return wind('verzeichnis/bild10.jpg',400,300);"
so zu manipulieren das er dann im neu geöffneten Fenster evtl. dieses img-tag schließt und dann z.b. php code ausführen kann? Hab lange getestet, und ich denke es wäre es möglich wenn man jetzt diesen String "verzeichnis/bild10.jpg" über javascript austauschen kann. Allerdings wie soll man das schaffen, wenn wirklich nur diese eine Javascript Funktion auf der Seite ist, und auch das php script keine benutzeingaben annimmt, sondern nur diesen Verzeichnisbaum ausliest?

Wenn man dies ausschliessen könnte, dann müßte ich ein Wort mit dem Hoster reden, da dann eventuell ich nenn es jetzt mal ein vhost übergreifendes Sicherheitsproblem da ist. obwohl ich gecheckt habe das die open-base_dir restriktion in php eingeschalten ist. Somit sollte doch von einem anderen vhost die Manipulation von Daten nicht möglich sein.

Also vielleicht kann mir jemand helfen. Es wäre schön wenn mir jemand die Bestätigung geben kann das dieses Script so nicht code-injection-tauglich ist. Laß mich natürlich gern eines anderen belehren...

grüße
gingebaker
Dieser Beitrag wurde am 10.07.2007 um 16:43 Uhr von gingebaker editiert.
Seitenanfang Seitenende
10.07.2007, 17:16
Member
Avatar TurnRstereO

Beiträge: 1543
#2

Zitat

gingebaker postete
....
Zum Code: Das ganze ist ein stinkeinfache galerie (und in die Jahre gekommen), die der USER über ftp mit jpg-Bilder füllt. In dem Verzeichnis das er befüllt befindet sich ein Verzeichnis thumbs/ das Schreibrechte für php-code besitzt. Das php Script macht nun nichts anderes als alle jpg Dateien aus dem Verzeichnis zu lesen, wenn nicht vorhanden ein thumbnail im Ordner thumbs abspeichert, und einen html code erzeugt, der dann dargestellt wird:
.....
Grüsse!

Irgendwie tu ich mich gerade schwer mit Deinem Code.
Mag das deshalb auch gar nicht beurteilen.
Aber wenn man schon Energie in die Absicherung reinsteckt:

Ich persönlich würde auf "gültige" Namen eines Bildes noch überprüfen und eine maximale Grösse für Bilder zulassen.

Viel Glück damit, ich hoffe jemand anderes kann dazu noch was sagen.

TS
Seitenanfang Seitenende
11.07.2007, 22:02
Member
Avatar ischtar

Beiträge: 157
#3 Per Script denke ich nicht. Wobei du schon per PHP exec und solche Scherze machen kannst. Aber wie siehts denn mit dem bösen safe_mode aus?
__________
Zahme Vögel singen von Freiheit, wilde Vögel fliegen. ^y^
"Wer Sicherheit der Freiheit vorzieht ist zu Recht ein Sklave." - Aristoteles
Seitenanfang Seitenende
12.07.2007, 08:41
...neu hier

Themenstarter

Beiträge: 5
#4 Vielen Dank für den Tipp mit exec. Diese Kommandos sind auf dem server alle eingeschalten gewesen. Diese direkten Linux-Kommandos halten sich ja nicht an die open_base_dir und können somit ja weiter in ein offenes Verzeichnis eines anderen vhosts schreiben (lieg ich da richtig?). Jetzt hab ich gleich mal veranlaßt das diese gefährlichen Systemfunktionen die ja eigentlich in seltenen Fällen verwendet werden global in der php.ini ausgeschalten wurden:
disable_functions = exec, passthru, popen, proc_open, shell_exec, show_source, system

Ich hoffe das war die Lücke. Wobei wenns so sein sollte die wirkliche Lücke ja auf irgendeinem anderen vhost liegt, aber jetzt hoffentlich nur noch diesen einen Schaden zufügen kann...

Vielen Dank für die Hilfe!
Seitenanfang Seitenende
12.07.2007, 10:36
Member
Avatar ischtar

Beiträge: 157
#5 gingebaker: exec heisst Konsole, heisst zugriff. Könnte Bruteforce oder sonstwas heissen. Aber vhost-Übergreifend würde das vermutlich nicht einfach so gehen. Weil vhosts ja eigentlich in einer change root liegen, denk ich. Klar, mit exec auf dem Muttersystem ist dir alles möglich und ja, unter gewissen Umständen kannst du vermutlich auch auf das Muttersystem und die Schwestersysteme (ich nenne die benachbarten vhosts jetzt mal so) kommen. Es ist aber schwer extern jetzt zu sagen; ja daran lags, oder ja ist möglich, weil die Systeme imho zu komplex sind für Kochbuchrezepte ;). Ich hoffe du verstehst was ich meine und ich hoffe ebenso dein VHost nun secure ist. Schau dir aber noch den save_mod an. Ich finde ihn nicht unwichtig, weil er uid checks macht. Und überprüfe besser noch ob deine Gallery nur bestimmte Dateiendungen zulässt und dabei den Filetyp und nicht nur die Endung berücksichtigt.
__________
Zahme Vögel singen von Freiheit, wilde Vögel fliegen. ^y^
"Wer Sicherheit der Freiheit vorzieht ist zu Recht ein Sklave." - Aristoteles
Seitenanfang Seitenende
12.07.2007, 11:35
...neu hier

Themenstarter

Beiträge: 5
#6 Hi ischtar

Also ich kenn den Befehl exec. Is paarmal ganz praktisch für Befehle wie tar oder so wenn man keinen shell-zugriff hat. Allerdings zu dem Schluß gekommen das es mit exec gehen würde bin ich durch den Absatz dieses Artikel gekommen:
Über die Funktionen »system«, »exec«, »shell_exec« und »passthru« starten PHP-Skripte externe Linux-Kommandos. Diese Shell-Befehle laufen mit den Rechten des Webservers, da PHP als Modul in den Daemon integriert ist. Die PHP-Funktionen sind auf einem normalen Webserver nur selten notwendig, fast jedes PHP-Skript kommt ohne Linux-Kommandos aus.
Zitat von: http://www.linux-magazin.de/heft_abo/ausgaben/2004/10/airbag_fuer_den_webserver

Wenn die Befehle wie in dem Absatz beschrieben tatsächlich mit den Rechten des Webservers laufen, und php wie bei meinem Host unter gleichem Benutzer wie der Webserver läuft, dann sollte man vorausgesetzt man findet den relativen Pfad zu einem Verzeichnis in einem anderen vhost (das schreibrechte für php besitzt) doch in der Lage sein hier eine Datei anzulegen oder? Also ich habs nicht ausprobiert, aber theorethisch klingts für mich einleuchtend.

Der safe_mode ist bei mir ausgeschalten. Einfach aus dem Grund da ich mich nicht wirklich damit befaßt habe, da ich meist schlechte Kritiken darüber gehört habe, und ich glaube das auch Zugriffs-Probleme mit den Dateirechten (php anderer Benutzer als Ftp) entstehen. Steht auch was in diesem oben genannten Artikel.

Das mit den Dateiendungen wird überpürft. Es werden nur Endungen mit jpg oder jpeg durchgelassen. Das überprüf ich mit dieser Funktion:

function isjpg($Filename)
{
$Extension = explode (".", $Filename);
$Extension_i = (count($Extension) - 1);
$ext = strtolower($Extension[$Extension_i]);
if($ext == "jpg" || $ext == "jpeg")
return true;
else
return false;
}

Diese Funktion kann man mit manipulierten Dateinamen wohl nicht knacken oder...
Seitenanfang Seitenende
12.07.2007, 13:15
Member
Avatar ischtar

Beiträge: 157
#7 Einige Gallerys zicken mit save_mod leider ...

Zum Thema Dateiendungen: du überprüfst nur die Endungen, nicht die Filetypen. Wenn nun jemand Böses eine Bilddatei mit manipuliertem Header schickt, oder was anderes als ne Bilddatei oder ne "foo.bar.php.jpg" dann war's das. Der Befehl explode zerhackt dir ja nur deinen String. Das extrem gemeine an deinem Code ist ja, dass er genau mein Beispiel noch doppelt unterstützt. Pass auf:

$lieb = "sonnenschein.jpg";
$evil= "unwetter.php.jpg";

werden hochgeladen.

explode wird aktiv:

$Extension = explode (".", $lieb);

=> $Extension[0]="sonnenschein";
$Extension[1]="jpg";

$Extension_i = (count($Extension) - 1);

entspricht einer 1, also der $Extension[1].

da steht jpg drin und das script freut sich.

Nun zum Unwetter:

$Extension = explode (".", $evil);

=> $Extension[0]="unwetter";
$Extension[1]="php";
$Extension[2]="jpg";
ergo 1, 2, 3 in count.

$Extension_i = (count($Extension) - 1);

entspricht einer 2, also der $Extension[2].

da steht jpg drin und das script freut sich.

Und wäre ich ein wenig böser, würde ich das auch tun, denn schliesslich interessiert bei $evil den Server je nach config das jpg nicht mehr .....

Anderes, wenn es schon so sein muss:

anstelle des

$Extension_i = (count($Extension) - 1);

ein:

$Extension_i = $Extension[1];

ok, wer dann ein:

"ich.bin.ein.held.jpg" als Bildnamen angibt, hatte Pech, aber wer braucht das?

bei:

"boese.jpg.php" würde dann durchfliegen.


Besser ist es, echt nach Filetypen zu schauen. Umbenennen und fertig.

Das kann beides böse ins Auge gehen.

Zumal beim parsen auch je nach config gefundes php/sh/perl ausgeführt werden kann

Greetz
__________
Zahme Vögel singen von Freiheit, wilde Vögel fliegen. ^y^
"Wer Sicherheit der Freiheit vorzieht ist zu Recht ein Sklave." - Aristoteles
Dieser Beitrag wurde am 12.07.2007 um 13:37 Uhr von ischtar editiert.
Seitenanfang Seitenende
12.07.2007, 14:10
...neu hier

Themenstarter

Beiträge: 5
#8 Hi

Ja das versteh ich auch alles. Aber ich hab noch nie nen Server gesehen bei dem ein z.b.: "unwetter.php.jpg" dann als php Datei geparst wird. Wenn in dieser nach dem Namen ja eindeutigen jpg Datei dann auch PHP-Code drinnen stehen würde, dann würde Apache diese Datei wohl auch als jpg parsen, und der Code käme nie zum php-Parser. Ist doch so oder?
Anders wäre es wenn man nur auf Filetypen bzw. Mime-Typen prüft und nicht auf Dateiendungen. dann könnte evtl. ein "unwetter.php" auf dem Server landen die mit einem verfälschten Header als jpg Datei durch die Überprüfung gekommen ist.

Irgendwie stellt sich dann die Frage wie Apache die Dateien prüft. Prüft der auf Filetypen bzw.MimeTypen oder prüft er auf Datei-Endungen? Ich hab bis jetzt geglaubt der prüft auf Dateiendungen!?
Seitenanfang Seitenende
12.07.2007, 14:25
Member
Avatar ischtar

Beiträge: 157
#9 Jein. Als php speichert er sie klar nicht, aber der Fileheader entscheidet. Und da kann es dir unter Umständen passieren dass eben ein Verzeichnis höher gesprungen wird und/oder Code executable wird. Mir sind da leider unbeabsichtigt schon krasse Dinge passiert.

Wie der Apache damit umgeht reguliert mod_mime bzw TypesConfig. mod_mime_magic hingegen arbeite ähnlich wie der Unix file Befehl und checked selbst durch um was es sich handelt. Da spielen zig Faktoren rein. Ich weiß es schlichtweg nicht 100%. Ich kann dir nur sagen das Script ist so eine grobe Sicherheitslücke aus den oben genannten Gründen. Der Teufel ist ein Eichhörnchen mit Namen Murpy ;).

Achso ja, und früher war es eben nicht gewährleistet dass die letzte Dateiextension verwendet wird. Sollte heute anders sein, Betonung liegt auf sollte ... ist es aber auch im Normalfall. Wobei es auch wieder eine Sache ist wie der Browser das auffasst und wie es der Server auffasst.
__________
Zahme Vögel singen von Freiheit, wilde Vögel fliegen. ^y^
"Wer Sicherheit der Freiheit vorzieht ist zu Recht ein Sklave." - Aristoteles
Seitenanfang Seitenende
12.07.2007, 18:18
...neu hier

Themenstarter

Beiträge: 5
#10 Okay in diesem Sinne werd ich noch ne Prüfung einbauen. Eine Mime Typ - Prüfung und evtl. einen Test durch getimagesize(). Dann sollt ich mir halbwegs sicher sein das es dann vielleicht unter Umständen doch wirklich eine Image-Datei ist...

danke für die Infos und alles
gingebaker
Seitenanfang Seitenende
12.07.2007, 20:27
Member
Avatar ischtar

Beiträge: 157
#11 Gerne, aber ich bin halt euch kein Apache Profi ;) Viel Erfolg!
__________
Zahme Vögel singen von Freiheit, wilde Vögel fliegen. ^y^
"Wer Sicherheit der Freiheit vorzieht ist zu Recht ein Sklave." - Aristoteles
Seitenanfang Seitenende
Um auf dieses Thema zu ANTWORTEN
bitte erst » hier kostenlos registrieren!!

Folgende Themen könnten Dich auch interessieren: