securitypo

Security PO

1. Inleiding: telefoon gehackt via WhatsApp

https://images.computational.nl/galleries/securitypo/2021-02-11_15-24-53.png

Eind januari 2020 kwam in het nieuws dat de telefoon van de directeur van Amazon (zeg maar de Amerikaans Bol.com) was gehackt. De aanval kwam vanuit Saoedi-Arabië, met hulp van de Saoedische kroonprins. De Saoedische prins had Jeff Bezos, de directeur, een videootje gestuurd via WhatsApp. Door een fout in WhatsApp konden de medewerkers van de prins alle berichten op zijn telefoon lezen. Jeff Bezos hoefde het filmpje niet eens te openen, het ontvangen van het filmpje was voor de hackers genoeg om toegang te krijgen tot alle bestanden op zijn telefoon. Een paar maanden later kwamen foto’s naar buiten waaruit bleek dat de getrouwde directeur een affaire had.

In dit bericht van RTL Nieuws wordt dit verhaal verder toegelicht.


2. Kwetsbaarheden

In software zitten allerlei fouten die misbruikt kunnen worden om toegang te krijgen tot systemen of vertrouwelijke informatie. Dit zijn kwetsbaarheden. Er zijn vele soorten kwetsbaarheden waar hackers misbruik van kunnen maken. We lichten er drie uit in dit hoofdstuk:

  • Buffer overflows
  • Cross-Site Request Forgery (CSRF)
  • Cross-Site Scripting (XSS)

Er zijn allerlei manieren om dit soort kwetsbaarheden te voorkomen en om je te beschermen tegen misbruik van dit soort kwetsbaarheden. De programmeurs van de software kunnen rekening houden met bekende soorten kwetsbaarheden en voorkomen dat deze kwetsbaarheden ontstaan in hun software. Softwareontwikkelaars brengen regelmatig updates uit waarin kwetsbaarheden worden weggenomen. Een belangrijke maatregel voor de gebruikers tegen een aanval via kwetsbaarheden is alle software actueel houden.

3. Leerdoelen

Dit zijn de leerdoelen voor dit hoofdstuk. In de opdracht kun je aangeven in hoeverre je ze beheerst.

Leerdoel

Je kunt op basis van de beschrijving van een kwetsbaarheid aangeven wat voor soort kwetsbaarheid het is (buffer overflow, cross-site request forgery, cross-site scripting).

Je kunt concreet aangeven hoe de volgende kwetsbaarheden misbruikt kunnen worden: buffer overflow, cross-site request forgery, cross-site scripting.

Je kunt op basis van een eenvoudig programma dat kwetsbaar is voor een buffer overflow concreet een aanval beschrijven, inclusief de off-by-one buffer overflow.

Je kunt passende maatregelen benoemen ter voorkoming van een buffer overflow, door zowel programmeurs als beheerders.

Je kunt minstens twee maatregelen noemen tegen misbruik via kwetsbaarheden.

Je bent in staat bent om bij een beschrijving van een aanval antwoord te geven op de volgende vragen:

Vragen over de aanval

  1. Van wie komt de aanval?

  2. Waarom wordt de aanval gedaan? Met andere woorden, wat is het doel van de aanval?

  3. Hoe gaat de aanval precies in z’n werk?

Vragen over de verdediging

  1. Wat zijn mogelijke tegenmaatregelen, zowel vooraf (nog voordat de aanval plaatsvindt) als tijdens (als de aanval eenmaal heeft plaatsgevonden).

  2. Hoe werken die tegenmaatregelen?

  3. Wie moet deze tegenmaatregelen nemen?

Je kunt voor een specifieke invoer van een programma voorbeelden geven van invoer die typisch door een fuzzer worden gegenereerd.

Je kunt enkele concrete voorbeelden noemen van cyberoorlog.

4. Belangrijkste begrippen

Dit zijn belangrijkste begrippen uit dit hoofdstuk.

Kwetsbaarheden (vulnerabilities)

Fouten in software die kunnen worden uitgebuit door hackers.

Exploits

Een programma dat gebruik maakt van de specifieke kwetsbaarheid om in te kunnen breken op een systeem.

Update

Een vernieuwde versie van een softwarepakket, waarin aanpassingen worden gedaan en waarin ook kwetsbaarheden worden opgelost. Men zegt ook wel: om het lek te dichten.

Buffer overflow

Een soort kwetsbaarheid waarbij een hacker gegevens invoert die langer zijn dan het syteem verwacht.

Off-by-one buffer overflow

Een buffer overflow door een fout in het programma waarbij een herhaling één keer te veel wordt doorlopen.

Cross-Site Request Forgery (CSRF)

Een soort kwetsbaarheid waarbij een hacker iemand onbedoeld een opdracht laat uitvoeren op een website.

Cross-Site Scripting (XSS)

Een soort kwetsbaarheid waarbij een hacker JavaScript-code invoert op een website dat vervolgens wordt uitgevoerd als andere bezoekers die website bekijken.

Zero-day

Een kwetsbaarheid die nog niet bekend is en waar dus nog geen update voor is ontwikkeld. Daardoor is een zero-day erg gewild bij hackers.

Bounty-programma

Een oproep van een bedrijf om kwetsbaarheden in hun software te melden tegen een beloning.

Segmentation fault

Een programma dat toegang probeert te krijgen tot een deel van het geheugen waar het geen recht toe heeft leidt tot een segmentation fault.

Fuzzing

Een manier om kwetsbaarheden te vinden, waarbij allerlei onverwachte invoer aan de software wordt gegeven.

Cyberoorlog

Landen proberen elkaar schade toe te doen of vertrouwelijke informatie in te winnen door gebruik te maken van de digitale infrastructuur.

Advance Persistent Threat (APT)

Een gerichte aanval op een persoon, organisatie of land, uitgevoerd door specialisten.

5. Voorkennis

Om de stof uit dit hoofdstuk goed te kunnen begrijpen is het goed dat je de volgende begrippen kent. We hebben een test toegevoegd om te kijken of je bekend bent met deze begrippen.

Programmeercode

In dit hoofdstuk tonen we soms kleine stukjes programmeercode, in de vorm van pseudocode. Daarbij worden de volgende onderdelen gebruikt: variabelen, rijen, herhaling, keuze.

HTML

We tonen kleine voorbeelden van HTML om te laten zien hoe cross-site request forgery en cross-site scripting werkt.

JavaScript

JavaScript is een programmeertaal die wordt ondersteund door alle bekende browsers. Het is belangrijk dat je begrijpt dat JavaScript-programma’s worden uitgevoerd door de browser. Dus: op de computer van degene die een website bezoekt.

Je hoeft geen JavaScript te kunnen schrijven en ook niet te kunnen begrijpen. In de kleine voorbeelden leggen we uit wat het programmaatje doet.

Webserver

Het is belangrijk om te weten dat een webserver de plek is waar websites worden opgeslagen. Daarnaast is de webserver de software die toegang tot de website biedt. Wil je weten wat een webserver doet? Lees dan: https://nl.wikipedia.org/wiki/Webserver

De bekendste softwarepakketten voor webservers zijn:

  • IIS van MicroSoft

  • Apache

  • Nginx (Spreek uit als Engine X)

Communicatie tussen browser en server

Je moet weten dat een browser verzoeken stuurt naar een webserver om webpagina’s op te vragen. Die verzoeken worden ook gebruikt als opdrachten aan de webserver. Bijvoorbeeld om aan te geven dat je een bepaalde foto leuk vindt.

Cookie

Een id dat de browser steeds stuurt naar de server, zodat de server kan achterhalen waar het verzoek vandaan komt.

Malware

Algemene term voor kwaadaardige software (zoals virussen en wormen).

(Computer)worm

Een worm is een vorm van malware (kwaadaardige software) dat zichzelf verspreidt zonder verder menselijk handelen.

Zie ook: https://nl.wikipedia.org/wiki/Computerworm

Virus

Een virus is een vorm van malware (kwaardaardige software) dat verspreidt wordt door menselijk handelen (bijvoorbeeld het openen van een bestand waar het virus in is verpakt).

Zie ook: https://nl.wikipedia.org/wiki/Computervirus

Bestandsformaten

Bestanden worden volgens een vaste structuur opgebouwd, dit is vastgelegd in het bestandsformaat. Bijvoorbeeld, voor afbeeldingen zijn er allerlei formaten beschikbaar zoals JPEG, PNG en GIF. Deze formaten schrijven voor hoe de gegevens over de afbeelding in het bestand moeten worden opgeslagen.

6. Code Red worm en de buffer overflow

Het is al weer lang geleden toen een gevaarlijke worm uitbrak op het internet. Deze worm maakte gebruik van een kwetsbaarheid in de webserversoftware van Microsoft, genaamd Internet Information Services (IIS). Iemand die de website van een geinfecteerde webserver opende kreeg het volgende te zien:

HELLO! Welcome to http://www.worm.com! Hacked By Chinese!

De worm zorgde ervoor dat de geinfecteerde server trager werd. Daarnaast startte de Code Red worm een aanval op de servers van het Witte Huis in Washington. De worm heeft in minder dan 24 uur meer dan 300.000 servers besmet. In deze animatie is dat mooi te zien.

De worm maakte dus gebruik van een kwetsbaarheid in IIS. En specifieker: het ging om een buffer overflow.

Hoe werkt een buffer overflow?

Om te begrijpen hoe een buffer overflow werkt is het belangrijk te weten hoe het werkgeheugen van een computer is opgebouwd en hoe dat wordt gebruikt. Je zou kunnen zeggen dat het werkgeheugen van een computer bestaat uit een verzameling geheugencellen. Elke cel is een byte, of 8 bits. Zo kan een programma allerlei informatie opslaan in het werkgeheugen. Als je gebruik maakt van een variabele in een programma wordt de waarde van die variabele opgeslagen in één of meerdere cellen van het werkgeheugen. Het werkgeheugen wordt ook wel RAM (Random Access Memory) genoemd.
De hoeveelheid werkgeheugen die wordt gebruikt voor een variabele hangt af van het type van de variabele. Hieronder zie je een voorbeeld. Het kan echter per programmeertaal en per type computer verschillen.

Type

Geheugengebruik

Integer

2 bytes

Boolean

1 byte

Char (=character, een teken)

1 byte

String

Het aantal tekens x 1 byte + 1 byte om het einde van de string aan te geven (namelijk NULL, of in binair: 0000 0000). Bijv: voor een string van 4 tekens zijn 5 bytes nodig.

Float

4 bytes

Een geheugencel bestaat uit 8 bits. Een byte wordt vaak weergegeven als een hexadecimaal getal bestaande uit twee cijfers. Het hangt van het type variabele af wat de betekenis is van die bits. Hieronder zie je een tabel met enkele voorbeelden. In de linker kolom zie je de binaire waarde in de geheugencel.

Binair

Hexadecimale representatie

Betekenis als het een integer is

Betekenis als het een char is1

0000 0000

00

0

NULL

0010 0000

20

32

<spatie>

0100 0000

40

64

@

0101 1010

5A

90

Z

1011 1101

BD

189

½

1111 1111

FF

255

ÿ

ASCII is slechts 7 bits en bevat 128 mogelijke tekens. Er zijn allerlei varianten van extended ASCII, de 8-bit variant die 256 mogelijke tekens bevat. Wij gebruiken deze.

7. Eerste voorbeeld van een buffer overflow

Nu je weet dat het werkgeheugen is opgebouwd uit cellen kun je leren hoe een buffer overflow werkt. Hieronder zie je een stukje werkgeheugen, gevuld met data. De data wordt hexadecimaal weergegeven.

https://images.computational.nl/galleries/securitypo/2021-02-14_15-19-16.png

In de onderstaande afbeelding lichten we er een stukje werkgeheugen uit en laten zien wat de betekenis is van de gegevens in dit werkgeheugen. Je ziet dat twee variabelen (naamGebruiker en geboortejaar) in het werkgeheugen zijn opgeslagen. De variabele naamGebruiker is van het type String, dat eigenlijk een rij van losse tekens (char) is. Een string wordt afgesloten met NULL (hexadecimaal: 00).

https://images.computational.nl/galleries/securitypo/2021-02-14_15-38-44.png

Dit zou het geheugen kunnen zijn na uitvoer van het volgende stukje programma.

PROGRAM voorbeeld:

STRING naamGebruiker [7]
INTEGER geboortejaar

naamGebruiker = “Adriaan”
geboortejaar = 1990

END PROGRAM

Let op: het kan zijn dat in de programmeertaal die jij gewend bent, je niet hoeft aan te geven hoe lang een string is, zoals in het voorbeeld hierboven (namelijk maximaal 7 tekens). De lengte wordt dan automatisch bijgesteld. Dat soort talen zijn over het algemeen minder gevoelig voor buffer overflows.
We passen vervolgens het programma een beetje aan. De gebruiker moet nu zelf een naam invullen.

PROGRAM voorbeeld:

STRING naamGebruiker [7]
INTEGER geboortejaar

READ (loginnaam, ‘Naam?’)

END PROGRAM

Nadat de variabelen zijn geinitialiseerd, maar voordat de gebruiker een naam heeft ingevuld, ziet het geheugen er als volgt uit, alles is gevuld met 00.

https://images.computational.nl/galleries/securitypo/2021-02-14_15-44-28.png

Je ziet, hier gaat iets niet helemaal goed. Dit is een buffer overflow: de hoeveelheid geheugen die is gereserveerd voor een bepaalde waarde is te klein, waardoor het andere geheugen wordt ‘overspoeld’. De variabele geboortejaar heeft ineens de waarde 24832 gekregen.

https://images.computational.nl/galleries/securitypo/2021-02-14_15-56-54.png

Dit komt omdat op de eerste geheugencel de 'a' wordt omgezet naar hexadecimale waarde 61. De volgende geheugenwaarde wordt niet ingevuld dus deze blijft 00.

8. Hoe kun je de buffer overflow voorkomen?

Om dit soort buffer overflows te voorkomen is het belangrijk om invoer in het programma (bijvoorbeeld van de gebruiker) te controleren op lengte. Als de lengte groter is dan de hoeveelheid geheugen die is gereserveerd moet het programma daarop reageren om een buffer overflow te voorkomen. Bijvoorbeeld door terug te geven ‘De naam is te lang, kies een kortere naam van maximaal 7 tekens’.

In de basis kan een buffer overflow ontstaan met een programmaatje als hieronder. Er wordt een variabele gemaakt met de naam invoerBuffer, die uit maximaal 10 tekens bestaat. Vervolgens kan de gebruiker van het programma iets invoeren, dit wordt opgeslagen in invoerBuffer. De vraag is: wat gebeurt er als de invoer (veel) langer is dan 10 tekens? Dat hangt ervan af welke programmeertaal je gebruikt en hoe je het programma precies maakt.

PROGRAM buffer overflow:

STRING invoerBuffer [10]

READ (invoerBuffer, ‘Vul hier de gegevens in’)

END PROGRAM

9. Tweede voorbeeld van een buffer overflow

Bekijk het volgende stukje pseudocode en de indeling van het werkgeheugen met daarin de variabelen loginNaam, wachtwoord en ingelogd.

https://images.computational.nl/galleries/securitypo/2021-02-14_16-36-27.png

We gebruiken het volgende programma.

PROGRAM login:

STRING loginNaam [8]
STRING wachtwoord [8]
BOOLEAN ingelogd = 0; // 0 betekent false: niet ingelogd, 1 betekent true: wel ingelogd

READ (loginNaam, ‘Wat is je loginnaam?’)
READ (wachtwoord, ‘Wat is je wachtwoord?’)

IF (checkWachtwoord (loginNaam, wachtwoord) == TRUE) THEN
     ingelogd = 1
ENDIF

IF (ingelogd == 1) THEN
     // succesvol ingelogd, naar het startscherm
ELSE 
     // foutief login en/of wachtwoord, terug naar het inlogscherm
ENDIF

END PROGRAM

10. Voorkomen van een buffer overflow

Sommige programmeertalen zijn minder gevoelig voor buffer overflows, zoals bijvoorbeeld Python en Java. Bij andere talen is het belangrijk op te letten de juiste functies te gebruiken. Bijvoorbeeld bij PHP of C. Bij die laatste geeft de compiler aan dat je bepaalde functies beter niet kunt gebruiken omdat die gevoelig zijn voor buffer overflows. Daarnaast is het altijd belangrijk om je programma goed te testen en goed te kijken naar hoe het reageert op externe invoer.

Bij elke aanval kun je enkele standaard vragen stellen. We maken onderscheid tussen vragen over de aanval of dreiging enerzijds en de verdediging anderzijds. We zullen dit doen aan de hand van een worm genaamd Code Red. We stellen een aantal vragen:

Vragen over de aanval

  1. Van wie komt de aanval?
  2. Waarom wordt de aanval gedaan? Met andere woorden, wat is het doel van de aanval?
  3. Hoe gaat de aanval precies in z’n werk?

Vragen over de verdediging

  1. Wat zijn mogelijke tegenmaatregelen, zowel vooraf (nog voordat de aanval plaatsvindt) als tijdens (als de aanval eenmaal heeft plaatsgevonden).
  2. Hoe werken die tegenmaatregelen?
  3. Wie moet deze tegenmaatregelen nemen?

Eén van de doelen van deze module over security is dat je in staat bent om bij een specifieke aanval antwoord te geven op deze vragen. Het is daarbij overigens prima om bronnen van internet gebruiken. Let wel op dat je betrouwbare bronnen gebruikt.

We gaan proberen antwoord te krijgen op deze vragen bij de Code Red worm die aan het begin van dit hoofdstuk is geïntroduceerd. Laten we eens kijken naar hoe de aanval precies in z’n werk ging. De verspreiding van de worm ging eigenlijk heel eenvoudig. De worm stuurt het volgende bericht naar willekeurige webservers. Als op die webserver IIS draaide, kon de worm zich verder verspreiden.

https://images.computational.nl/galleries/securitypo/2021-02-15_11-14-38.png

Berichtje dat de code Red Worm verstuurde.

Als op die webserver IIS draaide, kon de worm zich verder verspreiden. Het commando GET aan het begin is onderdeel van het HTTP-protocol dat wordt gebruikt om webpagina’s op te vragen.

De hacker die deze worm heeft ontwikkeld heeft waarschijnlijk goed gekeken naar hoe de IIS software werkt. Vaak is het een hele puzzel om dit voor elkaar te krijgen. Microsoft had overigens eerder al een bericht uitgedaan over de kwetsbaarheid, dat zal vast ook geholpen hebben. Er was ook al een maand een update beschikbaar om deze kwetsbaarheid te verhelpen.

Hieronder zie je een weergave van het geheugen nadat het bovenstaande bericht is verwerkt, in hexadecimale waarden. Dit is het deel van het geheugen dat eigenlijk niet gebruikt had mogen worden (zeg maar: het overspoelde geheugen).

https://images.computational.nl/galleries/securitypo/2021-02-15_11-35-59.png

Je kunt misschien wel iets herkennen van het oorspronkelijke bericht in het geheugen. De machinecode die in het bericht is opgenomen staat nu in het geheugen. Dit kleine programmaatje zorgt ervoor dat een uitgebreider, groter programma wordt opgestart. In het bericht dat de worm stuurde werd dat grotere programma meegestuurd (dat zie je niet terug in het bericht hierboven). Dit grotere programma zorgt ervoor dat de worm zich verder verspreidt.

Zo werkt een aanval op basis van een buffer overflow wel vaker. Een relatief kort berichtje met daarin een klein programma zorgt ervoor dat een veel groter programma wordt opgestart. De kabout kruipt door een klein gaatje naar binnen om vervolgens de poort te openen voor de reus die staat te wachten.