8.1 KiB
House of Roman
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Basic Information
Esta foi uma técnica muito interessante que permitiu RCE sem leaks através de fastbins falsos, o ataque unsorted_bin e sobrescritas relativas. No entanto, foi patchado.
Code
- Você pode encontrar um exemplo em https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Goal
- RCE abusando de ponteiros relativos
Requirements
- Editar ponteiros de fastbin e unsorted bin
- 12 bits de aleatoriedade devem ser forçados por brute force (0,02% de chance) de funcionar
Attack Steps
Part 1: Fastbin Chunk points to __malloc_hook
Crie vários chunks:
fastbin_victim
(0x60, offset 0): chunk UAF que será editado para apontar para o valor da LibC.chunk2
(0x80, offset 0x70): Para um bom alinhamentomain_arena_use
(0x80, offset 0x100)relative_offset_heap
(0x60, offset 0x190): offset relativo no chunk 'main_arena_use'
Então free(main_arena_use)
que colocará este chunk na lista não ordenada e obterá um ponteiro para main_arena + 0x68
tanto nos ponteiros fd
quanto bk
.
Agora é alocado um novo chunk fake_libc_chunk(0x60)
porque conterá os ponteiros para main_arena + 0x68
em fd
e bk
.
Então 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 offset de distância defake_libc_chunk
, que contém um ponteiro paramain_arena + 0x68
- Apenas mudando o último byte de
fastbin_victim.fd
é possível fazerfastbin_victim points
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
.
Note 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, há 2^4=16
possibilidades para o valor acabar apontando onde estamos interessados. Então, um ataque BF é realizado aqui para que o chunk termine como: 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 de novo até funcionar).
Então, 2 mallocs são realizados para remover os 2 chunks iniciais do fast bin e um terceiro é alocado para obter um chunk em __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 isso permite escrever main_arena + 0x68
em qualquer local especificado em chunk->bk
. E para o ataque, escolhemos __malloc_hook
. Então, 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 chunk para apontar unsorted_bin_ptr->bk
para o endereço de __malloc_hook
(nós forçamos isso anteriormente).
{% hint style="danger" %} Note que este ataque corrompe o bin não ordenado (portanto, pequeno e grande também). Então, só podemos usar alocações do fast bin agora (um programa mais complexo pode fazer outras alocações e travar), e para acionar isso, devemos alocar o mesmo tamanho ou o programa travará. {% endhint %}
Então, para acionar a escrita de main_arena + 0x68
em __malloc_hook
, após definir __malloc_hook
em unsorted_bin_ptr->bk
, só precisamos fazer: malloc(0x80)
Passo 3: Definir __malloc_hook para system
No primeiro passo, terminamos 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 um endereço one_gadget
.
Aqui é onde é necessário forçar 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)
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.