Geheugencorruptie: de kwetsbaarheid die decennia oud is en nog altijd toeslaat
Stel je een flatgebouw voor waarin elke bewoner precies één appartement heeft toegewezen gekregen, met een deur die op slot zou moeten zitten. Geheugencorruptie is wat er gebeurt als een programma zich niet aan de grenzen van zijn eigen appartement houdt: het schrijft spullen in de gang, in de kast van de buren, of zelfs in de meterkast waar de sleutels van het hele gebouw liggen. In computertermen: een programma schrijft of leest gegevens buiten het stukje geheugen dat er eigenlijk voor bedoeld was.
Dat klinkt onschuldig — een foutje, een crash, hooguit vervelend. Maar in de praktijk is geheugencorruptie een van de belangrijkste manieren waarop hackers programma's overnemen. Door heel precies de verkeerde gegevens op de verkeerde plek te zetten, kunnen aanvallers een computer dwingen om hún code uit te voeren in plaats van de bedoelde software. Het is de technische basis achter een groot deel van de spraakmakende hacks van de afgelopen decennia, van de Morris-worm in 1988 tot moderne spyware die op afstand een telefoon kan overnemen zonder dat het slachtoffer ook maar iets hoeft aan te klikken.
Wat is het precies?
Computergeheugen (RAM) is één lange rij genummerde vakjes, elk met een eigen adres. Wanneer een programma draait, reserveert het stukjes van die rij om variabelen, tekst, foto's of instructies in op te slaan. Zolang elk onderdeel van het programma netjes binnen zijn eigen gereserveerde vakjes blijft, gaat alles goed.
Geheugencorruptie ontstaat wanneer die grenzen worden overschreden. Dat gebeurt in een paar bekende varianten. Bij een buffer overflow (bufferoverloop) schrijft een programma meer gegevens dan er in een gereserveerd blok passen, waardoor de rest overloopt in het geheugen ernaast. Bij use-after-free gebruikt een programma een stuk geheugen nadat het al is 'vrijgegeven' — vergelijkbaar met iemand die nog post ontvangt op een adres waar hij net is verhuisd, terwijl er inmiddels een ander in trekt. Bij een null pointer dereference probeert een programma iets te lezen van adres 'nul', een plek die niet bestaat, wat meestal tot een crash leidt.
Het gevaarlijke zit in wat er verder in het geheugen ligt. Naast gewone data staan vaak ook gegevens die bepalen wat het programma hierna moet doen, zoals een 'retouradres' dat aangeeft welke functie na afloop moet worden aangeroepen. Als een aanvaller precies dat retouradres weet te overschrijven met een adres van zijn eigen keuze, kan hij het programma dwingen om willekeurige, door hemzelf aangeleverde code uit te voeren. Dat heet remote code execution: de aanvaller krijgt volledige controle, vaak zonder dat de gebruiker iets hoeft te doen.
Programmeertalen als C en C++ geven ontwikkelaars veel vrijheid over geheugenbeheer, maar controleren zelf niet of grenzen worden overschreden. Dat maakt ze snel en flexibel, maar ook foutgevoelig: een simpele fout in de code kan al genoeg zijn. Nieuwere talen zoals Rust bouwen die controles wél verplicht in de taal zelf in, waardoor hele categorieën van dit soort fouten vrijwel onmogelijk worden.
Wat wil men ermee bereiken?
Geheugencorruptie is geen technologie die iemand wÃl bouwen — het is een ongewenst bijproduct van decennia software geschreven in talen zonder ingebouwde geheugenveiligheid. Het onderzoeksveld eromheen bestaat uit twee kanten die met tegenovergestelde doelen naar hetzelfde probleem kijken.
Aanvallers en beveiligingsonderzoekers zoeken naar dit soort fouten om te bewijzen dat software onveilig is, of om ze daadwerkelijk te misbruiken voor spionage, sabotage of criminele winst. Verdedigers — softwarebedrijven, overheidsinstanties, academici — willen precies het omgekeerde: fouten vinden vóórdat kwaadwillenden dat doen, en op termijn de hele bugklasse laten verdwijnen door programmeertalen, tools en hardware te ontwikkelen die dit soort fouten simpelweg onmogelijk maken.
Die laatste ambitie heet 'memory safety by design': niet elke individuele fout jagen, maar de architectuur zo bouwen dat de fout niet kan ontstaan. Dat is de reden waarom grote partijen als Google, Microsoft en de Amerikaanse overheid de afgelopen jaren openlijk zijn gaan aandringen op een overstap naar geheugenveilige talen voor nieuwe, kritieke software.
Voorbeelden uit de praktijk
De geschiedenis van geheugencorruptie is bezaaid met incidenten die de kwetsbaarheid pijnlijk concreet maken.
- Morris-worm (1988) — een van de eerste internetwormen misbruikte een bufferoverloop in de Unix-dienst 'fingerd' en legde grote delen van het toenmalige internet plat.
- Heartbleed (2014) — een fout in de veelgebruikte OpenSSL-bibliotheek zorgde voor een 'buffer over-read': servers lekten stukjes geheugen, waaronder soms wachtwoorden en versleutelingssleutels, aan wie er maar om vroeg.
- EternalBlue / WannaCry (2017) — een bufferoverloop in de Windows SMB-netwerkdienst, ontwikkeld door de NSA en later gelekt, werd de motor achter de wereldwijde ransomware-uitbraak WannaCry.
- Stagefright (2015) — meerdere geheugencorruptiefouten in de mediaverwerking van Android maakten het mogelijk telefoons over te nemen via een simpel mms-bericht.
- FORCEDENTRY (2021) — een keten van geheugencorruptiefouten in Apples beeldverwerking, gebruikt door spyware-bedrijf NSO Group om iPhones over te nemen zonder dat het slachtoffer op iets hoefde te klikken.
Hoe ver is de techniek?
Het probleem is oud — de eerste bufferoverlopen zijn al meer dan veertig jaar bekend — maar allesbehalve opgelost. Onderzoek van zowel Microsoft als Google liet de afgelopen jaren zien dat ruwweg zeventig procent van de ernstige beveiligingslekken in hun grote, in C/C++ geschreven codebases (Windows, Chrome, Android) terug te voeren is op geheugenfouten. Dat is een indicatie, geen exacte wet van de natuur, maar het patroon is opvallend consistent tussen verschillende organisaties.
Er bestaan al langer verzachtende maatregelen die misbruik moeilijker maken zonder de onderliggende fout weg te nemen: ASLR (het willekeurig plaatsen van geheugenblokken, zodat een aanvaller adressen niet kan raden), DEP/NX (geheugen markeren als 'niet uitvoerbaar'), stack canaries (een soort geheime controlewaarde die verklikt of een buffer is overschreven) en Control Flow Integrity (controleren of een programma alleen naar toegestane plekken springt). Deze maatregelen zijn inmiddels standaard in vrijwel alle besturingssystemen, maar vastberaden aanvallers vinden geregeld manieren om ze te omzeilen.
De grotere verschuiving zit in geheugenveilige programmeertalen zoals Rust, en in nieuwere hardware zoals Arms Memory Tagging Extension en het experimentele CHERI-ontwerp van de Universiteit van Cambridge, die op chipniveau afdwingen dat geheugentoegang binnen de juiste grenzen blijft. Google rapporteerde dat het aandeel geheugenveiligheidslekken in nieuwe Android-code sterk daalde nadat delen van het besturingssysteem in Rust werden herschreven. Toch verloopt de overgang traag: miljarden regels bestaande C/C++-code herschrijf je niet in een paar jaar, en niet elk onderdeel leent zich daarvoor. Geheugencorruptie blijft daarom voorlopig een van de meest gebruikte inbraakroutes in geavanceerde cyberaanvallen.
Wie werken eraan?
Aan de verdedigende kant investeren vooral de grote softwarebedrijven zwaar. Google voert via zijn Project Zero-team en de Chrome- en Android-beveiligingsteams actief onderzoek uit en dringt aan op een bredere overstap naar Rust. Microsoft doet via het Microsoft Security Response Center vergelijkbaar werk en herschrijft stap voor stap onderdelen van de Windows-kernel in Rust. Apple bouwt hardwarematige beveiligingen zoals Pointer Authentication in zijn eigen chips.
Op academisch vlak loopt de Universiteit van Cambridge voorop met het CHERI-onderzoeksproject naar geheugenveilige hardware, mede gefinancierd door het Britse ministerie van Defensie en Arm. De Rust Foundation, met leden als Google, Microsoft, Amazon en Mozilla, onderhoudt en ontwikkelt de programmeertaal die inmiddels als belangrijkste alternatief voor C/C++ geldt.
Ook overheden mengen zich in het debat. De Amerikaanse cyberbeveiligingsdienst CISA en de NSA publiceerden de afgelopen jaren gezamenlijke richtlijnen die softwaremakers oproepen over te stappen op geheugenveilige talen, als onderdeel van een bredere 'secure by design'-beweging. Vergelijkbare aandacht is er bij het Nederlandse NCSC en de Europese ENISA, al blijft de praktische impact van dit soort beleidsdocumenten vooralsnog beperkt ten opzichte van de omvang van bestaande software.