8.2 KiB
Casa do Romano
{% hint style="success" %}
Aprenda e pratique Hacking AWS:Treinamento HackTricks AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: Treinamento HackTricks GCP Red Team Expert (GRTE)
Apoie o HackTricks
- Verifique os planos de assinatura!
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para os repositórios HackTricks e HackTricks Cloud.
Informações Básicas
Esta foi uma técnica muito interessante que permitia RCE sem vazamentos através de fastbins falsos, ataque unsorted_bin e sobrescritas relativas. No entanto, ela foi corrigida.
Código
- Você pode encontrar um exemplo em https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Objetivo
- RCE abusando de ponteiros relativos
Requisitos
- Editar ponteiros fastbin e unsorted bin
- 12 bits de aleatoriedade devem ser forçados (0,02% de chance) de funcionar
Passos do Ataque
Parte 1: Chunk Fastbin aponta para __malloc_hook
Crie vários chunks:
fastbin_victim
(0x60, offset 0): Chunk UAF para editar posteriormente o ponteiro do heap para apontar para o valor do LibC.chunk2
(0x80, offset 0x70): Para um bom alinhamentomain_arena_use
(0x80, offset 0x100)relative_offset_heap
(0x60, offset 0x190): deslocamento relativo no chunk 'main_arena_use'
Em seguida, free(main_arena_use)
que colocará este chunk na lista não ordenada e obterá um ponteiro para main_arena + 0x68
nos ponteiros fd
e bk
.
Agora é alocado um novo chunk fake_libc_chunk(0x60)
porque ele conterá os ponteiros para main_arena + 0x68
em fd
e bk
.
Em seguida, relative_offset_heap
e fastbin_victim
são liberados.
/*
Current heap layout:
0x0: fastbin_victim - size 0x70
0x70: alignment_filler - size 0x90
0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main - size 0x20
0x190: relative_offset_heap - size 0x70
bin layout:
fastbin: fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
-
fastbin_victim
tem umfd
apontando pararelative_offset_heap
-
relative_offset_heap
é um deslocamento de distância defake_libc_chunk
, que contém um ponteiro paramain_arena + 0x68
- Apenas alterando o último byte de
fastbin_victim.fd
é possível fazer com quefastbin_victim
aponte paramain_arena + 0x68
Para as ações anteriores, o atacante precisa ser capaz de modificar o ponteiro fd de fastbin_victim
.
Então, main_arena + 0x68
não é tão interessante, então vamos modificá-lo para que o ponteiro aponte para __malloc_hook
.
Observe que __memalign_hook
geralmente começa com 0x7f
e zeros antes dele, então é possível falsificá-lo como um valor no fast bin 0x70
. Como os últimos 4 bits do endereço são aleatórios, existem 2^4=16
possibilidades para o valor terminar apontando para onde estamos interessados. Portanto, um ataque BF é realizado aqui para que o chunk termine assim: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)
.
(Para mais informações sobre o restante dos bytes, verifique a explicação no how2heap exemplo). Se o BF não funcionar, o programa simplesmente trava (então comece novamente até que funcione).
Em seguida, são realizados 2 mallocs para remover os 2 chunks iniciais do fast bin e um terceiro é alocado para obter um chunk no __malloc_hook:
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Parte 2: Ataque unsorted_bin
Para mais informações, você pode verificar:
{% content-ref url="unsorted-bin-attack.md" %} unsorted-bin-attack.md {% endcontent-ref %}
Mas basicamente permite escrever main_arena + 0x68
em qualquer local especificado em chunk->bk
. E para o ataque escolhemos __malloc_hook
. Em seguida, após sobrescrevê-lo, usaremos uma sobrescrita relativa para apontar para um one_gadget
.
Para isso, começamos obtendo um chunk e colocando-o no unsorted bin:
uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate
puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);
Use um UAF neste trecho para apontar unsorted_bin_ptr->bk
para o endereço de __malloc_hook
(já bruteforceamos isso anteriormente).
{% hint style="danger" %} Note que esse ataque corrompe o bin não ordenado (portanto também o pequeno e o grande). Assim, só podemos usar alocações do bin rápido agora (um programa mais complexo poderia fazer outras alocações e travar), e para acionar isso devemos alocar o mesmo tamanho ou o programa travará. {% endhint %}
Portanto, para acionar a escrita de main_arena + 0x68
em __malloc_hook
, realizamos após definir __malloc_hook
em unsorted_bin_ptr->bk
apenas precisamos fazer: malloc(0x80)
Passo 3: Definir __malloc_hook para system
No passo um, acabamos controlando um chunk contendo __malloc_hook
(na variável malloc_hook_chunk
) e no segundo passo conseguimos escrever main_arena + 0x68
aqui.
Agora, abusamos de uma sobrescrita parcial em malloc_hook_chunk
para usar o endereço da libc que escrevemos lá (main_arena + 0x68
) para apontar para um endereço de one_gadget
.
Aqui é onde é necessário bruteforce de 12 bits de aleatoriedade (mais informações no how2heap exemplo).
Finalmente, uma vez que o endereço correto é sobrescrito, chame malloc
e acione o one_gadget
.
Referências
- https://github.com/shellphish/how2heap
- https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/
{% 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)
Suporte ao HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para os repositórios do HackTricks e HackTricks Cloud.