Maison de l'Orange

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

Code

Objectif

  • Abuser de la fonction malloc_printerr

Exigences

  • Écraser la taille du chunk supérieur
  • Fuites de libc et de heap

Contexte

Quelques informations nécessaires provenant des commentaires de cet exemple:

Le fait est que, dans les anciennes versions de libc, lorsque la fonction malloc_printerr était appelée, elle itérerait à travers une liste de structures _IO_FILE stockées dans _IO_list_all, et exécuterait en fait un pointeur d'instruction dans cette structure.
Cette attaque va forger une fausse structure _IO_FILE que nous allons écrire dans _IO_list_all, et provoquer l'exécution de malloc_printerr.\ Ensuite, elle exécutera n'importe quelle adresse que nous avons stockée dans la table de saut des structures _IO_FILE, et nous obtiendrons une exécution de code.

Attaque

L'attaque commence par réussir à obtenir le chunk supérieur à l'intérieur de la bin non triée. Cela est réalisé en appelant malloc avec une taille supérieure à la taille actuelle du chunk supérieur mais inférieure à mmp_.mmap_threshold (la valeur par défaut est 128K), ce qui déclencherait autrement une allocation mmap. Chaque fois que la taille du chunk supérieur est modifiée, il est important de s'assurer que le chunk supérieur + sa taille est aligné sur une page et que le bit prev_inuse du chunk supérieur est toujours défini.

Pour obtenir le chunk supérieur à l'intérieur de la bin non triée, allouez un chunk pour créer le chunk supérieur, changez la taille du chunk supérieur (avec un dépassement dans le chunk alloué) afin que chunk supérieur + taille soit aligné sur une page avec le bit prev_inuse défini. Ensuite, allouez un chunk plus grand que la nouvelle taille du chunk supérieur. Notez que free n'est jamais appelé pour obtenir le chunk supérieur dans la bin non triée.

L'ancien chunk supérieur est maintenant dans la bin non triée. En supposant que nous puissions lire des données à l'intérieur (possiblement en raison d'une vulnérabilité qui a également causé le dépassement), il est possible de fuir des adresses libc à partir de celui-ci et d'obtenir l'adresse de _IO_list_all.

Une attaque de bin non triée est effectuée en abusant du dépassement pour écrire topChunk->bk->fwd = _IO_list_all - 0x10. Lorsqu'un nouveau chunk est alloué, l'ancien chunk supérieur sera divisé, et un pointeur vers la bin non triée sera écrit dans _IO_list_all.

L'étape suivante consiste à réduire la taille de l'ancien chunk supérieur pour qu'il s'adapte à une petite bin, en définissant spécifiquement sa taille à 0x61. Cela sert deux objectifs :

  1. Insertion dans la petite bin 4 : Lorsque malloc parcourt la bin non triée et voit ce chunk, il essaiera de l'insérer dans la petite bin 4 en raison de sa petite taille. Cela fait que le chunk se retrouve en tête de la liste de la petite bin 4, qui est l'emplacement du pointeur FD du chunk de _IO_list_all car nous avons écrit une adresse proche dans _IO_list_all via l'attaque de la bin non triée.
  2. Déclenchement d'un contrôle de Malloc : Cette manipulation de la taille du chunk provoquera malloc à effectuer des vérifications internes. Lorsqu'il vérifie la taille du faux chunk avant, qui sera zéro, cela déclenche une erreur et appelle malloc_printerr.

La manipulation de la petite bin vous permettra de contrôler le pointeur avant du chunk. Le chevauchement avec _IO_list_all est utilisé pour forger une fausse structure _IO_FILE. La structure est soigneusement conçue pour inclure des champs clés comme _IO_write_base et _IO_write_ptr définis sur des valeurs qui passent les vérifications internes dans libc. De plus, une table de saut est créée dans la fausse structure, où un pointeur d'instruction est défini à l'adresse où un code arbitraire (par exemple, la fonction system) peut être exécuté.

Pour résumer la partie restante de la technique :

  • Réduire l'ancien chunk supérieur : Ajustez la taille de l'ancien chunk supérieur à 0x61 pour l'adapter à une petite bin.
  • Configurer la fausse structure _IO_FILE : Chevauchez l'ancien chunk supérieur avec la fausse structure _IO_FILE et définissez les champs de manière appropriée pour détourner le flux d'exécution.

L'étape suivante consiste à forger une fausse structure _IO_FILE qui chevauche l'ancien chunk supérieur actuellement dans la bin non triée. Les premiers octets de cette structure sont soigneusement conçus pour inclure un pointeur vers une commande (par exemple, "/bin/sh") qui sera exécutée.

Les champs clés dans la fausse structure _IO_FILE, tels que _IO_write_base et _IO_write_ptr, sont définis sur des valeurs qui passent les vérifications internes dans libc. De plus, une table de saut est créée dans la fausse structure, où un pointeur d'instruction est défini à l'adresse où un code arbitraire peut être exécuté. En général, cela serait l'adresse de la fonction system ou une autre fonction qui peut exécuter des commandes shell.

L'attaque culmine lorsqu'un appel à malloc déclenche l'exécution du code via la structure _IO_FILE manipulée. Cela permet effectivement l'exécution de code arbitraire, entraînant généralement le lancement d'un shell ou l'exécution d'une autre charge utile malveillante.

Résumé de l'attaque :

  1. Configurer le chunk supérieur : Allouez un chunk et modifiez la taille du chunk supérieur.
  2. Forcer le chunk supérieur dans la bin non triée : Allouez un chunk plus grand.
  3. Fuir les adresses libc : Utilisez la vulnérabilité pour lire depuis la bin non triée.
  4. Effectuer l'attaque de la bin non triée : Écrivez dans _IO_list_all en utilisant un dépassement.
  5. Réduire l'ancien chunk supérieur : Ajustez sa taille pour l'adapter à une petite bin.
  6. Configurer une fausse structure _IO_FILE : Forgez une fausse structure de fichier pour détourner le flux de contrôle.
  7. Déclencher l'exécution de code : Allouez un chunk pour exécuter l'attaque et exécuter un code arbitraire.

Cette approche exploite les mécanismes de gestion de heap, les fuites d'informations libc et les dépassements de heap pour obtenir une exécution de code sans appeler directement free. En façonnant soigneusement la fausse structure _IO_FILE et en la plaçant au bon endroit, l'attaque peut détourner le flux de contrôle lors des opérations d'allocation de mémoire standard. Cela permet l'exécution de code arbitraire, entraînant potentiellement un shell ou d'autres activités malveillantes.

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