House of Roman
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
Puedes encontrar un ejemplo en https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
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ónmain_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
.
fastbin_victim
tiene unfd
que apunta arelative_offset_heap
relative_offset_heap
es un desplazamiento de distancia desdefake_libc_chunk
, que contiene un puntero amain_arena + 0x68
Simplemente cambiando el último byte de
fastbin_victim.fd
es posible hacer quefastbin_victim apunte
amain_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:
Parte 2: Ataque unsorted_bin
Para obtener más información, puedes consultar:
Unsorted Bin AttackPero 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:
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
Last updated