Blog

Leren programmeren infiltreren

“Kan jij hacken?” Vandaag in mijn blog geef ik antwoord op deze vraag, die meerdere malen aan me gesteld is, nadat ik iemand uitgelegd heb wat ik doe voor werk. Veiligheid is een hot topic, met strengere wetten, zero-days, ransomware en phising elke week wel weer in het nieuws. Maar wat is hacken eigenlijk en hoe doe je dat? Ik ga het je laten zien in een kleine tutorial hacken. Voordat we beginnen echter nog wel even een waarschuwing: de meeste mensen die gehackt worden, worden dat doordat ze onvoorzichtig zijn. Als je op een link klikt waarvan je niet weet of je die kunt vertrouwen, moet je soms erg goed oppassen. Lees voor je verder gaat eerst even snel dit: onveilige link

Ik heb er even over moeten nadenken wat we zouden gaan hacken. Omdat het misschien jullie eerste keer is kunnen we het niet té moeilijk maken, maar het moet ook niet te saai zijn, anders ben ik jullie natuurlijk veel te snel kwijt. Daarom is de keus gevallen op de AIVD. De AIVD is minder goed beveiligd dan bijvoorbeeld de FBI of de NSA, maar omdat het de Nederlandse inlichtingen en veiligheidsdienst is, kun je er toch een aantal leuke dingen over je zelf vinden. De AIVD heeft 5 firewalls, die we stuk voor stuk moeten omzeilen, het beste kun je daar dit programmaatje voor gebruiken firewall cracker maar als je niet achter een pc zit kan je ook de webversie gebruiken: firewall cracker online.

Hopelijk heb ik niemand teleurgesteld die even echt dacht dat we de AIVD gingen hacken. Zo simpel is het nou allemaal ook weer niet. Hacken zoals het normaal gezien gebruikt wordt, is het vinden van een stuk code dat niet helemaal veilig is en daar misbruik van maken. Eén van de bekendste en makkelijkst uit te leggen vormen hiervan is waarschijnlijk de SQL-injectie. SQL is een opzoek taal die gemaakt is om informatie uit databases en tabellen te halen. Stel ik heb de volgende tabel met volledig willekeurige gebruikersnamen, wachtwoorden en toegangsniveaus:

Gebruikersnaam Wachtwoord Toegangsniveau
Jarrie Password1 administrator
Michiel Password administrator
Sjook 123456 user
Pieter P@ssw0rd user
Potrick Password123 user
Koos Password2 user
Birt Summer12 user
Menfred password1 user
Katonka 12345678 user
Woeter Welcome2 user
Bunneke Spring2012 user
Bort Summer2012 user
Dean Password3 user
Marloes Hello123 user
Loesbeth Spring2012 user
Wieter Summer2012 user
Maroska Password3 user
Irune Spring12 user
Parcy Pa$$w0rd user
Reulof p@ssword user

 

Ok, de wachtwoorden zijn niet helemaal willekeurig. Dit waren volgens een onderzoek de meest gebruikte wachtwoorden in 2012. We zijn inmiddels 5 jaar verder, dus je mag er blind vanuit gaan dat dingen als Summer2012 niet meer voorkomen en vervangen zijn door Summer2017. Maar mocht je wachtwoord in het lijstje staan, is het misschien geen overbodige luxe om deze aan te passen.

Stel ik maak me geen enkele zorgen over beveiliging en ik zou een stukje SQL-code schrijven om te kijken of een user in mag loggen en welk toegangsniveau hij of zij dan heeft, dan kan dat er als volgt uitzien:

select gebruikersnaam
     , toegangsniveau
from gebruikers
where gebruikersnaam = <invoerveld1>
and wachtwoord = <invoerveld2>;    

Vervolgens maak je 2 invoervelden en als een gebruiker dan bijvoorbeeld invult: Dean en Password3, dan geeft dat stukje code terug: Dean user. Als er een foute combinatie ingevuld wordt, dan geeft het stukje code niets terug en weet je dat de inlog ongeldig is. In eerste instantie ziet dat er nog niet zo slecht uit. Natuurlijk zou je wachtwoord nooit zo opgeslagen mogen worden. Maar hoewel  ik dit expres slecht heb beveiligd als voorbeeld zie je dit nog steeds op te veel plekken terug, hoewel er in de laatste paar jaar extreem veel verbeterd is. Daar maken we ons even geen zorgen over, we gaan nu SQL injecteren. Toen we net de code gebruikte zoals die bedoeld was deed de computer dit:

select gebruikersnaam
     , toegangsniveau
from gebruikers
where gebruikersnaam = 'Dean'
and wachtwoord = 'Password3';

Maar stel dat we geen wachtwoord weten, maar we willen toch in kunnen loggen? Wat we dan moeten doen is zorgen dat de code iets terug geeft. Als we weten hoe de code er uit ziet kunnen we iets doen waar de programmeur bij het bouwen waarschijnlijk geen rekening mee heeft gehouden.

Stel als gebruikersnaam vullen we weer in Dean, maar als wachtwoord vullen we het volgende in: ‘ or 1=1; —
Dat ziet er misschien raar uit, maar kijk eens wat er gebeurt als we dat invullen in de code:

 

select gebruikersnaam
     , toegangsniveau
from gebruikers
where gebruikersnaam = 'Dean'
and wachtwoord = ' ' or 1=1; --';

Alles wat in SQL achter twee min tekenstaat, is inclusief de mintekens commentaar en wordt door de computer genegeerd. Waardoor de code die de computer nu uitvoert is geworden:

select gebruikersnaam
     , toegangsniveau
from gebruikers
where gebruikersnaam = 'Dean'
and wachtwoord = ' '
or 1=1;

Waar we eerst 2 voorwaarden hadden om te zorgen of we resultaat terug kregen: gebruikersnaam = X en wachtwoord = Y, hebben we er nu 3: gebruikersnaam = X en wachtwoord = Y of 1 = 1. Dat zorgt dat het stukje code altijd iets teruggeeft, immers 1 = 1 is altijd waar. Om te begrijpen waarom dat altijd waar is, moet ik even snel iets uitleggen over bewerkingsvolgorde. Vrijwel iedereen kent het ezelsbruggetje “Meneer van Dale wacht op antwoord” of een variant daarvan, die aangeeft dat bij rekenen je eerst moet machtsverheffen, dan vermenigvuldigen en delen, en optellen en aftrekken. Programmeer talen hebben net zoiets en dat heet bewerkingsvolgorde, dit kan per programmeertaal verschillen, maar we gaan er even vanuit, dat en hoger in de volgorde staat dan of. Dat betekent dat A of B en C hetzelfde betekent als B en C of A. Eerst wordt de en clausule bekeken, dus B en C en daarna wordt die waarde tegen de of A gehouden. Je mag het dus ook lezen als: A of (B en C).

1 =1 gaat altijd voor alle regels op, dus zal de code ook alle regels terug geven. Dat is potentieel een probleem, het stukje code kan in de war raken als het meer dan 1 resultaat terugkrijgt, maar ook dat is gelukkig makkelijk op te lossen door bijvoorbeeld: ‘ or 1=1 and gebruikersnaam = ‘Jarrie’; —
Dat geeft dan als code:

select gebruikersnaam
     , toegangsniveau
from gebruikers
where gebruikersnaam = 'Dean'
and wachtwoord = ' '
or 1=1
and gebruikersnaam = 'Jarrie';

Nu krijgen we maar 1 regel terug en zijn we ook nog eens direct administrator. Dat is een versimpelde versie van hoe een SQL injectie werkt. Waar het op neerkomt is dat we waar de programmeur verwacht dat we een stukje tekst intypen, we eigenlijk een stuk computercode intypen waarmee we de huidige code aanpassen en de computer laten doen wat wij willen. Als je deze vorm van hacken wilt gebruiken loop je tegen 2 problemen aan. Ten eerste weet je weet niet wat de code is die je probeert aan te passen. Dat is op te lossen door gewoon heel veel dingen te proberen. En 2, de programmeur heeft misschien wel rekening gehouden met de veiligheid van zijn stukje code. Dan heeft hij waarschijnlijk tegen de computer gezegd: “Wat de gebruiker ook invult, het is tekst en geen computercode dus je mag niets wat de gebruiker typt interpreteren als computercode”. Dat is wel een beetje een versimpeling van de echte wereld, maar het idee is wel ongeveer zo. Veel programmeurs houden tegenwoordig rekening met SQL-injectie waardoor dit steeds minder effectief is. Je zult echter nog steeds af en toe een nieuwsbericht tegenkomen over een ‘slecht beveiligde database’ en in dat geval is de kans groot dat de hacker in kwestie gebruik heeft gemaakt van SQL-injectie.

Een aanval die daar een beetje op lijkt is cross-site-scripting (afgekort met XSS). Cros-site-scripting werkt eveneens door ergens code in te vullen waar tekst wordt verwacht, maar dit keer wordt die code niet op de server uitgevoerd zoals bij de SQL injectie, waar het wachtwoord wordt vergeleken, dit keer wordt er javascript uitgevoerd op de computer van een willekeurige gebruiker. XXS werkt als volgt:
Stel je maakt een internet pagina, en je wil bezoekers de mogelijkheid geven een reactie achter te laten op die pagina, die vervolgens iedereen kan zien. Je maakt een invoerveldje en alles wat daar ingevoerd wordt sla je op, en bij de volgende keer dat de pagina geladen wordt laat je dat zien. Dat is iets wat je op het internet vrij veel ziet, in de vorm van bijvoorbeeld forums, gastenboeken en recensies. Stel iemand geeft een reactie op je pagina en typt het volgende:
“Leuke site, er mogen alleen wel iets meer plaatjes bij”
Dat ziet iedereen die vervolgens de pagina opent ziet dan bij de reacties die tekst staan, niets aan de hand. Maar stel iemand typt het volgende:

<script>console.log("leren infiltreren")</script>

De internet pagina gaat dan proberen dat stukje tekst te laten zien, maar als hij dat doet, dan herkent hij het als javascript, en javascript is niet iets wat je browser op de internetpagina zet, javascript is iets dat de browser uitvoert. Dus in plaats van dat er op de pagina iets komt te staan, ziet de browser dat hij iets in de javascript console moet loggen en doet hij dat.

Nou is dat vrij onschuldig, maar zoals je in de vorige blogs hebt kunnen zien kan je met javascript wel iets meer dan alleen iets in de console zetten. Zo zijn bijvoorbeeld OrcadoInvaders, TicTacToe en alle bijbehorende bots geschreven in javascript. Maar je kan met javascript ook bijvoorbeeld data versturen. Je kunt met dit trucje bijvoorbeeld alle toetsaanslagen die een gebruiker doet opslaan in een variabele en die vervolgens versturen naar je eigen server. Stel je voor dat op de zelfde pagina een inlog scherm zit, de eerstvolgende keer dat iemand dan inlogt heb je zijn of haar inloggegevens en hup, website gehackt.

Ook hier wordt gelukkig steeds vaker op gelet, maar dat betekent niet dat het niet nog steeds af en toe mis gaat. Zelfs de internetgiganten zoals Google, Facebook en Twitter hebben in het verleden last gehad van dit soort aanvallen. Je kunt deze aanval vrij makkelijk testen, als je ergens ook maar iets van tekst in moet voeren waarvan je weet dat die later zichtbaar zal zijn, zoals bijvoorbeeld op een forum of een gastenboek, probeer eens in te vullen:

<script>alert("test");</script>

Krijg je een popup met de tekst “test”? Dan is de pagina gevoelig voor XSS en is het een goed idee om de eigenaar op te hoogte te stellen.

Dat zijn waarschijnlijk de meest voorkomende vormen van hacken op het internet. Hacken komt meestal neer op het volgende: zoek een zwakte in de code van hetgeen je wilt hacken en buit dat uit, door bijvoorbeeld je eigen code uit te laten voeren in plaats van de oorspronkelijke code. Dat zoeken kost erg veel tijd en maakt het hacken erg lastig. Maar zoals je regelmatig in het nieuws leest tegenwoordig absoluut niet onmogelijk. Mocht je het nou heel leuk lijken, het is ook niet perse illegaal. Ja, het uitbuiten er van wel, maar de meeste grote bedrijven hebben tegenwoordig zogenaamde “bug bounty’s” wat inhoudt dat je een bedrag uitbetaald krijgt als je een dergelijk zwakte in hun code kunt vinden.

Terugkomend op de vraag: “Kun jij hacken?”. Ja, en jij nu ook! Maar de AIVD hoeft zich voorlopig nog geen zorgen te maken.

Back-To-Top