7.1 KiB
Double Free
{% hint style="success" %}
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para os repositórios do HackTricks e HackTricks Cloud.
Basic Information
Se você liberar um bloco de memória mais de uma vez, isso pode bagunçar os dados do alocador e abrir a porta para ataques. Veja como isso acontece: quando você libera um bloco de memória, ele volta para uma lista de blocos livres (por exemplo, o "fast bin"). Se você liberar o mesmo bloco duas vezes seguidas, o alocador detecta isso e gera um erro. Mas se você liberar outro bloco no meio, a verificação de double-free é contornada, causando corrupção.
Agora, quando você pede 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 o mesmo local de memória. Se um atacante controla um desses ponteiros, ele pode alterar o conteúdo daquela memória, o que pode causar problemas de segurança ou até mesmo permitir que ele execute 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 *)i2);
return 0;
}
Neste exemplo, após preencher o tcache com vários chunks liberados (7), o código libera o chunk h
, depois o chunk i
, e então h
novamente, causando um double free (também conhecido como Fast Bin dup). 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 através de um ponteiro pode então afetar o outro, criando um risco crítico de segurança e potencial para exploração.
Executando, note como i1
e i2
obtiveram o mesmo endereço:
Alocações 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
Exemplos
- Dragon Army. Hack The Box
- Podemos alocar apenas chunks do tamanho Fast-Bin, exceto para o tamanho
0x70
, o que impede a sobrescrita usual de__malloc_hook
. - Em vez disso, usamos endereços PIE que começam com
0x56
como alvo para Fast Bin dup (1/2 de chance). - Um lugar onde os endereços PIE são armazenados é em
main_arena
, que está dentro do Glibc e perto de__malloc_hook
. - Alvo um deslocamento específico de
main_arena
para alocar um chunk lá e continuar alocando chunks até alcançar__malloc_hook
para obter execução de código. - zero_to_hero. PicoCTF
- Usando bins Tcache e um overflow de byte nulo, podemos alcançar uma situação de double-free:
- Alocamos três chunks de tamanho
0x110
(A
,B
,C
) - Liberamos
B
- Liberamos
A
e alocamos novamente para usar o overflow de byte nulo - Agora o campo de tamanho de
B
é0x100
, em vez de0x111
, então podemos liberá-lo novamente - Temos um Tcache-bin de tamanho
0x110
e um de tamanho0x100
que apontam para o mesmo endereço. Portanto, temos um double free. - Aproveitamos o double free usando Tcache poisoning
Referências
{% hint style="success" %}
Aprenda e pratique AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.