House of Roman
Reading time: 5 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.
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.
Code
- Vous pouvez trouver un exemple dans 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 alignementmain_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.
/*
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 unfd
pointant versrelative_offset_heap
relative_offset_heap
est un offset de distance par rapport àfake_libc_chunk
, qui contient un pointeur versmain_arena + 0x68
- En changeant simplement le dernier octet de
fastbin_victim.fd
, il est possible de faire pointerfastbin_victim
versmain_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 exemple). 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:
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Partie 2 : Attaque Unsorted_bin
Pour plus d'infos, vous pouvez consulter :
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 :
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 exemple).
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/blob/master/glibc_2.23/house_of_roman.c
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.