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

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

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 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:

c
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);

Partie 2 : Attaque Unsorted_bin

Pour plus d'infos, vous pouvez consulter :

Unsorted Bin Attack

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 exemple).

Enfin, une fois la bonne adresse écrasée, appelez malloc et déclenchez le one_gadget.

Références

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