Der erste, oder zumindest der erste allgemein bekannt gewordene, Web-Wurm war der MySpace-Wurm Samy, der sich am 4. Oktober 2005 auf MySpace ausbreitete.
Samy Kamkar war der Meinung, zu wenig Freunde auf MySpace zu haben. Samy (der Wurm) sollte das ändern. Und tat das sehr erfolgreich. Ausgehend von Samy Kamkars Profilseite verbreitete sich der Wurm über eine persistente XSS-Schwachstelle in die Profilseiten der Besucher eines befallenen Profils. Über einen XMLHttpRequest wurde Samy zum Freund und 'Hero' des Besuchers gemacht und der Wurmcode in dessen Profilseite integriert. Innerhalb von 20 Stunden hatte Samy Kamkar mehr als 1 Million Freunde und Samy (der Wurm) entsprechend viele Profile verseucht. MySpace musste den Betrieb vorübergehend komplett einstellen, um den Wurm zu stoppen und alle befallenen Seiten zu reinigen.
Die folgende Beschreibung des MySpace-Wurms basiert auf Samy Kamkars eigener Beschreibung. Die Methoden, um MySpaces Filter zu umgehen, sehen inzwischen recht altmodisch aus. Der Wurm ist ja auch schon fast 10 Jahre alt.
Bei der Entwicklung musste Samy Kamkar einige Schutzmaßnahmen von MySpace und weitere Einschränkungen überwinden. Was ihm erfolgreich gelang, wie der Erfolg des Wurms eindrucksvoll bewies.
Den Sourcecode des Wurm finden Sie sowohl in der Originalformatierung als auch in einer angepassten, lesbareren Formatierung sowie in einer kommentierten Version mit "sprechenden" Variablennamen hier. In der Beschreibung ist das Wort "Code" teilweise mit den entsprechenden Quellen im Sourcecode verlinkt.
<script>-Tags, HREF-Tags mit JavaScript etc.. Nicht
gefiltert wurden jedoch CSS-Tags. Samy nutzte aus, das einige Browser wie
zum Beispiel der Internet Explorer und einige Safari-Versionen
JavaScript-Code in CSS-Tags auswerteten. Dadurch funktionierte der
Wurm-Code nicht in jedem Browser, aber es blieben genug potentielle Opfer
übrig.<div style="background:url('javascript:alert(1)')">
"javascript" überall aus - nicht aber
"java\nscript", was von einigen Browsern als
"javascript" interpretiert wird
(\n ist der Zeilenumbruch, Newline). <div style="background:url('java
script:alert(1)')">
<div>-Tags konnten keine
Quote-Zeichen verwendet werden, da sowohl ' als auch
" bereits verwendet wurden. Nun ist es ziemlich
schwierig, JavaScript ohne Quote-Zeichen zu programmieren. Als Ausweg hat
Samy Kamkar den JavaScript-Code in einem Ausdruck gespeichert und dann mit
dessen Namen aufgerufen und ausgeführt. Dadurch konnte das einfache
Quote-Zeichen (') verwendet werden. <div id="mycode" expr="alert('Hallo!')" style="background:url('java
script:eval(document.all.mycode.expr)')">') wurden auch
doppelte Quote-Zeichen (") benötigt. Das escapen
(zum Beispiel foo\"bar) funktionierte nicht, da
MySpace alle maskierten Quote-Zeichen ausfilterte. Als Ausweg hat Samy
Kamkar die doppelten Quote-Zeichen mit der Funktion
String.fromCharCode() aus ihrem Dezimalcode erzeugt. <div id="mycode" expr="alert('Doppeltes Quote-Zeichen: ' + String.fromCharCode(34))" style="background:url('java
script:eval(document.all.mycode.expr)')">
document.body.innerHTML - wenn MySpace nicht die
Zeichenkette "innerHTML" überall ausgefiltert
hätte. Als Ausweg wurde "innerHTML" in einem
eval()-Aufruf aus zwei Strings zusammengesetzt: alert(eval('document.body.inne' + 'rHTML'));
"friendID" würde auch der eigene Code gefunden
werden, da der diese Zeichenkette ja auch enthält. Daher muss das zu
suchende Wort ebenfalls zusammengesetzt werden. Der gleiche Fall tritt auf,
wenn der Wurm-Code für die Weiterverbreitung von der aktuellen Seite
gelesen wird. var index = html.indexOf('m' + 'ycode');
"onreadystatechange" wurde von MySpace
ausgefiltert und daher ebenfalls in einem eval()-Aufruf
zusammengesetzt. eval('xmlhttp.onread' + 'ystatechange = callback');
www.myspace.com geschickt werden. Die aktuelle Seite befand
sich jedoch unter profile.myspace.com, so dass der Request
gegen die Same-Origin Policy verstößt. Um diese
Einschränkung zu umgehen, nutzte Samy Kamkar aus, das die Profile
sowohl unter profile.myspace.com als auch unter
www.myspace.com erreichbar waren. Die Seite musste also nur
unter der gewünschten Domain neu geladen werden.if (location.hostname == 'profile.myspace.com') document.location = 'http://www.myspace.com' + location.pathname + location.search;
Wie Sie sehen können, besteht der Wurm aus ganz normalen JavaScript-Code, wenn auch teilweise in etwas unüblichen Schreibweisen - und an einer Stelle eingefügt, an der JavaScript eigentlich nichts zu Suchen hat.
Das der Wurm überhaupt funktionierte und sich auf MySpace ausbreiten konnte, hat zwei Gründe:
'innerHTML'
verboten ist, hätte auch nach 'i'+'nnerHTML',
'in'+'nerHTML', ... 'i'+'n'+'nerHTML', ... usw.
usf. gesucht werden müssen. Und alle möglichen anderen Kodierungen.
Weiter zum Wurm-Code oder zurück zur Kapitel-Startseite oder zur Doku-Startseite