113 lines
5.9 KiB
Markdown

# House of Roman
{{#include ../../banners/hacktricks-training.md}}
## Informazioni di Base
Questa era una tecnica molto interessante che consentiva RCE senza leak tramite fake fastbins, l'attacco unsorted_bin e sovrascritture relative. Tuttavia è stata [**patchata**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).
### Codice
- Puoi trovare un esempio in [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)
### Obiettivo
- RCE abusando di puntatori relativi
### Requisiti
- Modificare i puntatori fastbin e unsorted bin
- 12 bit di casualità devono essere forzati (0.02% di possibilità) di funzionare
## Passi di Attacco
### Parte 1: Fastbin Chunk punta a \_\_malloc_hook
Crea diversi chunk:
- `fastbin_victim` (0x60, offset 0): chunk UAF da modificare successivamente per puntare al valore LibC.
- `chunk2` (0x80, offset 0x70): Per una buona allineamento
- `main_arena_use` (0x80, offset 0x100)
- `relative_offset_heap` (0x60, offset 0x190): offset relativo sul chunk 'main_arena_use'
Poi `free(main_arena_use)` che posizionerà questo chunk nella lista non ordinata e otterrà un puntatore a `main_arena + 0x68` sia nei puntatori `fd` che `bk`.
Ora viene allocato un nuovo chunk `fake_libc_chunk(0x60)` perché conterrà i puntatori a `main_arena + 0x68` in `fd` e `bk`.
Poi `relative_offset_heap` e `fastbin_victim` vengono liberati.
```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` ha un `fd` che punta a `relative_offset_heap`
- `relative_offset_heap` è un offset di distanza da `fake_libc_chunk`, che contiene un puntatore a `main_arena + 0x68`
- Cambiando semplicemente l'ultimo byte di `fastbin_victim.fd` è possibile far sì che `fastbin_victim punti` a `main_arena + 0x68`
Per le azioni precedenti, l'attaccante deve essere in grado di modificare il puntatore fd di `fastbin_victim`.
Poi, `main_arena + 0x68` non è così interessante, quindi modifichiamolo affinché il puntatore punti a **`__malloc_hook`**.
Nota che `__memalign_hook` di solito inizia con `0x7f` e zeri prima di esso, quindi è possibile falsificarlo come un valore nel fast bin `0x70`. Poiché gli ultimi 4 bit dell'indirizzo sono **random**, ci sono `2^4=16` possibilità per il valore finale a cui siamo interessati. Quindi qui viene eseguito un attacco BF affinché il chunk finisca come: **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`.**
(Per ulteriori informazioni sugli altri byte, controlla la spiegazione nell'[how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ esempio](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). Se il BF non funziona, il programma si blocca semplicemente (quindi inizia di nuovo finché non funziona).
Poi, vengono eseguiti 2 malloc per rimuovere i 2 chunk fast bin iniziali e un terzo viene allocato per ottenere un chunk in **`__malloc_hook:`**
```c
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
```
### Parte 2: Attacco Unsorted_bin
Per ulteriori informazioni puoi controllare:
{{#ref}}
unsorted-bin-attack.md
{{#endref}}
Ma fondamentalmente consente di scrivere `main_arena + 0x68` in qualsiasi posizione specificata in `chunk->bk`. E per l'attacco scegliamo `__malloc_hook`. Poi, dopo averlo sovrascritto, utilizzeremo una sovrascrittura relativa per puntare a un `one_gadget`.
Per questo iniziamo a ottenere un chunk e metterlo nel **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 in questo chunk per puntare `unsorted_bin_ptr->bk` all'indirizzo di `__malloc_hook` (lo abbiamo forzato precedentemente).
> [!CAUTION]
> Nota che questo attacco corrompe l'unsorted bin (quindi anche small e large). Quindi possiamo solo **usare allocazioni dal fast bin ora** (un programma più complesso potrebbe fare altre allocazioni e andare in crash), e per attivare questo dobbiamo **allocare la stessa dimensione o il programma andrà in crash.**
Quindi, per attivare la scrittura di `main_arena + 0x68` in `__malloc_hook` eseguiamo, dopo aver impostato `__malloc_hook` in `unsorted_bin_ptr->bk`, dobbiamo semplicemente fare: **`malloc(0x80)`**
### Passo 3: Imposta \_\_malloc_hook su system
Nel primo passo abbiamo finito per controllare un chunk contenente `__malloc_hook` (nella variabile `malloc_hook_chunk`) e nel secondo passo siamo riusciti a scrivere `main_arena + 0x68` qui.
Ora, abusiamo di un parziale overwrite in `malloc_hook_chunk` per usare l'indirizzo libc che abbiamo scritto lì (`main_arena + 0x68`) per **puntare a un indirizzo `one_gadget`**.
Qui è dove è necessario **forzare 12 bit di casualità** (maggiori informazioni nell'[how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ esempio](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).
Infine, una volta che l'indirizzo corretto è sovrascritto, **chiama `malloc` e attiva il `one_gadget`**.
## Riferimenti
- [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}}