7.3 KiB
Dupla Liberação
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Verifique os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe seus truques de hacking enviando PRs para os HackTricks e HackTricks Cloud repositórios do github.
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 a porta 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 "fast bin"). 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é mesmo 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 pedaços liberados (7), o código libera o pedaço h
, depois o pedaço i
e depois h
novamente, causando uma dupla liberação (também conhecida como Fast Bin dup). Isso abre a possibilidade de receber endereços de memória sobrepostos ao realocar, o que significa 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
Exemplos
- Dragon Army. Hack The Box
- Só podemos alocar pedaços do tamanho Fast Bin, exceto para o tamanho
0x70
, o que impede a substituição usual de__malloc_hook
. - Em vez disso, usamos endereços PIE que começam com
0x56
como alvo para Fast Bin dup (1/2 chance). - Um local onde os endereços PIE são armazenados é em
main_arena
, que está dentro do Glibc e próximo a__malloc_hook
. - Visamos um deslocamento específico de
main_arena
para alocar um pedaço lá e continuar alocando pedaços até chegar a__malloc_hook
para obter a execução de código. - zero_to_hero. PicoCTF
- Usando Tcache bins e um estouro de byte nulo, podemos alcançar uma situação de dupla liberação:
- Alocamos três pedaços de tamanho
0x110
(A
,B
,C
). - Liberamos
B
. - Liberamos
A
e alocamos novamente para usar o estouro 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 uma dupla liberação. - Aproveitamos a dupla liberação usando Tcache poisoning
Referências
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você quiser ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra The PEASS Family, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe seus truques de hacking enviando PRs para os repositórios HackTricks e HackTricks Cloud.