Moinsen,
In diesem HowTo werde ich euch zeigen was Hooking ist, wofür wir es nutzen können und weshalb wir niemals unsere Javascript Projekte ohne Absicherung & Validierung von Daten unserer eigenen Funktionen erstellen sollten.
Was ist Hooking?
Hooking beschreibt den Prozess, das man sich in eine bestimmte Funktion "einklinkt" und somit die volle Kontrolle über diese Funktion & ihren Daten übernimmt.
Wir können hierbei jede beliebige Funktion Hooken die wir möchten - auch die Javascript internen Funktionen wie zum Beispiel alert, prompt etc.
Um euch besser zeigen zu können was Hooking ist, werde ich mit euch nun ein Praktisches Beispiel durchspielen ![Rolleyes](images/smilies/rolleyes.png)
Nehmen wir an, wir haben eine Funktion die 2 Zahlen als Variablen-Werte aufnehmen kann, und diese Zusammenzählt und wieder ausgibt.
Code:
function add(a, b)
{
return parseInt(a+b);
}
Nun nehmen wir zusätzlich an das diese Funktion in irgendeinem Web-Projekt genutzt wird - jedoch haben KEINEN (!) Zugriff auf den Server.
Wir wollen aber sooooo doll gerne das Ergebnis beeinflussen was "unsere" (jedenfalls bald! ;P) add() Funktion ausgibt..
Wir haben keinen Zugriff auf die Sources vom Server, wir müssen uns also was anderes einfallen lassen.. und hier kommt das Hooking ins Spiel.
Mit Hooking können wir uns nun in unsere add() Funktion einklinken, und auch auf die Variablen a sowie b zugreifen.
Kurz gesagt ? Wenn wir die add() Funktion hooken, sind wir der neue Gott diese Funktion und können sie beliebig beeinflussen.
Doch wie funktioniert so ein Hooking? Nun, das hängt davon ab was wir tun wollen.. da gibt es Grundsätzlich gesehen nämlich 2 Varianten.
Diese zeige ich euch nun mal.
Hooking Methode #1
Die ersten Variante des Hookings besteht aus folgendem:
1) Wir klonen unsere Funktion die wir Hooken möchten (unter einem neuen Funktionsname)
2) Nun überschreiben wir die alte Funktion mit einer neuen Funktion in der wir tun was wir möchten.
Info: Die Funktion muss von der Struktur her genauso aufgebaut sein wie die alte.. sonst gibts Fehler in der Web Application die wir ja beeinflussen möchten
..
3) Am Ende unserer neuen Funktion müssen wir nun nochmals die Originale Funktion aufrufen - da wir diese nun ja aber überschrieben haben, müssen wir den Klon dieser Funktion nehmen.
4) Voila, Hook erfolgreich.
Um das ganze näher zu verdeutlichen werden wir nun mal die alert() Funktion von Javascript hooken
!
Code:
//Wir Klonen die alert() Funktion - unsere geklonte Funktion heißt nun orig_alert();
var orig_alert = alert;
//Wir überschreiben die alte alert() Funktion mit unserer eigenen
alert = function(msg)
{
msg = msg+"- Hooks sind toll :)!"; //Wir beeinflussen nun den Text der normalerweise ausgegeben würde und fügen einen eigenen Text hinzu
orig_alert(msg); //Nun rufen wir die originale alert() funktion auf
}
Hiermit haben wir nun die alert() Funktion von Javascript hooked. Rufen wir nun beispielweise
auf.. dann erhalten wir keine Nachrichtenbox die "XSS" ausgibt sondern es wird "XSS - Hooks sind toll
!" ausgegeben.
Das war die Version 1 eines Hookes in Javascript ![Wink](images/smilies/wink.png)
Hooking Methode #2
Die Erste Version eines Hooks eignet sich nicht für alle Funktionen - denn manchmal müssen wir auch tiefergehend in Funktionen eingreifen.
Bei der 1. Version können wir die Funktion in ihrer Funktionsweise nicht selbst beeinflussen, sondern nur die Variablen womit die Funktion aufgerufen wurde.
Damit wir nun tiefergehend in die Funktionsweise einer Funktion eingreifen können, benötigen wir die 2. Variante des Hookens.
Hierfür benötigen wir jedoch den Quelltext der entsprechenden Funktion - aus diesem Grunde eignet sich diese Variante meistens nur für Benutzerdefinierte Funktionen.
Funktionen wie zum Beispiel alert() sind für uns nicht so einfach einsehbar - wenn wir die Funktion näher einsehen wollen (alert.toString()) bekommen wir nur folgendes zu Gesicht:
Code:
function alert()
{
[native code]
}
Kurz gesagt - wir können die Variante 2 nicht so ohne weiteres auf eine Javascript Interne Funktion anwenden.
Um eine Funktion mit unseren 2. Variante Hooken zu können benötigen wir den Sourcecode.. und den holen wir uns ganz einfach über die toString() Funktion von Javascript (oder indem wir in den Quelltext schaun).
Da ich wieder Praktisch ein Beispiel zeigen möchte, nehmen wir das Beispiel von ganz oben.. nehmen wir an eine Web Application besitzt eine add(a,b) Funktion.
Code:
function add(a, b)
{
return parseInt(a+b);
}
Nun möchten wir aber das jedesmal wenn diese Funktion aufgerufen wird 1337 als Ergebnis ausgegeben wird. Wie lösen wir dieses Problem?
Nun, da wir nun schon wissen wie die Funktion aufgebaut ist, können wir sie einfach überschreiben und anpassen.
Das geht im Grunde genommen ganz einfach:
Code:
add = function(a, b)
{
return parseInt(1337);
}
jedesmal wenn nun add() aufgerufen wird, gibt sie 1337 als Ergebnis zurück - komplett egal welche Variablen sie enthält.
Natürlich können wir auch die Variablen die von außerhalb in die Funktion gegeben wird dumpen - das ist oft Hilfreich bei Web Anwendungen wo die Entwickler versuchen die Funktionsweise zu verschleiern indem sie Javascript Funktionen in Form von Variablen an andere Funktionen übergeben und ähnliches.
Kurz gesagt wars das eigendlich schon mit dem Hooken in Javascript - nun möchte ich noch kurz einige Anreize geben wofür man das ganze nutzen kann ![Applause](images/smilies/applause.png)
Anwendungzwecke
- Analysieren von Javascript Funktionen
Oft werden Javascript Funktionen bewusst Verschachtelt, Verschleiert oder Verschlüsselt.
Viele Javascript Entwickler denken das ihre Webanwendungen sicher sind wenn sie ihre Funktionen Anonym gestalten, oder so gestalten das man nur schwer durchblickt als Externe Person. Doch mit dem Hooken von Funktionen kann man wichtige Daten aus Funktionen auslesen die einem dann helfen können zu verstehen was die eigendliche Funktion tut und wie man sie eventuell nutzen könnte. Man kann hier sehr gut verstehen lernen wie man selbst spezielle Funktionen aufrufen muss um bestimmte Dinge zu bewirken.
- Manipulation von Javascript Funktionen
Viele Entwickler die Javascript ( & HTML5) Anwendungen entwickeln scripten enorm Stümperhaft.
Da werden Benutzereingaben nicht validiert, Funktions-Daten nicht kontrolliert und vieles mehr.
Man könnte bei vielen Javascript Anwendungen wirklich denken sie wären von einem 5 Jährigen zusammenkopiert.
Das Problem bei dem ganzen? Oft lässt sich durch Javascript auch Serverseitig Dinge beeinflussen.
Das klassische Beispiel hierfür ist ein Spiel in dem es ein Highscore gibt für die schnellste Zeit für das lösen eines Puzzels.
Hier kann man die Zeit-Funktion hooken und das Puzzle instant innerhalb 0 Sekunden lösen und landet auf Platz 1 ![Redface](images/smilies/redface.png)
![Pirate](images/smilies/pirate.png)
Das härtere Beispiel hierfür ist dann ein Deface eines ganzen Webservices aufgrund eines Fehlers in einer Javascript Funktion
wodurch man Code injecten kann oder sonstwie auf den Server zugreifen kann.
Kurz gesagt - Javascript = Enorm Machtvoll.. wenn man weiß wie man es einsetzt.
Ich lege wirklich jedem der Webanwendungen auf HTML5 und Javascript Basis entwickelt ans Herz -> Validiert ALLE Eingaben Serverseitig.
Das prüfen basierend auf Javascript Funktionen ist enorm Unsicher.. und lässt sich durch das hier gezeigte Hooking umgehen.
Da nützen dann auch keine Hashes basierend auf Zeit, Datum und Useragent mehr wenn es Clientside validiert wird und der Server alles annimmt was man ihm zuschmeißt.. Viele Webseiten haben Validierung der Daten nur Clientside (= sehr sehr schlecht).
Reallife Anwendungsfall
Wie gefährlich es wirklich sein kann den Userinput nicht zu validieren möchte ich euch mal hier an einem realen Beispiel von mir aufzeigen.
Vor einiger Zeit hatte ich mal einen Captcha Anbieter unter die Lupe genommen (beginnt mit Sweet..
) weil ich schauen wollte ob ich die Captcha Abfrage umgehen kann. Weshalb? Nunja, ich wollte für eine andere Webseite einen Javascript Bot erstellen um Kostenlose Punkte für Traffic zu bekommen.
Ich schaute mir also die Javascript Funktionen an.. und siehe da! Es wurde Clientside ein Hash generiert anhand eines Random() Wertes.
Anhand dieses Zahlen-Strings hatte der Server anschließend ein Captcha generiert. Das Problem am ganzen? Man konnte beliebig oft den Zahlenwert
an den Server senden und immer wiederverwenden.. beliebig oft. Die Captcha-Antwort blieb dabei immer die selbe. Captcha = geknackt.
Die Lücke ist mittlerweile behoben.. aber es zeigt deutlich wie wichtig das ganze sein kann.
Ohne Javascript Hooking hätte ich viele Funktionen des Anbieters nicht verstanden da der ganze Code ziemlich obfuscated und so konstruiert war das
man ihn nicht gut versteht. Hooking hatte mir dann vieles erleichtert und das Captcha System war nach einem Abend geknackt ![Biggrin New](images/smilies/biggrin-new.png)
Was lernen wir daraus?..
Validiert eure verdammten Daten richtig, Mensch! ![Tongue](images/smilies/tongue.png)
![Wink](images/smilies/wink.png)
Grüße