House of Roman

Apoya a HackTricks

Información Básica

Esta fue una técnica muy interesante que permitía la ejecución remota de código sin fugas a través de fastbins falsos, el ataque unsorted_bin y sobrescrituras relativas. Sin embargo, ha sido parcheada.

Código

Objetivo

  • Ejecución remota de código abusando de punteros relativos

Requisitos

  • Editar punteros fastbin y unsorted bin

  • Se deben forzar 12 bits de aleatoriedad (0.02% de probabilidad) para que funcione

Pasos del Ataque

Parte 1: El Chunk Fastbin apunta a __malloc_hook

Crear varios chunks:

  • fastbin_victim (0x60, offset 0): Chunk UAF para editar más tarde el puntero del heap y que apunte al valor de LibC.

  • chunk2 (0x80, offset 0x70): Para una buena alineación

  • main_arena_use (0x80, offset 0x100)

  • relative_offset_heap (0x60, offset 0x190): desplazamiento relativo en el chunk 'main_arena_use'

Luego, free(main_arena_use) colocará este chunk en la lista desordenada y obtendrá un puntero a main_arena + 0x68 en los punteros fd y bk.

Ahora se asigna un nuevo chunk fake_libc_chunk(0x60) porque contendrá los punteros a main_arena + 0x68 en fd y bk.

Luego se liberan relative_offset_heap y fastbin_victim.

/*
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 tiene un fd que apunta a relative_offset_heap

  • relative_offset_heap es un desplazamiento de distancia desde fake_libc_chunk, que contiene un puntero a main_arena + 0x68

  • Simplemente cambiando el último byte de fastbin_victim.fd es posible hacer que fastbin_victim apunte a main_arena + 0x68

Para las acciones anteriores, el atacante necesita ser capaz de modificar el puntero fd de fastbin_victim.

Entonces, main_arena + 0x68 no es tan interesante, así que modifiquemos para que el puntero apunte a __malloc_hook.

Tenga en cuenta que __memalign_hook generalmente comienza con 0x7f y ceros antes de él, entonces es posible falsificarlo como un valor en el fast bin 0x70. Debido a que los últimos 4 bits de la dirección son aleatorios hay 2^4=16 posibilidades para que el valor termine apuntando donde estamos interesados. Por lo tanto, se realiza un ataque de fuerza bruta aquí para que el chunk termine así: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).

(Para obtener más información sobre el resto de los bytes, consulte la explicación en el how2heap ejemplo). Si la fuerza bruta no funciona, el programa simplemente se bloquea (así que comience de nuevo hasta que funcione).

Luego, se realizan 2 mallocs para eliminar los 2 chunks iniciales del fast bin y se asigna un tercero para obtener un chunk en el __malloc_hook:

malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);

Parte 2: Ataque unsorted_bin

Para obtener más información, puedes consultar:

Unsorted Bin Attack

Pero básicamente permite escribir main_arena + 0x68 en cualquier ubicación especificada en chunk->bk. Y para el ataque elegimos __malloc_hook. Luego, después de sobrescribirlo, utilizaremos una sobrescritura relativa para apuntar a un one_gadget.

Para esto comenzamos obteniendo un chunk y colocándolo en el 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);

Utiliza un UAF en este fragmento para apuntar unsorted_bin_ptr->bk a la dirección de __malloc_hook (lo hemos forzado previamente).

Ten en cuenta que este ataque corrompe el bin no ordenado (por lo tanto también el pequeño y el grande). Por lo tanto, solo podemos utilizar asignaciones del fast bin ahora (un programa más complejo podría hacer otras asignaciones y fallar), y para desencadenar esto debemos asignar el mismo tamaño o el programa fallará.

Entonces, para desencadenar la escritura de main_arena + 0x68 en __malloc_hook, simplemente debemos hacer: malloc(0x80)

Paso 3: Establecer __malloc_hook en system

En el primer paso terminamos controlando un chunk que contiene __malloc_hook (en la variable malloc_hook_chunk) y en el segundo paso logramos escribir main_arena + 0x68 aquí.

Ahora, abusamos de una sobrescritura parcial en malloc_hook_chunk para utilizar la dirección de libc que escribimos allí (main_arena + 0x68) para apuntar a una dirección de one_gadget.

Aquí es donde es necesario forzar 12 bits de aleatoriedad (más información en el how2heap ejemplo).

Finalmente, una vez que se sobrescribe la dirección correcta, llama a malloc y desencadena el one_gadget.

Referencias

Apoya a HackTricks

Last updated