mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
113 lines
5.9 KiB
Markdown
113 lines
5.9 KiB
Markdown
# House of Roman
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## 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**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).
|
|
|
|
### Código
|
|
|
|
- Puedes encontrar un ejemplo en [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](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 del 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)` 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 se liberan `relative_offset_heap` y `fastbin_victim`.
|
|
```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` que apunta 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 modifiquémoslo 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](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ ejemplo](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). 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:
|
|
|
|
{{#ref}}
|
|
unsorted-bin-attack.md
|
|
{{#endref}}
|
|
|
|
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 fragmento 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 sin ordenar (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 de `one_gadget`**.
|
|
|
|
Aquí es donde es necesario **forzar 12 bits de aleatoriedad** (más información en el [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ ejemplo](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).
|
|
|
|
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)
|
|
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](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/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/)
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|