hacktricks/binary-exploitation/libc-heap/house-of-roman.md

8.4 KiB

Maison de Roman

{% hint style="success" %} Apprenez et pratiquez le piratage AWS :Formation HackTricks AWS Red Team Expert (ARTE)
Apprenez et pratiquez le piratage GCP : Formation HackTricks GCP Red Team Expert (GRTE)

Soutenez HackTricks
{% endhint %}

Informations de base

Il s'agissait d'une technique très intéressante qui permettait une exécution de code à distance sans fuites via de faux fastbins, l'attaque unsorted_bin et des écrasements relatifs. Cependant, elle a été corrigée.

Code

Objectif

  • Exécution de code à distance en abusant des pointeurs relatifs

Exigences

  • Modifier les pointeurs fastbin et unsorted bin
  • 12 bits de hasard doivent être forcés (chance de 0,02 %) de fonctionner

Étapes de l'attaque

Partie 1 : Le chunk Fastbin pointe vers __malloc_hook

Créez plusieurs chunks :

  • fastbin_victim (0x60, décalage 0) : Chunk UAF pour éditer plus tard le pointeur du tas pour pointer vers la valeur LibC.
  • chunk2 (0x80, décalage 0x70) : Pour un bon alignement
  • main_arena_use (0x80, décalage 0x100)
  • relative_offset_heap (0x60, décalage 0x190) : décalage relatif sur le chunk 'main_arena_use'

Ensuite, free(main_arena_use) placera ce chunk dans la liste non triée et obtiendra un pointeur vers main_arena + 0x68 dans les pointeurs fd et bk.

Maintenant, allouez un nouveau chunk fake_libc_chunk(0x60) 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 un fd pointant vers relative_offset_heap
  • relative_offset_heap est un décalage de distance depuis 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 en sorte que fastbin_victim pointe 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 en tant que 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. Une attaque BF est donc effectuée ici pour que le chunk se termine comme suit: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).

(Pour plus d'informations sur le reste des octets, consultez l'explication dans l'exemple how2heap). Si le BF ne fonctionne pas, le programme plante simplement (donc recommencez jusqu'à ce que cela fonctionne).

Ensuite, 2 mallocs sont effectués pour supprimer les 2 chunks fast bin initiaux 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'informations, vous pouvez consulter :

{% content-ref url="unsorted-bin-attack.md" %} unsorted-bin-attack.md {% endcontent-ref %}

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 placer 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 chunk pour pointer unsorted_bin_ptr->bk vers l'adresse de __malloc_hook (nous l'avons déjà bruteforcée auparavant).

{% hint style="danger" %} Notez que cette attaque corrompt le unsorted bin (donc aussi small et large). Nous ne pouvons donc utiliser que des allocations du fast bin maintenant (un programme plus complexe pourrait effectuer d'autres allocations et planter), et pour déclencher cela, nous devons allouer la même taille ou le programme plantera. {% endhint %}

Ainsi, pour déclencher l'écriture de main_arena + 0x68 dans __malloc_hook, nous devons simplement faire : malloc(0x80)

Étape 3 : Définir __malloc_hook sur system

À l'étape un, nous avons fini par contrôler un chunk contenant __malloc_hook (dans la variable malloc_hook_chunk) et à la deuxième étape, nous avons réussi à écrire main_arena + 0x68 ici.

Maintenant, nous exploitons une écriture partielle dans malloc_hook_chunk pour utiliser l'adresse libc que nous avons écrite là (main_arena + 0x68) pour pointer vers une adresse one_gadget.

C'est ici qu'il est nécessaire de bruteforcer 12 bits de hasard (plus d'informations dans l'how2heap exemple).

Enfin, une fois que l'adresse correcte est écrasée, appelez malloc et déclenchez le one_gadget.

Références

{% hint style="success" %} Apprenez et pratiquez le Hacking AWS :Formation HackTricks AWS Red Team Expert (ARTE)
Apprenez et pratiquez le Hacking GCP : Formation HackTricks GCP Red Team Expert (GRTE)

Soutenez HackTricks
{% endhint %}