# 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}}