.. | ||
use-after-free | ||
bins-and-memory-allocations.md | ||
double-free.md | ||
fast-bin-attack.md | ||
heap-functions-security-checks.md | ||
heap-overflow.md | ||
house-of-einherjar.md | ||
house-of-force.md | ||
house-of-lore.md | ||
house-of-orange.md | ||
house-of-spirit.md | ||
large-bin-attack.md | ||
off-by-one-overflow.md | ||
overwriting-a-freed-chunk.md | ||
README.md | ||
tcache-bin-attack.md | ||
unlink-attack.md | ||
unsorted-bin-attack.md | ||
use-after-free.md |
Heap
Heap Basies
Die heap is basies die plek waar 'n program data kan stoor wanneer dit data aanvra deur funksies soos malloc
, calloc
... Daarbenewens, wanneer hierdie geheue nie meer nodig is nie, word dit beskikbaar gestel deur die funksie free
te roep.
Soos getoon, is dit net na waar die binêre lêer in die geheue gelaai word (kyk na die [heap]
afdeling):
Basiese Stuk Toekenning
Wanneer daar versoek word dat sekere data in die heap gestoor moet word, word 'n deel van die heap daaraan toegewys. Hierdie spasie behoort aan 'n bin en slegs die versoekte data + die spasie van die bin koppe + minimum bin grootte offset sal vir die stuk gereserveer word. Die doel is om so min moontlik geheue te reserveer sonder om dit moeilik te maak om te vind waar elke stuk is. Hiervoor word die metadata stuk inligting gebruik om te weet waar elke gebruikte/vrye stuk is.
Daar is verskillende maniere om die spasie te reserveer, hoofsaaklik afhangende van die gebruikte bin, maar 'n algemene metodologie is as volg:
- Die program begin deur 'n sekere hoeveelheid geheue aan te vra.
- As daar in die lys van stukke iemand beskikbaar is wat groot genoeg is om aan die versoek te voldoen, sal dit gebruik word.
- Dit kan selfs beteken dat 'n deel van die beskikbare stuk vir hierdie versoek gebruik sal word en die res sal by die stukke lys gevoeg word.
- As daar geen beskikbare stuk in die lys is nie, maar daar steeds spasie in die toegewysde heap-geheue is, skep die heap-bestuurder 'n nuwe stuk.
- As daar nie genoeg heap-geheue is om die nuwe stuk toe te ken nie, vra die heap-bestuurder die kernel om die geheue wat aan die heap toegeken is, uit te brei en gebruik dan hierdie geheue om die nuwe stuk te genereer.
- As alles misluk, gee
malloc
null terug.
Let daarop dat as die versoekte geheue 'n drempel oorskry, mmap
gebruik sal word om die versoekte geheue in te kaart.
Arenas
In multidraad-toepassings moet die heap-bestuurder wedloop-toestande voorkom wat tot ongelukke kan lei. Aanvanklik is dit gedoen deur 'n globale grendel te gebruik om te verseker dat slegs een draad op 'n slag toegang tot die heap kon verkry, maar dit het prestasieprobleme veroorsaak as gevolg van die grendel-geïnduseerde knelpunt.
Om dit aan te spreek, het die ptmalloc2 heap-toewysingsprogram "arenas" ingevoer, waar elke arena as 'n afsonderlike heap optree met sy eie data strukture en grendel, wat dit vir meerdere drade moontlik maak om heap-operasies uit te voer sonder om met mekaar te bots, solank hulle verskillende arenas gebruik.
Die verstek "hoof" arena hanteer heap-operasies vir enkel-draad-toepassings. Wanneer nuwe drade bygevoeg word, ken die heap-bestuurder hulle sekondêre arenas toe om kontensie te verminder. Dit probeer eers om elke nuwe draad aan 'n ongebruikte arena te koppel, nuwes te skep indien nodig, tot 'n limiet van 2 keer die CPU-kerns vir 32-bis-stelsels en 8 keer vir 64-bis-stelsels. Sodra die limiet bereik is, moet drade arenas deel, wat tot potensiële kontensie kan lei.
In teenstelling met die hoof arena, wat uitbrei deur die brk
stelseloproep te gebruik, skep sekondêre arenas "subheape" deur mmap
en mprotect
te gebruik om die heap-gedrag na te boots, wat buigsaamheid bied om geheue vir multidraad-operasies te bestuur.
Subheape
Subheape dien as geheue-reserwes vir sekondêre arenas in multidraad-toepassings, wat hulle in staat stel om te groei en hul eie heap-gebiede afsonderlik van die hoofheap te bestuur. Hier is hoe subheape verskil van die aanvanklike heap en hoe hulle werk:
- Aanvanklike Heap vs. Subheape:
- Die aanvanklike heap is direk na die program se binêre in die geheue geleë, en dit brei uit deur die
sbrk
stelseloproep te gebruik. - Subheape, wat deur sekondêre arenas gebruik word, word geskep deur
mmap
, 'n stelseloproep wat 'n gespesifiseerde geheue-gebied in kaart bring.
- Geheue Reservering met
mmap
:
- Wanneer die heap-bestuurder 'n subheap skep, reserveer dit 'n groot blok geheue deur
mmap
. Hierdie reservering ken nie onmiddellik geheue toe nie; dit dui eenvoudig 'n gebied aan wat ander stelselprosesse of toekennings nie moet gebruik nie. - Standaard is die gereserveerde grootte vir 'n subheap 1 MB vir 32-bis prosesse en 64 MB vir 64-bis prosesse.
- Gegradueerde Uitbreiding met
mprotect
:
- Die gereserveerde geheue-gebied word aanvanklik gemerk as
PROT_NONE
, wat aandui dat die kernel nie fisiese geheue aan hierdie spasie hoef toe te ken nie. - Om die subheap te "groei", gebruik die heap-bestuurder
mprotect
om bladsy-toestemmings vanPROT_NONE
naPROT_READ | PROT_WRITE
te verander, wat die kernel aanspoor om fisiese geheue aan die voorheen gereserveerde adresse toe te ken. Hierdie stap-vir-stap benadering laat die subheap toe om soos nodig uit te brei. - Sodra die hele subheap uitgeput is, skep die heap-bestuurder 'n nuwe subheap om voort te gaan met toekenning.
malloc_state
Elke heap (hoof arena of ander draad-arenas) het 'n malloc_state
struktuur.
Dit is belangrik om op te merk dat die hoof arena malloc_state
e
struktuur 'n globale veranderlike in die libc is (dus geleë in die libc-geheue-ruimte).
In die geval van malloc_state
strukture van die heaps van drade, is hulle geleë binne eie draad "heap".
Daar is 'n paar interessante dinge om van hierdie struktuur te let (sien C-kode hieronder):
- Die
mchunkptr bins[NBINS * 2 - 2];
bevat aanwysers na die eerste en laaste stukke van die klein, groot en ongesorteerde bins (die -2 is omdat die indeks 0 nie gebruik word nie) - Daarom sal die eerste stuk van hierdie bins 'n agterwaartse aanwyser na hierdie struktuur hê en die laaste stuk van hierdie bins sal 'n voorwaartse aanwyser na hierdie struktuur hê. Dit beteken basies dat as jy hierdie adresse in die hoof arena kan lek, sal jy 'n aanwyser na die struktuur in die libc hê.
- Die strukture
struct malloc_state *next;
enstruct malloc_state *next_free;
is gekoppelde lyste van arenas - Die
top
stuk is die laaste "stuk", wat basies al die oorblywende heap-geheue is. Sodra die top stuk "leeg" is, is die heap heeltemal gebruik en moet meer spasie aangevra word. - Die
last reminder
stuk kom uit gevalle waar 'n presiese grootte stuk nie beskikbaar is nie en daarom 'n groter stuk gesplit word, 'n aanwysende oorblywende deel word hier geplaas.
// From https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/malloc_state
struct malloc_state
{
/* Serialize access. */
__libc_lock_define (, mutex);
/* Flags (formerly in max_fast). */
int flags;
/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];
/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;
/* The remainder from the most recent split of a small request */
mchunkptr last_remainder;
/* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2];
/* Bitmap of bins */
unsigned int binmap[BINMAPSIZE];
/* Linked list */
struct malloc_state *next;
/* Linked list for free arenas. Access to this field is serialized
by free_list_lock in arena.c. */
struct malloc_state *next_free;
/* Number of threads attached to this arena. 0 if the arena is on
the free list. Access to this field is serialized by
free_list_lock in arena.c. */
INTERNAL_SIZE_T attached_threads;
/* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};
typedef struct malloc_state *mstate;
malloc_chunk
Hierdie struktuur verteenwoordig 'n spesifieke stuk geheue. Die verskillende velde het verskillende betekenisse vir toegewysde en nie-toegewysde stukke.
// From https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/malloc_chunk
struct malloc_chunk {
INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk, if it is free. */
INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk_nextsize;
};
typedef struct malloc_chunk* mchunkptr;
Soos voorheen opgemerk, het hierdie brokke ook metadata, baie goed verteenwoordig in hierdie beeld:
Die metadata is gewoonlik 0x08B wat die huidige brokkie-grootte aandui deur die laaste 3 bits te gebruik om aan te dui:
A
: As 1, kom dit van 'n subheap af, as 0 is dit in die hoof-arenaM
: As 1, is hierdie brokkie deel van 'n spasie wat toegewys is met mmap en nie deel van 'n heap nieP
: As 1, is die vorige brokkie in gebruik
Dan die spasie vir die gebruikersdata, en uiteindelik 0x08B om die vorige brokkie-grootte aan te dui wanneer die brokkie beskikbaar is (of om gebruikersdata te stoor wanneer dit toegewys is).
Verder, wanneer beskikbaar, word die gebruikersdata ook gebruik om ook 'n paar data te bevat:
- Aanwysing na die volgende brokkie
- Aanwysing na die vorige brokkie
- Grootte van die volgende brokkie in die lys
- Grootte van die vorige brokkie in die lys
{% hint style="info" %} Merk op hoe die lys op hierdie manier rangskik die behoefte verhoed om 'n array te hê waar elke enkele brokkie geregistreer word. {% endhint %}
Vinnige Heap Voorbeeld
Vinnige heap voorbeeld van https://guyinatuxedo.github.io/25-heap/index.html maar in arm64:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(void)
{
char *ptr;
ptr = malloc(0x10);
strcpy(ptr, "panda");
}
Stel 'n breekpunt in aan die einde van die hooffunksie en laat ons uitvind waar die inligting gestoor was:
Dit is moontlik om te sien dat die string panda gestoor was by 0xaaaaaaac12a0
(wat die adres was wat as reaksie deur malloc binne x0
gegee is). Deur 0x10 byte voor dit te ondersoek, is dit moontlik om te sien dat die 0x0
aandui dat die vorige blok nie gebruik word (lengte 0 nie) en dat die lengte van hierdie blok 0x21
is.
Die ekstra spasies wat voorbehou is (0x21-0x10=0x11) kom van die bygevoegde koppe (0x10) en 0x1 beteken nie dat daar 0x21B voorbehou is nie, maar die laaste 3 bits van die lengte van die huidige kop het 'n paar spesiale betekenisse. Aangesien die lengte altyd 16-byte uitgelyn is (op 64-bits masjiene), gaan hierdie bits eintlik nooit deur die lengtenommer gebruik word nie.
0x1: Previous in Use - Specifies that the chunk before it in memory is in use
0x2: Is MMAPPED - Specifies that the chunk was obtained with mmap()
0x4: Non Main Arena - Specifies that the chunk was obtained from outside of the main arena
Bins & Geheue-toekennings/Vrymakings
Kyk wat die bakkies is en hoe hulle georganiseer is en hoe geheue toegewys en vrygemaak word in:
{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}
Heap Funksies Sekuriteitskontroles
Funksies betrokke by die heap sal sekere kontroles uitvoer voordat hulle hul aksies uitvoer om te probeer verseker dat die heap nie gekorrup is nie:
{% content-ref url="heap-functions-security-checks.md" %} heap-functions-security-checks.md {% endcontent-ref %}