Mja, kijk, uw vraag is hier ook zeer algemeen.
Het probleem is: jij wilt gaan bruteforce leren. Dat op zich is easy als hell (zoals ik hier boven zei: basis komt neer op 1 lusje).
De code die je gebruikt om te hacken zelf is puur implementatie-afhankelijk. Wil jij een hash "decoden" of een pass bij een username raden of een bepaalde file op een server zoeken of ... .
Dit zijn zeer verschillende zaken die op een heel eigen manier geprogrammeerd worden en eigenlijk totaal niet onder het topic "hacken" vallen maar wel onder dat specifieke domein. Voor die hash zal je die specifieke hash functie moeten implementeren. Voor dat pass op een site zal je moeten networking (sockets) en wat HTTP-protocol gebruiken. Voor die file dan weer het FTP (of ook HTTP) protocol, ... .
Dit zijn dus zaken die op zich niets met hacking te maken hebben, je schrijft gewoon code die een pagina opvraagt ofzo. Het hacken zelf is dat je die code een 1000x per seconde ofzo laat uitvoeren om te proberen aan het pass te geraken.
Je kan dus niet zomaar algemeen leren bruteforcen

. Daarom dat het uit leeraspect vrij oninteressant is.
Rainbow table is gewoon een tabel waarin je alle voorgaande resultaten opslaat.
Stel je wilt een md5 hash raden, je begint bij "a", zo tot "z", dan "aa" tot "zz", enz. enz. (in het echt zal je meer tekens afgaan ofcourse, tis maar een vb.).
Nu ga je die allemaal aflopen en altijd die hash herberekenen, wat al een vrij zware functie is. Stel dat je dan bij "test" eindelijk de juiste sequentie hebt gevonden waren die vorige resultaten "nutteloos" en ga je die de volgende keer weer allemaal overlopen, verspilling dus.
Een rainbow table komt er in de basis op neer dat je gewoon de hash opslaat met de corresponderende tekst nadat je berekening hebt gedaan. De volgende keer dat je zoekt kan je dan eerst in die tabel kijken of je die hash al opgeslagen hebt. De kost die je hebt is dat je een opslag-algoritme extra hebt uit te voeren, dat echter vaak zeer snel is. De winst is dat je bij veelvuldig gebruik op den duur een zeer mooie tabel hebt aangelegd en hashes vrij snel kan vinden.
Voor zulke tabellen gebruikt men dan ook meestal speciale (zeer snelle) datastructuren, geen gewone arrays, maar daar ga ik niet verder op ingaan gezien je nog maar basis gezien hebt. Want zoiets op zich programmeren is nogal moeilijk als je niets ervan kent

. Maar hiervoor bestaan dan weer voorgeprogrammeerde containerclasses in de meeste populaire talen.
In zo een geval word het dus iets als (dit is pseudocode he)
Code:
bool correct = false;
gezochtemd5 = ...;
Table t = loadCalculatedMD5s();
String test= t["0"]!=NULL?t["0"]:"a";
if(t[gezochtemd5] != NULL) resultaat = t[gezochtemd5];
else while(!correct)
{
resultaat = MD5(test);
correct = (resultaat==gezochtemd5);
t.add(resultaat,test++);
}
t.add("0",test);
saveCalculatedMD5s(t);
We initialiseren eerst een boolean voor onze loop (kan zonder ook, maar kwou het duidelijk houden). Dan hebben we natuurlijk nog de md5 die we willen "kraken".
Daarna maken we een tabel aan, hiervoor roepen we een functie aan die de reeds berekende md5's ophaalt (dat komt er gewoon op neer een tekstbestandje in te lezen in een tabel, zit in java e.d. std in).
Dan maken we de start-string. Hier heb ik deze opgeslagen in de tabel op positie ["0"] (omdat er geen enkele md5hash ooit "0" zal geven kan ik dat gebruiken). Immers, we willen niet weer alles van "a" herhalen, maar waar we laatste keer gestopt zijn (we slaan dit op in ["0"], zoals je later in code ziet). Natuurlijk, als dit niet bestaat (we hebben de code nog nooit uitgevoerd, er bestaat geen tabel), dan beginnen we gewoon op "a", x?y:z is gewoon gelijkaardig aan if(x) then y else z.
Daarna kijken we of die gezochte hash al in die tabel voorkomt (iets wat normaal zeer snel gaat). Zoja, dan steken we dit in het resultaat.
Zo nee, we komen in onze bruteforce loop terecht.
In deze loop berekenen we eerst de md5 van onze teststring. Dan kijken we of de md5 hiervan gelijk is aan de gezochte md5, dit resultaat steken we in de boolean resultaat.
En op het einde voegen we de berekende hash toe aan de tabel (eerste argument = hash = uw index, zoals de 0,1,2, ... in arrays; tweede argument = de tekst die met die hash overeenkomt).
In dat statement gebruik ik ook ++, dit wilt zeggen dat uw string naar de volgende waarde zal springen (bv. van a->b, z->aa, ...). Dat wordt normaal wel intern in de string klasse geïmplementeerd

.
Als resultaat gelijk is aan true stopt de lus, als ze vals is gaan we verder.
Eenmaal de lus stopt slaan we op positie ["0"] op waar we gekomen zijn met de test-string (dit is dus waar we volgende keer verdergaan

). Merk op dat dit door dat ++ statement de string is volgend op de laatste die we berekend hebben, zoals we willen

.
En natuurlijk slaan we dan de tabel nog ergens op in een tekstbestandje of zo zodat we volgende keer weer heel onze tabel kunnen inladen.
Dit is dus vrij basic & geschreven in de hoop dat jullie het kunnen begrijpen, in echte implementaties zal het ietsje sneller & technischer geschreven worden. En in heel realistische situaties zit je met netwerken van hackers die elk een deel berekenen (gedistribueerde programma's), maar dat is dan weer geadvanceerd gedoe

.
Je moet je gewoon leren inprenten dat hacking niet direct een kunst op zich is. Vele hackers zijn gewoon mensen die een bepaald systeem goed begrijpen en eigenlijk ook zo een systeem goed kunnen gebruiken of zelf schrijven. Je leert niet "hacken", je leert een systeem kennen en probeert in te zien waar de zwakheden zitten

.
En dan heb ik het over echte hackers, de mensen die de code schrijven. Geen scriptkiddies en attackers die gewoon tooltjes gebruiken.