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
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a HackTricks y HackTricks Cloud repos de github.
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
- Puedes encontrar un ejemplo en https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
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ónmain_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.
/*
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 unfd
apuntando arelative_offset_heap
relative_offset_heap
es un offset de distancia desdefake_libc_chunk
, que contiene un puntero amain_arena + 0x68
- Solo 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 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:
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Parte 2: Ataque Unsorted_bin
Para más información, puedes consultar:
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);
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
- 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/
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
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a HackTricks y HackTricks Cloud repos de github.