Double Free

Ondersteun HackTricks

Basiese Inligting

As jy 'n blok geheue meer as een keer vrylaat, kan dit die toewysersdata verwar en die deur oopmaak vir aanvalle. Hier is hoe dit gebeur: wanneer jy 'n blok geheue vrylaat, gaan dit terug in 'n lys van vrye stukke (bv. die "vinnige bin"). As jy dieselfde blok twee keer agtereenvolgens vrylaat, detecteer die toewysers dit en gooi 'n fout. Maar as jy 'n ander stuk tussenin vrylaat, word die dubbele-vry kontrole omseil, wat korrupsie veroorsaak.

Nou, wanneer jy nuwe geheue vra (met malloc), kan die toewysers jou 'n blok gee wat twee keer vrygelaat is. Dit kan lei tot twee verskillende punters wat na dieselfde geheue ligging wys. As 'n aanvaller een van daardie punters beheer, kan hulle die inhoud van daardie geheue verander, wat sekuriteitsprobleme kan veroorsaak of selfs toelaat dat hulle kode uitvoer.

Voorbeeld:

#include <stdio.h>
#include <stdlib.h>

int main() {
// Allocate memory for three chunks
char *a = (char *)malloc(10);
char *b = (char *)malloc(10);
char *c = (char *)malloc(10);
char *d = (char *)malloc(10);
char *e = (char *)malloc(10);
char *f = (char *)malloc(10);
char *g = (char *)malloc(10);
char *h = (char *)malloc(10);
char *i = (char *)malloc(10);

// Print initial memory addresses
printf("Initial allocations:\n");
printf("a: %p\n", (void *)a);
printf("b: %p\n", (void *)b);
printf("c: %p\n", (void *)c);
printf("d: %p\n", (void *)d);
printf("e: %p\n", (void *)e);
printf("f: %p\n", (void *)f);
printf("g: %p\n", (void *)g);
printf("h: %p\n", (void *)h);
printf("i: %p\n", (void *)i);

// Fill tcache
free(a);
free(b);
free(c);
free(d);
free(e);
free(f);
free(g);

// Introduce double-free vulnerability in fast bin
free(h);
free(i);
free(h);


// Reallocate memory and print the addresses
char *a1 = (char *)malloc(10);
char *b1 = (char *)malloc(10);
char *c1 = (char *)malloc(10);
char *d1 = (char *)malloc(10);
char *e1 = (char *)malloc(10);
char *f1 = (char *)malloc(10);
char *g1 = (char *)malloc(10);
char *h1 = (char *)malloc(10);
char *i1 = (char *)malloc(10);
char *i2 = (char *)malloc(10);

// Print initial memory addresses
printf("After reallocations:\n");
printf("a1: %p\n", (void *)a1);
printf("b1: %p\n", (void *)b1);
printf("c1: %p\n", (void *)c1);
printf("d1: %p\n", (void *)d1);
printf("e1: %p\n", (void *)e1);
printf("f1: %p\n", (void *)f1);
printf("g1: %p\n", (void *)g1);
printf("h1: %p\n", (void *)h1);
printf("i1: %p\n", (void *)i1);
printf("i2: %p\n", (void *)i2);

return 0;
}

In hierdie voorbeeld, nadat die tcache met verskeie vrygestelde stukke (7) gevul is, vry die stuk h, dan die stuk i, en dan weer h, wat 'n dubbele vrystelling veroorsaak (ook bekend as Fast Bin dup). Dit open die moontlikheid om oorvleuelende geheue adresse te ontvang wanneer herallokasie plaasvind, wat beteken dat twee of meer wysers na dieselfde geheue ligging kan wys. Deur data deur een wysers te manipuleer, kan dit dan die ander beïnvloed, wat 'n kritieke sekuriteitsrisiko en potensiaal vir uitbuiting skep.

Voer dit uit, let op hoe i1 en i2 dieselfde adres ontvang:

Begin toewysings:
a: 0xaaab0f0c22a0
b: 0xaaab0f0c22c0
c: 0xaaab0f0c22e0
d: 0xaaab0f0c2300
e: 0xaaab0f0c2320
f: 0xaaab0f0c2340
g: 0xaaab0f0c2360
h: 0xaaab0f0c2380
i: 0xaaab0f0c23a0
Na herallokasies:
a1: 0xaaab0f0c2360
b1: 0xaaab0f0c2340
c1: 0xaaab0f0c2320
d1: 0xaaab0f0c2300
e1: 0xaaab0f0c22e0
f1: 0xaaab0f0c22c0
g1: 0xaaab0f0c22a0
h1: 0xaaab0f0c2380
i1: 0xaaab0f0c23a0
i2: 0xaaab0f0c23a0

Voorbeelde

  • Ons kan slegs Fast-Bin-grootte stukke toewys, behalwe vir grootte 0x70, wat die gewone __malloc_hook oorskryding voorkom.

  • In plaas daarvan, gebruik ons PIE adresse wat met 0x56 begin as 'n teiken vir Fast Bin dup (1/2 kans).

  • Een plek waar PIE adresse gestoor word, is in main_arena, wat binne Glibc is en naby __malloc_hook

  • Ons teiken 'n spesifieke offset van main_arena om 'n stuk daar toe te wys en voort te gaan om stukke toe te wys totdat ons __malloc_hook bereik om kode-uitvoering te verkry.

  • Deur Tcache-bins en 'n null-byte oorgang te gebruik, kan ons 'n dubbele-vrystelling situasie bereik:

  • Ons wys drie stukke van grootte 0x110 (A, B, C)

  • Ons vry B

  • Ons vry A en wys weer om die null-byte oorgang te gebruik

  • Nou is B se grootte veld 0x100, in plaas van 0x111, so ons kan dit weer vry.

  • Ons het een Tcache-bin van grootte 0x110 en een van grootte 0x100 wat na dieselfde adres wys. So ons het 'n dubbele vrystelling.

  • Ons benut die dubbele vrystelling deur Tcache vergiftiging

Verwysings

Ondersteun HackTricks

Last updated