House of Roman

Apoie o HackTricks

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

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 alinhamento

  • main_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 um fd apontando para relative_offset_heap

  • relative_offset_heap é um deslocamento de distância de fake_libc_chunk, que contém um ponteiro para main_arena + 0x68

  • Apenas alterando o último byte de fastbin_victim.fd é possível fazer com que fastbin_victim aponte para main_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:

Unsorted Bin Attack

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).

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á.

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

Suporte ao HackTricks

Last updated