Inhaltsverzeichnis
Mit über 22 Millionen Besuchern pro Monat (Stand 2019) ist heise.de eine der meistbesuchten deutschsprachigen IT-Nachrichtenseiten. Auch ich kann bestätigen, dass heise.de mein bevorzugtes Medium ist, wenn es um IT & Technik geht.
Ich habe als fleißiger Leser des heise.de Redaktionsteams einfach mal aus Spaß ein bisschen rumgewerkelt, als ich das heise+ Abonnement abgeschlossen habe und hatte dort bereits nach ca. 10 Minuten mit einer gefundenen XSS-Lücke Erfolg.
Mir gelang es über einen ungesicherten Parameter (plenigo-affiliate-id) HTML und JavaScript einzuschleusen und diesen auch ausgeben zu lassen. Mit freundlicher Erlaubnis von heise.de darf ich diese Sicherheitslücke in diesem Beitrag vorstellen. Vorher aber noch eine kurze Erklärung, was eigentlich eine XSS-Lücke ist.
Was ist Cross-Site-Scripting?
Als Cross-Site-Scripting (kurz XSS), bezeichnet man Sicherheitslücken in Webanwendungen, die Nutzereingaben in einem Formular oder ähnliches nicht richtig filtern. Die übergebenen Daten werden ungefiltert und damit unsicher wieder dargestellt und bei korrekter Anwendung eines Schadcodes kann dort zum Beispiel HTML, JavaScript oder sonstiges ausgeführt werden.
Grundsätzlich unterscheidet man zwischen drei Arten von Cross-Site-Scripting. Reflected, persistent und DOM based. In diesem Artikel stelle ich dir jetzt eine echte reflected XSS-Lücke vor. Diese Lücke tritt nur auf, wenn in einem HTTP-Request Schadcode ungefiltert dargestellt wird.
Ich erkläre das kurz anhand eines Beispiels. Wenn also der Übergabeparameter text normalerweise nur deinen übermittelten Text übergibt, du dort aber einen HTML-Code ausgeben lässt und diesen Parameter dementsprechend abänderst, wird der Code implementiert und ausgeben.
So könnte in der URL sichereseite.de/schadcode.php?text=SichererText
der Wert des Parameters text folgendermaßen abgeändert werden: sichereseite.de/schadcode.php?text=<h1>XSS</h1>
! Wenn du dich ein wenig mit HTML auskennst, wirst du erkannt haben, dass hier auf der Seite schadcode.php eine Überschrift mit dem Inhalt „XSS“ ausgegeben wird. Kommen wir nun zur Praxis.
Praxisbeispiel – heise.de
Wie bereits in der Einleitung erwähnt, habe ich die XSS-Lücke während dem Abschließen meines heise+ Abonnements entdeckt. Der Parameter plenigo-affiliate-id war komplett ungesichert.
Plenigo ist ein Anbieter für cloudbasiertes Verwalten von Abonnements. Nicht nur die Heise Gruppe verwendet diesen Anbieter, sondern unter anderem auch der Spiegel! Dementsprechend kann man davon ausgehen, dass mehrere Nachrichtenseiten von der Sicherheitslücke betroffen waren.
Wie im Bild zu sehen, konnte ich relativ einfach eine Überschrift (<h1>XSS by Maurice Woitzyk</h1>
) und einen weiteren Absatz (<p>Das ist ein XSS Test</p>
) ausgeben lassen. Mir ging es im ersten Moment darum, erst einmal zu überprüfen, ob die Eingabe über den Parameter überhaupt gefiltert wird. Für mich gehört das zu den Grundlagen.
Tatsächlich brauchte ich keine 10 Minuten, um diese Lücke zu finden. Da ich immer versuche, die Grenzen auszutesten, habe ich ein wenig mit JavaScript herumgespielt. Allerdings handelt es sich hierbei nur um eine kleine Auswahl.
Anschließend bin ich etwas weitergegangen, da ich Probleme hatte normales JavaScript auszuführen, da dieses anscheinend entweder gefiltert oder falsch interpretiert wurde. Also habe ich etwas um die Eckt gedacht und wollte den gleichen Code über einen Trick ausgeben lassen.
Da HTML ohne Probleme interpretiert wird, dachte ich mir, dass eventuell der <script>
-Tag gefiltert wird. Aus diesem Grund habe ich mich für einen Link entschieden, welcher mit einem JavaScript-Event versehen war, sodass der erforderliche Code ausgeführt wird, sofern ich mit meiner Maus über den Link gehe.

onmouseover
Tatsächlich habe ich mit dem JavaScript-Event onmouseover
eine einfache Implementierung von JavaScript erreicht, was mir mit dem normalen <script>
-Tag nicht gelungen ist.
Hier sieht man wieder, dass es immer Mittel und Wege gibt. Man muss diese nur finden. In diesem Praxisbeispiel habe ich einfach alle Cookies ausgegeben, welche auf meinem Computer zu finden waren.
"><a onmouseover="alert(document.cookie)">xxs link</a>
In meinem letzten Beispiel habe ich das JavaScript-Event onerror
getriggert. In diesem Fall habe ich mit Absicht ein Bild falsch eingebunden, sodass ein Error entstand.
Da ich vorher ein Event definiert und beschrieben hatte, was dann passieren sollte, konnte ich auch hier einfach die Ausgabe von JavaScript-Code erzwingen. Allerdings hatte ich dieses Mal den Code nicht lesbar, sondern als Zeichencode definiert.
"><img src=/ onerror="alert(String.fromCharCode(88,83,83))">
Auch dieser Code wurde übersetzt und mittels Warnmeldung als Fenster im Browser ausgegeben.

onerror
mit ZeichencodeLogischerweise habe ich diese Lücke direkt an heise.de weitergeleitet. Tatsächlich wurde diese direkt am nächsten Tag geschlossen, indem ein Hotfix eingespielt wurde. Meinen Lob an der Stelle für die schnelle Reaktionszeit. Normalerweise dauert es nicht unerheblich länger, bis eine solche Sicherheitslücke an der richtigen Stelle angekommen ist.
Die Möglichkeiten für die „Bad Guys“ waren allerdings auch sehr begrenzt, sodass sich auch niemand groß Sorgen machen musste. Bei einer reflected XSS-Lücke muss der Nutzer entweder auf einen im Voraus präparierten Link klicken, oder diesen selber manipulieren.
Trotzdem ist es sehr wichtig, dass man auf solche Lücken hinweist. Schließlich könnte man selber auch etwas übersehen haben und der mögliche Schaden dadurch nicht unerheblich zunehmen.
Ich bedanke mich für deine Aufmerksamkeit und wünsche noch einen angenehmen Tag – dein Maurice.