Inhaltsverzeichnis
In diesem Beitrag stelle ich dir eine reflected XSS Sicherheitslücke auf der Lotteriewebsite tipp24.de vor. Zum damaligen Zeitpunkt war die Website noch unter der .com Domain zu erreichen.
Im Vorwort möchte ich direkt anmerken, dass der Support und die Entwickler der Website sehr professionell und schnell reagiert haben. So habe ich das selten von größeren Firmen gesehen. Teilweise muss man Wochen auf Antworten oder einen Fix warten.
Was ist tipp24.de?
Folgendes sagt Tipp24 über sich selber.
Tipp24 hat aktuell über 3 Millionen zufriedene Kunden und bisher mehr als 1,8 Milliarden Euro ausgezahlt. Ihre Tipps sind bei uns sicher, denn Tipp24 ist offizieller Partner von LOTTO und wir geben Ihre Spielscheine direkt bei den staatlichen Lotterien in Deutschland ab.
Quelle: tipp24.de/ueberuns
Mit mehr als drei Millionen Kunden und Gewinnausschüttungen im Gesamtwert von über 1,8 Milliarden Euro ist Tipp24 eine der größten Anbieter im deutschsprachigen Raum ist.
Die Lücke
Da ich nun Tipp24 vorgestellt habe, komme ich direkt zur von mir gefundenen Sicherheitslücke. Ich bin tatsächlich durch Zufall auf diese Lücke gestoßen. Ich wollte mich vom Newsletter der Website abmelden und habe direkt bemerkt, dass in der URL sehr viele Parameter angezeigt wurden.
So etwas ergibt zum Beispiel bei einer Suchfunktion Sinn, da man diese bestimmte Suche dann einfach als Lesezeichen im Browser speichern kann. Warum das ganze bei der Abmeldung eines Newsletters vonnöten ist? Ich gehe davon aus, dass es sich dabei um UTM-Tracking handeln muss.
Vereinfacht gesagt ermöglicht UTM-Tracking einem Webseitenbetreiber genau nachzuvollziehen, welche Kampagnen (z. B. Newsletter) besonders erfolgreich sind und welche nicht. Natürlich ist das sehr vereinfacht ausgedrückt.
Aber kommen wir zurück zur Sicherheitslücke. Der Link dazu ist folgender.
https://www.tipp24.com/abbestellen?type={UNSICHER}&authId=&advertisementId=&wt_mc=&wt_cc1=&wt_cc2=&wt_cc3=&partnerId=&M_BT=
Den damals unsicheren Parameter habe ich mit {UNSICHER} markiert. Die Inhalte der anderen Parameter habe ich für dieses Beispiel entfernt.
Mir ist relativ schnell aufgefallen, dass ein „Bad Guy“ relativ wenig mit dieser Lücke hätte anstellen können, da eine WAF installiert ist und dort gute Dienste leistet. Allerdings war es mir trotzdem möglich simplen HTML-Code auszuführen, was im klassischen Sinne eine aktive Sicherheitslücke (XSS) darstellt.
Meiner Meinung nach, hätte man mit dieser Lücke mehr Imageschaden verursachen können, als wirklichen Schaden bei den Nutzern der Website.
Im Prinzip wurde im Parameter type der Name des Newsletters gespeichert und auf der Website ausgegeben. Hätte ich dem Parameter den Wert „Faule Socke“ gegeben, würde auf der Website der Text „Leider konnten wir sie nicht von unserer Verteilerliste Faule Socke […]“ stehen. Mehr dazu weiter unten im Text.
Wie man erkennen kann, habe ich in der URL anstatt dem Namen des Newsletters mehrere HTML-Tags gegeben. Dazu zählen Zeilenumbrüche und verschiedene Überschriften, sodass man das auf der Website gut erkennen kann.
Wie kann man die Sicherheitslücke schließen?
Ich habe in meinem Report an den Support von Tipp24.de auch direkt beschrieben, wie man diese Sicherheitslücke schließen könnte. Die schnellste und einfachste Lösung wäre, die Parameter mit htmlspecialchars()
zu entschärfen.
Ich kann mir vorstellen, dass der Parameter in einer Variable – ich nenne diesen jetzt einfach „verteilerliste“ – gespeichert wird und dass der Quellcode der Website so lautet.
<p>Leider konnten wir Sie nicht aus unserer Verteilerliste <?php echo $verteilerliste; ?> austragen.</p>
Wenn wir jetzt htmlspecialchars()
anwenden, sieht das ganze so aus.
<p>Leider konnten wir Sie nicht aus unserer Verteilerliste <?php echo htmlspecialchars($verteilerliste); ?> austragen.</p>
Das wäre sicherlich die einfachste und etwas unschönere Variante. Es wird zwar kein HTML-Code mehr implementiert, aber trotzdem wird dieser als Name der Verteilerliste ausgegeben, was natürlich etwas unschön und definitiv sinnfrei ist.
Die ITler hinter Tipp24 haben die Lücke genauso geschlossen, wie ich Ihnen das vorgeschlagen hatte und das auch selber gemacht hätte. Allerdings bin ich mir sicher, dass die ITler da auch selber drauf gekommen wären.
Ich gehe einfach davon aus, dass die Verteilerlisten in einer der unzähligen Datenbanken gespeichert sind. Kurze Erklärung, warum ich von mehreren Datenbanken ausgehe? Ich gehe davon aus, weil es sehr, sehr verwerflich wäre, private Kundendaten, Kreditkarteninformationen, Handynummern und Adressen mit so etwas Banalem zu mischen. Das wird mit Sicherheit alles getrennt gespeichert.
Ich gehe also davon aus, dass die Verteilerlisten in einer eigenen Datenbank gespeichert sind. Ich würde nun also eine Abfrage starten, ob die Verteilerliste mit dem Namen aus der Variable „verteilerliste“ in der Datenbank vorhanden ist. Das kann man gefahrlos mit Prepared Statements realisieren.
PS: Dazu habe ich bereits einen Blogpost veröffentlicht. Das verbinde ich mit einer IF/ELSE-Bedingung. Wenn die Verteilerliste vorhanden ist, kann ich den Inhalt der Variable ohne Probleme auf der Website ausgeben. Sollte die Verteilerliste nicht vorhanden sein, gebe ich einen Standardtext aus. Das könnte zum Beispiel „Leider konnten wir Sie nicht von unserem Newsletter abmelden.“ sein.
Die Belohnung
Wie bereits gesagt, der Support und die ITler waren sehr schnell im Antworten und dem Schließen dieser Lücke. Neben einem Dankeschön per E-Mail gab es für mich noch einen Bonus, welchen man als Bug Bounty bezeichnet. Dieser besteht aus einem Spielguthaben von 20,00 EUR auf der Website. Das reicht mit Sicherheit für mehrere Lottoziehungen mit der Familie!
Das war es dann auch schon von mir. Sollte dir das Thema und dieser Beitrag gefallen haben, habe ich noch einen weiteren Artikel für dich. Dort habe ich eine XSS-Lücke bei heise.de entdeckt. Bis zum nächsten Mal – Maurice.