hacktricks/binary-exploitation/heap/double-free.md
2024-12-12 13:56:11 +01:00

5.9 KiB

Dupla Liberação

Aprenda hacking AWS do zero ao avançado com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Informação Básica

Se você liberar um bloco de memória mais de uma vez, pode bagunçar os dados do alocador e abrir portas para ataques. Aqui está como isso acontece: quando você libera um bloco de memória, ele volta para uma lista de pedaços livres (por exemplo, o "fastbin"). Se você liberar o mesmo bloco duas vezes seguidas, o alocador detecta isso e lança um erro. Mas se você liberar outro pedaço no meio, a verificação de dupla liberação é contornada, causando corrupção.

Agora, quando você solicita nova memória (usando malloc), o alocador pode lhe dar um bloco que foi liberado duas vezes. Isso pode levar a dois ponteiros diferentes apontando para a mesma localização de memória. Se um atacante controlar um desses ponteiros, eles podem alterar o conteúdo dessa memória, o que pode causar problemas de segurança ou até permitir que eles executem código.

Exemplo:

#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 *)i1);

return 0;
}

Neste exemplo, após preencher o tcache com vários blocos liberados, o código libera o bloco h, em seguida o bloco i, e depois h novamente, causando um erro de double-free. Isso abre a possibilidade de receber endereços de memória sobrepostos ao realocar, significando que dois ou mais ponteiros podem apontar para a mesma localização de memória. Manipular dados por meio de um ponteiro pode então afetar o outro, criando um risco de segurança crítico e potencial para exploração.

Ao executá-lo, observe como i1 e i2 obtiveram o mesmo endereço:

Allocations iniciais:
a: 0xaaab0f0c22a0
b: 0xaaab0f0c22c0
c: 0xaaab0f0c22e0
d: 0xaaab0f0c2300
e: 0xaaab0f0c2320
f: 0xaaab0f0c2340
g: 0xaaab0f0c2360
h: 0xaaab0f0c2380
i: 0xaaab0f0c23a0
Após realocações:
a1: 0xaaab0f0c2360
b1: 0xaaab0f0c2340
c1: 0xaaab0f0c2320
d1: 0xaaab0f0c2300
e1: 0xaaab0f0c22e0
f1: 0xaaab0f0c22c0
g1: 0xaaab0f0c22a0
h1: 0xaaab0f0c2380
i1: 0xaaab0f0c23a0
i2: 0xaaab0f0c23a0

Referências

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks: