113 lines
6.2 KiB
Markdown

# House of Roman
{{#include ../../banners/hacktricks-training.md}}
## Informations de base
C'était une technique très intéressante qui permettait un RCE sans leaks via des fastbins factices, l'attaque unsorted_bin et des écrasements relatifs. Cependant, elle a été [**patchée**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).
### Code
- Vous pouvez trouver un exemple dans [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)
### Objectif
- RCE en abusant des pointeurs relatifs
### Exigences
- Modifier les pointeurs fastbin et unsorted bin
- 12 bits de randomisation doivent être brute-forcés (0,02 % de chance) de fonctionner
## Étapes de l'attaque
### Partie 1 : Le chunk Fastbin pointe vers \_\_malloc_hook
Créer plusieurs chunks :
- `fastbin_victim` (0x60, offset 0) : chunk UAF à éditer plus tard pour pointer vers la valeur LibC.
- `chunk2` (0x80, offset 0x70) : Pour un bon alignement
- `main_arena_use` (0x80, offset 0x100)
- `relative_offset_heap` (0x60, offset 0x190) : offset relatif sur le chunk 'main_arena_use'
Ensuite, `free(main_arena_use)` qui placera ce chunk dans la liste non triée et obtiendra un pointeur vers `main_arena + 0x68` dans les pointeurs `fd` et `bk`.
Maintenant, un nouveau chunk `fake_libc_chunk(0x60)` est alloué car il contiendra les pointeurs vers `main_arena + 0x68` dans `fd` et `bk`.
Ensuite, `relative_offset_heap` et `fastbin_victim` sont libérés.
```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` a un `fd` pointant vers `relative_offset_heap`
- `relative_offset_heap` est un offset de distance par rapport à `fake_libc_chunk`, qui contient un pointeur vers `main_arena + 0x68`
- En changeant simplement le dernier octet de `fastbin_victim.fd`, il est possible de faire pointer `fastbin_victim` vers `main_arena + 0x68`
Pour les actions précédentes, l'attaquant doit être capable de modifier le pointeur fd de `fastbin_victim`.
Ensuite, `main_arena + 0x68` n'est pas si intéressant, alors modifions-le pour que le pointeur pointe vers **`__malloc_hook`**.
Notez que `__memalign_hook` commence généralement par `0x7f` et des zéros avant, il est donc possible de le falsifier comme une valeur dans le fast bin `0x70`. Comme les 4 derniers bits de l'adresse sont **aléatoires**, il y a `2^4=16` possibilités pour que la valeur finisse par pointer là où nous sommes intéressés. Ainsi, une attaque BF est effectuée ici pour que le chunk se termine comme : **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`.**
(Pour plus d'infos sur le reste des octets, consultez l'explication dans le [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ exemple](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). Si le BF ne fonctionne pas, le programme plante simplement (donc recommencez jusqu'à ce que ça fonctionne).
Ensuite, 2 mallocs sont effectués pour supprimer les 2 premiers chunks de fast bin et un troisième est alloué pour obtenir un chunk dans le **`__malloc_hook:`**
```c
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
```
### Partie 2 : Attaque Unsorted_bin
Pour plus d'infos, vous pouvez consulter :
{{#ref}}
unsorted-bin-attack.md
{{#endref}}
Mais en gros, cela permet d'écrire `main_arena + 0x68` à n'importe quel emplacement spécifié dans `chunk->bk`. Et pour l'attaque, nous choisissons `__malloc_hook`. Ensuite, après l'avoir écrasé, nous utiliserons un écrasement relatif pour pointer vers un `one_gadget`.
Pour cela, nous commençons par obtenir un chunk et le mettre dans le **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);
```
Utilisez un UAF dans ce morceau pour pointer `unsorted_bin_ptr->bk` à l'adresse de `__malloc_hook` (nous l'avons bruteforcé précédemment).
> [!CAUTION]
> Notez que cette attaque corrompt le tas non trié (donc les petits et grands aussi). Nous ne pouvons donc **utiliser que des allocations du tas rapide maintenant** (un programme plus complexe pourrait faire d'autres allocations et planter), et pour déclencher cela, nous devons **allouer la même taille sinon le programme plantera.**
Donc, pour déclencher l'écriture de `main_arena + 0x68` dans `__malloc_hook`, nous effectuons après avoir défini `__malloc_hook` dans `unsorted_bin_ptr->bk`, nous devons juste faire : **`malloc(0x80)`**
### Étape 3 : Définir \_\_malloc_hook à system
Dans la première étape, nous avons fini par contrôler un morceau contenant `__malloc_hook` (dans la variable `malloc_hook_chunk`) et dans la deuxième étape, nous avons réussi à écrire `main_arena + 0x68` ici.
Maintenant, nous abusons d'un écrasement partiel dans `malloc_hook_chunk` pour utiliser l'adresse libc que nous y avons écrite (`main_arena + 0x68`) pour **pointer une adresse `one_gadget`**.
C'est ici qu'il est nécessaire de **bruteforcer 12 bits de random** (plus d'infos dans le [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ exemple](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).
Enfin, une fois la bonne adresse écrasée, **appelez `malloc` et déclenchez le `one_gadget`**.
## Références
- [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}}