Wat is Bufferoverloop (buffer overflow)?

Meer gegevens schrijven naar een gebied zoals een array (een buffer) dan erin passen, waardoor het aangrenzende geheugen wordt beschadigd. In C gebeurt dit gemakkelijk met functies die de grootte van de bestemming niet kennen, zoals strcpy en gets, of met lussen die indexen gebruiken zonder het bereik te controleren, en het is ongedefinieerd gedrag. Als een buffer op de stack overloopt, kunnen lokale variabelen en het retouradres van de functie worden overschreven, wat kan worden misbruikt door aanvallen die via gemanipuleerde invoer willekeurige code uitvoeren. Het wordt voorkomen met functies die een grootte aannemen en met controles van het bereik.

Japanse benaming: バッファオーバーフロー

“Bufferoverloop (buffer overflow)” komt voor in 3 oefenvragen uit 2 onderwerpen, bijv. Linker, loader en uitvoerbare formaten, Basis van programmeren in C.

Vakgebied: Basis van programmeren in C

Veelvoorkomende oorzaken

Typische fouten zijn de 1 byte voor het afsluitende '\0' vergeten en met strcpy 8 tekens kopiëren naar char name[8], invoer met gets of scanf("%s") lezen zonder de lengte te controleren, en één element te veel schrijven, zoals in for (i = 0; i <= N; i++). Bij een functie die de grootte van de bestemming niet meekrijgt, bepalen de invoergegevens hoeveel er wordt geschreven.

Misbruik door aanvallen en tegenmaatregelen

Het retouradres van de functie staat dicht bij een buffer op de stack opgeslagen. Een aanvaller overschrijft het met lange invoer en leidt de uitvoering om naar voorbereide code of naar bibliotheekfuncties. Besturingssystemen en compilers maken misbruik moeilijker met stackbescherming (canaries), die een waarde vóór het retouradres controleert, scheiding van beschrijfbaar en uitvoerbaar geheugen (W^X) en randomisatie van adressen (ASLR).

Voorkomen in het programma

Gebruik in plaats van strcpy functies die de te schrijven grootte aannemen, zoals snprintf, en controleer altijd de lengte van invoer en het bereik van indexen. Tijdens de ontwikkeling detecteert -fsanitize=address (AddressSanitizer) schrijfacties buiten de grenzen tijdens de uitvoering. Op een microcontroller zonder MMU stopt een overloop het programma niet direct, maar beschadigt hij ongemerkt aangrenzende gegevens, dus daar is bijzondere voorzichtigheid nodig.

Nu oefenen: vragen over Bufferoverloop (buffer overflow)

Wat is het juiste doel van ASLR (address space layout randomization)?

  1. ADe adressen van stack, heap en bibliotheken bij elke uitvoering veranderen, zodat het moeilijk is te voorspellen welke adressen een aanvaller beoogt
  2. BGeheugenadressen willekeurig kiezen om het cachehitpercentage te verhogen
  3. COngebruikt geheugen willekeurig vrijgeven om de vrije capaciteit te vergroten
Antwoord en toelichting tonen

Antwoord: A. De adressen van stack, heap en bibliotheken bij elke uitvoering veranderen, zodat het moeilijk is te voorspellen welke adressen een aanvaller beoogt

Bij aanvallen die bijvoorbeeld bufferoverflows misbruiken, is het belangrijk de adressen van bibliotheekfuncties en data op de stack te kennen. ASLR verschuift bij elke start van een proces de adressen waarop stack, heap, gedeelde bibliotheken en het uitvoerbare bestand worden geplaatst, zodat aanvallers adressen niet vast kunnen aannemen. Het kan niet alleen volledig beschermen en wordt gecombineerd met andere maatregelen zoals scheiding van schrijven en uitvoeren.

Welke aanval is gemakkelijker te voorkomen door te verbieden dat een geheugenpagina tegelijk „beschrijfbaar” en „uitvoerbaar” is (W^X, scheiding van schrijven en uitvoeren)?

  1. AEen aanval die wachtwoorden met brute kracht probeert
  2. BEen aanval die met een grote hoeveelheid verkeer een server stillegt
  3. CEen aanval die machinecode voor de aanval in een datagebied zoals de stack schrijft en daar naartoe laat springen om uit te voeren
Antwoord en toelichting tonen

Antwoord: C. Een aanval die machinecode voor de aanval in een datagebied zoals de stack schrijft en daar naartoe laat springen om uit te voeren

Bij oude aanvallen werd vaak machinecode via een bufferoverflow op de stack geschreven en het terugkeeradres daarheen gericht om het uit te voeren. De paginatabel van de CPU heeft een bit voor uitvoeringsverbod (zoals het NX-bit); als het OS stack, heap en .data uitvoeren verbiedt en .text schrijven verbiedt, werkt deze methode niet meer. Bij code die tijdens uitvoering wordt gemaakt, zoals JIT-compilers, worden de rechten voor schrijven en uitvoeren omgeschakeld gebruikt.

Veelgestelde vragen

Stopt een bufferoverloop het programma altijd?

Niet noodzakelijk. Als de schrijfactie buiten de buffer in een ongebruikt gebied terechtkomt, lijkt er niets te gebeuren, en als ze een andere variabele beschadigt, geeft het programma ergens anders verkeerde resultaten. Het programma crasht soms pas als het retouradres is beschadigd of als de stackbescherming ingrijpt.

Is strncpy veilig?

strncpy kopieert hoogstens het opgegeven aantal tekens, maar als de bronstring langer is, voegt het geen afsluitende '\0' toe, zodat latere verwerking buiten de grenzen kan lezen. Gebruik snprintf, dat een grootte aanneemt en altijd een afsluiter toevoegt, of schrijf na strncpy zelf de afsluiter.

“Bufferoverloop (buffer overflow)” in de toelichting

Vragen met “Bufferoverloop (buffer overflow)” (3)

  1. Wat is het juiste doel van ASLR (address space layout randomization)?
  2. Welke aanval is gemakkelijker te voorkomen door te verbieden dat een geheugenpagina tegelijk „beschrijfbaar” en „uitvoerbaar” is (W^X, scheiding van schrijven en uitvoeren)?
  3. De string "ABCDEFGH" van 8 tekens werd aan de bovenstaande functie save doorgegeven. Wat gebeurt er?

Verwante termen

Stack (stapelgeheugen) Heap ASLR Paginatabel Variabele Retouradres Bitveld (bit-field) Dangling pointer Dynamische geheugentoewijzing Functiepointer

Naar de woordenlijst