ASLR: hoe willekeurige geheugenadressen hackers dwarsbomen
Stel je een gebouw voor waarvan de kamers na elke sluitingstijd van plek wisselen: de directiekamer, de serverruimte, de kluis - ze staan er allemaal nog, maar een inbreker die gisteren de plattegrond heeft bestudeerd, staat vandaag voor een dichte muur. Zoiets doet ASLR, voluit Address Space Layout Randomization, met het geheugen van een computer. Het is een beveiligingstechniek die de locaties van programmaonderdelen in het werkgeheugen bij elke start willekeurig door elkaar husselt.
Zonder deze bescherming staan belangrijke onderdelen van een programma vaak op vaste, voorspelbare plekken in het geheugen. Een aanvaller die een fout in software weet te misbruiken, kan daardoor precies uitrekenen waar hij kwaadaardige code naartoe moet sturen. ASLR maakt dat gokwerk: de aanvaller weet niet meer waar iets staat, en een verkeerde gok laat het programma meestal simpelweg vastlopen in plaats van de aanvaller controle te geven.
Wat is het precies?
Elk programma dat draait, krijgt van het besturingssysteem een eigen adresruimte toegewezen: een genummerde reeks geheugenplekken waarin de code, de gegevens en tijdelijke werkruimte van dat programma leven. Van oudsher kozen besturingssystemen voor vaste, voorspelbare adressen voor onderdelen als de stack (het geheugen voor actieve functie-aanroepen), de heap (geheugen dat een programma tijdens het draaien zelf aanvraagt) en gedeelde bibliotheken (herbruikbare codeblokken zoals de standaardbibliotheek van een besturingssysteem).
ASLR verandert dat door bij elke opstart van een programma - of bij elke herstart van het systeem - deze onderdelen op een willekeurig gekozen offset (verschuiving) te plaatsen ten opzichte van hun normale locatie. De stack staat de ene keer hoger in het geheugen, de andere keer lager; hetzelfde geldt voor de heap en de bibliotheken.
Om ook de uitvoerbare code van het programma zelf te kunnen verplaatsen, moet die code geschikt zijn gemaakt als PIE (Position Independent Executable, positie-onafhankelijk uitvoerbaar bestand). Dat is code die overal in het geheugen kan draaien zonder dat er vaste adressen in zijn ingebakken. Programma's die niet als PIE zijn gecompileerd, missen dit deel van de bescherming, ook al draaien ze op een systeem met ASLR.
Ook de kernel - het besturingssysteemonderdeel dat rechtstreeks met de hardware praat en de hoogste rechten heeft - kan worden gerandomiseerd. Dat heet KASLR (Kernel ASLR) en kwam later dan gewone ASLR, omdat het ingewikkelder is om een systeem dat alles aanstuurt zelf ook nog eens te verplaatsen.
Hoeveel bescherming ASLR biedt, hangt sterk af van de entropie: het aantal mogelijke posities waaruit willekeurig wordt gekozen. Op 32-bit systemen is de adresruimte klein, waardoor er maar een beperkt aantal mogelijke locaties is - een aanvaller kan die soms binnen afzienbare tijd stuk voor stuk uitproberen (brute force). Op 64-bit systemen is de adresruimte enorm veel groter, wat gokken vrijwel onmogelijk maakt.
Wat wil men ermee bereiken?
ASLR is een antwoord op een familie van aanvallen die misbruik maken van geheugenfouten in software, met de buffer overflow als bekendste voorbeeld: een programma schrijft meer gegevens in een geheugenblok dan erin past, waardoor aangrenzend geheugen wordt overschreven. Als een aanvaller dat overschrijven zo weet te sturen dat hij eigen instructies laat uitvoeren, heeft hij in feite de controle over het programma overgenomen.
Klassieke exploittechnieken zoals return-to-libc (waarbij een aanvaller de uitvoering laat springen naar bestaande, vertrouwde bibliotheekcode om die voor eigen doeleinden te misbruiken) en ROP, Return Oriented Programming (waarbij kleine stukjes bestaande code achter elkaar worden geketend tot een nieuwe, kwaadaardige functie), zijn allemaal afhankelijk van het kennen van exacte geheugenadressen. Zonder die kennis werkt de aanval niet.
Het doel van ASLR is dus niet om geheugenfouten te voorkomen - die blijven gewoon bestaan - maar om ze veel lastiger te misbruiken. Dit past in een bredere aanpak die in de beveiligingswereld defense in depth heet: meerdere onafhankelijke verdedigingslagen, zodat het doorbreken van één laag niet meteen tot volledige overname leidt. ASLR wordt daarom nadrukkelijk niet als wondermiddel gepresenteerd, maar als een van de vele hindernissen die een aanval duurder en onzekerder maken.
Voorbeelden uit de praktijk
Het PaX-project, een pseudoniem team van Linux-beveiligingsontwikkelaars, publiceerde rond 2001 de eerste praktisch bruikbare ASLR-implementatie als patch voor de Linux-kernel. Dit werk legde de technische basis waarop latere, bredere implementaties voortbouwden.
In 2003 bracht Red Hat, mede ontwikkeld door kernelontwikkelaar Ingo Molnar, exec-shield uit: een lichtere vorm van adresrandomisatie die in Red Hat Enterprise Linux terechtkwam en zo een van de eerste keren was dat gewone gebruikers ASLR-achtige bescherming kregen zonder er zelf iets voor te hoeven doen.
Microsoft introduceerde systeembrede ASLR voor het eerst in Windows Vista in 2007, als onderdeel van een grotere reeks beveiligingsmaatregelen in die release. Latere Windows-versies bouwden dit verder uit.
Apple voegde ASLR toe aan mobiele apparaten met iOS 4.3 in 2011, nadat het eerder al in Mac OS X was doorgevoerd. Rond diezelfde tijd, met Android 4.0 (Ice Cream Sandwich) in 2011, kreeg ook Google's mobiele besturingssysteem volledige ASLR-ondersteuning.
De Linux-kernel zelf kreeg pas in versie 3.14, uitgebracht in 2014, ingebouwde KASLR-ondersteuning zonder externe patches - een teken van hoe lang het kan duren voordat een beveiligingsidee van experimentele patch tot standaardonderdeel van een mainstream systeem wordt.
Hoe ver is de techniek?
ASLR is inmiddels geen experimentele techniek meer, maar een standaardvoorziening in vrijwel elk hedendaags besturingssysteem: Windows, macOS, de meeste Linux-distributies, iOS en Android schakelen het tegenwoordig standaard in. In die zin is de techniek volwassen en breed uitgerold.
Toch is de wapenwedloop niet gestreden. De belangrijkste zwakte van ASLR is het informatielek (information leak): een aparte fout waardoor een aanvaller alsnog een geheugenadres te weten komt, bijvoorbeeld via een foutmelding of een programma dat per ongeluk een pointer (geheugenverwijzing) prijsgeeft. Met dat ene lekkende adres kan de rest van de randomisatie soms worden teruggerekend.
Op oudere 32-bit systemen met beperkte entropie is daarnaast pure brute force in sommige gevallen haalbaar gebleken: door een aanval simpelweg te herhalen met verschillende gegokte adressen. Op moderne 64-bit systemen is dat in de praktijk vrijwel onhaalbaar geworden door de veel grotere adresruimte.
Een fundamentelere klap kwam in 2018, toen onderzoekers de Meltdown- en Spectre-kwetsbaarheden onthulden. Deze maakten gebruik van side-channel-aanvallen - technieken die informatie afleiden uit indirecte signalen, zoals timingverschillen in de processor - en konden daarmee onder bepaalde omstandigheden KASLR omzeilen zonder een klassiek geheugenlek. Dit liet zien dat zelfs een goed geïmplementeerde randomisatietechniek kwetsbaar kan zijn voor aanvallen op een heel ander niveau, namelijk de hardware zelf.
Mede daarom wordt ASLR in de praktijk vrijwel nooit alleen ingezet. Het wordt gecombineerd met DEP/NX (Data Execution Prevention / No-eXecute), dat voorkomt dat gegevensgeheugen als uitvoerbare code wordt behandeld, met stack canaries (kleine controlewaarden die geheugenbeschadiging op de stack detecteren), en met nieuwere technieken als CFG/CFI (Control Flow Guard bij Microsoft, Control Flow Integrity als algemeen concept), die controleren of de uitvoering van een programma alleen naar toegestane plekken springt. Onafhankelijke beveiligingsonderzoekers zijn het er breed over eens dat ASLR een nuttige maar op zichzelf onvoldoende maatregel is.
Wie werken eraan?
Het pseudonieme PaX Team geldt als grondlegger van praktische ASLR voor Linux en blijft via het gerelateerde grsecurity-project actief in het ontwikkelen van geheugenbeveiliging. Red Hat, met destijds Ingo Molnar als kernontwikkelaar, bracht de techniek met exec-shield naar een breder publiek van Linux-gebruikers.
Bij Microsoft werkt het Windows-beveiligingsteam voortdurend aan verdere verfijning van ASLR en aanverwante mitigaties zoals Control Flow Guard. Apple onderhoudt en verbetert ASLR-implementaties voor zowel macOS als iOS als onderdeel van zijn platformbeveiliging. Google doet hetzelfde voor Android en voor de sandboxing-technieken in de Chrome-browser, waarbij ASLR een van de vele verdedigingslagen vormt.
De bredere Linux-kernelgemeenschap, bestaande uit honderden onafhankelijke ontwikkelaars en bedrijven wereldwijd, onderhoudt de KASLR-implementatie in de mainline-kernel. Daarnaast dragen academische onderzoeksgroepen aan universiteiten voortdurend bij door zowel nieuwe omzeilingstechnieken (zoals bij het Meltdown/Spectre-onderzoek) als nieuwe verdedigingsmethoden te publiceren, in een voortdurende wisselwerking tussen aanval en verdediging die het vakgebied vooruit blijft duwen.