House of Roman

Reading time: 5 minutes

tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Apoya a HackTricks

Información Básica

Esta fue una técnica muy interesante que permitió RCE sin leaks a través de fastbins falsos, el ataque unsorted_bin y sobreescrituras relativas. Sin embargo, ha sido parcheada.

Código

Objetivo

  • RCE abusando de punteros relativos

Requisitos

  • Editar punteros de fastbin y unsorted bin
  • 12 bits de aleatoriedad deben ser forzados por fuerza bruta (0.02% de probabilidad) de funcionar

Pasos de Ataque

Parte 1: Fastbin Chunk apunta a __malloc_hook

Crea varios chunks:

  • fastbin_victim (0x60, offset 0): Chunk UAF que se editará más tarde para apuntar 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): offset relativo en el chunk 'main_arena_use'

Luego free(main_arena_use) lo que colocará este chunk en la lista no ordenada y obtendrá un puntero a main_arena + 0x68 en ambos 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 relative_offset_heap y fastbin_victim son liberados.

c
/*
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 apuntando a relative_offset_heap
  • relative_offset_heap es un offset de distancia desde fake_libc_chunk, que contiene un puntero a main_arena + 0x68
  • Solo 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 lo modificamos para que el puntero apunte a __malloc_hook.

Nota que __memalign_hook generalmente comienza con 0x7f y ceros antes de él, por lo que 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 a donde nos interesa. Así que se realiza un ataque BF aquí para que el chunk termine como: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).

(Para más información sobre el resto de los bytes, consulta la explicación en el how2heap ejemplo). Si el BF no funciona, el programa simplemente se bloquea (así que comienza 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:

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

Parte 2: Ataque Unsorted_bin

Para 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:

c
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);

Usa un UAF en este bloque para apuntar unsorted_bin_ptr->bk a la dirección de __malloc_hook (esto lo forzamos previamente).

caution

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

Entonces, para activar la escritura de main_arena + 0x68 en __malloc_hook, después de establecer __malloc_hook en unsorted_bin_ptr->bk, solo necesitamos hacer: malloc(0x80)

Paso 3: Establecer __malloc_hook a 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 usar la dirección de libc que escribimos allí (main_arena + 0x68) para apuntar a una dirección one_gadget.

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

Finalmente, una vez que la dirección correcta es sobrescrita, llama a malloc y activa el one_gadget.

Referencias

tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Apoya a HackTricks