Content-Spoofing – Teil 3 – HTTP Redirects

Content-Spoofing - Redirects

Es gibt eine "versteckte Gefahr", von der viele Webentwickler gar nichts wissen.

Beim Herunterladen von Inhalten über URL's folgt ein mit PHP realisierter HTTP-Request standardmäßig bis zu 20 Weiterleitungen - das ist zum Beispiel beim Darstellen von Bildern, die auf externen Servern liegen, der Fall.

Wie Angreifer dies ausnutzen können, welche Gefahr dahinter steckt und wie man mehrere Redirects in PHP-Anwendungen verhindern kann, wird in diesem 3. Teil der Artikel-Serie "Content-Spoofing" demonstriert.

Redirects auf externen Servern

In vielen PHP-Anwendungen können u. A. Bilder in Form einer URL eingebunden werden. In Forensystemen werden dazu meistens BB-Tags verwendet, die anschließend von der PHP-Anwendung in HTML-Markup umgewandelt werden.

Beispiel:

[img]http://www.domain.tld/bild.jpg[/img]

Wird umgewandelt in:

<img src="http://www.domain.tld/bild.jpg" />

Wenn (wie in diesem Beispiel) eine Bilddatei dargestellt / heruntergeladen werden soll, sendet der Browser ein HTTP-Request an den Server. Daraufhin antwortet der Server mit einer HTTP-Response, in der unter anderem der Statuscode übergeben wird.

Der Statuscode 200 bedeutet zum Beispiel, dass die Anfrage erfolgreich bearbeitet wurde. In diesem Fall würde das Bild also ganz normal dargestellt werden.

Die Statuscodes sind im RFC 2616 spezifiziert.

Der Statuscode 301 steht für eine permanente Weiterleitung. Dies können Angreifer ausnutzen, indem sie auf dem Server, wo sich das Bild / die Datei befindet, eine Weiterleitung verursachen - z. B. mit einer htaccess-Datei (Mod Rewrite):

RewriteEngine On
RewriteRule ^bild.jpg$ http://evilsite.tld/evilcode.php [L,R=301]

Wenn nun die Datei "bild.jpg" aufgerufen wird, erfolgt eine Weiterleitung zu einer beliebigen URL - in diesem Beispiel eine PHP Datei auf dem Server des Angreifers.

Proof-Of-Concept

Um das ganze nun anhand eines PHP Scripts zu demonstrieren, werde ich keine BB-Tags in HTML-Markup umwandeln, sondern die URL einfach per GET-Parameter übergeben.

<?php
  $url = $_GET['url'];

  if(isset($url))
    echo "<img src='$url' />";
?>

Ein Aufruf könnte so aussehen:

http://www.domain.tld/vuln.php?url=http://evilsite.tld/bild.jpg

Oder in einem Forensystem mit BB-Tags:

[img]http://evilsite.tld/bild.jpg[/img]

In diesem Beispiel erfolgt eine Weiterleitung zu http://evilsite.tld/evilcode.php und der vorhandene Code wird ausgeführt. Angreifer könnten hier zu einer infizierten Webseite weiterleiten, bei der z. B. Sicherheitslücken im Browser ausgenutzt werden. Man würde in den meisten Fällen noch nicht mal etwas davon mitbekommen, da die Weiterleitung per HTTP-Request im Hintergrund stattfindet.

In Verbindung mit XSRF (Cross-Site Request Forgery) ist allerdings noch mehr möglich.

In Webanwendungen werden sehr häufig Daten per GET-Parameter übermittelt, die zu bestimmten Aktionen führen. Zum Beispiel zu einem Kauf in einem Online-Shop (sofern man dort eingeloggt ist) oder zum mehrmaligen Aufrufen der eigenen Werbeanzeigen, was zum Ausschluss beim Anbieter und somit zum Einnahmeverlust führen kann.

Gegenmaßnahmen

Wie bereits erwähnt folgt ein mit PHP realisierter HTTP-Request standardmäßig max. 20 Weiterleitungen, um eine Endlos-Schleife zu verhindern.

Um die maximale Anzahl der Weiterleitungen selbst festzulegen, kann man die Erweiterung cURL nutzen. Dort gibt es die Option CURLOPT_MAXREDIRS.

Im folgenden Beispiel werden die Daten der angeforderten Datei ausgelesen und in eine Variable gespeichert. Da die Option CURLOPT_MAXREDIRS auf 0 gesetzt wird, ist keine Weiterleitung möglich. Danach werden die Daten in eine lokale Datei "file.jpg" geschrieben.

Anschließend wird überprüft, ob es sich um eine valide Bilddatei handelt. Falls nicht, wird die Datei gelöscht und das Script beendet - andernfalls wird das Bild normal dargestellt.

<?php
  $url = $_GET['url'];

  if(isset($url))
  {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 0); // max. Anzahl von Redirects
    $data = curl_exec($ch); // Daten in Variable speichern
    curl_close($ch);

    $file = fopen('file.jpg', 'wb'); // Neue Datei (file.jpg) anlegen
    fwrite($file, $data); // Daten in Datei schreiben
    fclose($file);

    if(...) // Bildformat ueberpruefen!
    {
      unlink('file.jpg'); // Datei loeschen
      die('Fehler: Ungueltiges Bildformat!'); // Script beenden
    }

    echo "<img src='file.jpg' />";
  }
?>

Zusätzlich muss die übergebene URL so gut wie möglich überprüft werden, ansonsten würde dieser Schutz nichts bringen, da ein Angreifer einfach direkt die URL zur infizierten Webseite übergeben könnte. Besonders GET-Parameter sollten herausgefiltert werden, was zumindest viele potenzielle Angriffe verhindert.

Dir hat der Artikel gefallen? Dann abonniere doch einfach den RSS-Feed, damit du immer auf dem Laufenden bleibst und über neue Einträge kostenlos informiert wirst.

Diesen Artikel weiterempfehlen:
TwitterFacebookDeliciousTechnoratiMister WongWikio

Eine Reaktion zu “Content-Spoofing – Teil 3 – HTTP Redirects”

Kommentare (0)

Für diesen Artikel sind bisher nur Trackbacks vorhanden.

Kommentar hinterlassen