10 KiB
Maison d'Orange
{% 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
- Consultez les plans d'abonnement!
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de piratage en soumettant des PR aux HackTricks et HackTricks Cloud dépôts GitHub.
Informations de base
Code
- Trouvez un exemple dans https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c
- La technique d'exploitation a été corrigée dans ce correctif donc cela ne fonctionne plus (fonctionne pour les versions antérieures à 2.26)
- Même exemple avec plus de commentaires dans https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html
Objectif
- Abuser de la fonction
malloc_printerr
Exigences
- Écraser la taille du chunk supérieur
- Fuites de libc et de heap
Contexte
Certains éléments de contexte nécessaires provenant des commentaires de cet exemple:
En fait, dans les anciennes versions de libc, lorsque la fonction malloc_printerr
était appelée, elle itérait à travers une liste de structures _IO_FILE
stockées dans _IO_list_all
, et exécutait en fait un pointeur d'instruction dans cette structure.
Cette attaque va forger une fausse structure _IO_FILE
que nous écrirons dans _IO_list_all
, et provoquer l'exécution de malloc_printerr
.
Ensuite, il exécutera l'adresse que nous avons stockée dans les pointeurs d'instruction de la structure _IO_FILE
, et nous obtiendrons une exécution de code
Attaque
L'attaque commence par parvenir à obtenir le chunk supérieur à l'intérieur du bloc non trié. Cela est réalisé en appelant malloc
avec une taille supérieure à la taille actuelle du chunk supérieur mais plus petite que mmp_.mmap_threshold
(par défaut 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 la page et que le bit prev_inuse du chunk supérieur est toujours défini.
Pour obtenir le chunk supérieur à l'intérieur du bloc non trié, allouez un chunk pour créer le chunk supérieur, modifiez la taille du chunk supérieur (avec un débordement dans le chunk alloué) de sorte que le chunk supérieur + la taille soit aligné sur la 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 placer le chunk supérieur dans le bloc non trié.
L'ancien chunk supérieur est maintenant dans le bloc non trié. En supposant que nous puissions lire des données à l'intérieur (éventuellement en raison d'une vulnérabilité ayant également provoqué le débordement), il est possible de fuiter des adresses libc à partir de celui-ci et d'obtenir l'adresse de _IO_list_all.
Une attaque sur le bloc non trié est effectuée en abusant du débordement 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 le bloc non trié sera écrit dans _IO_list_all
.
L'étape suivante consiste à réduire la taille de l'ancien chunk supérieur pour qu'il rentre dans un petit bloc, en définissant spécifiquement sa taille à 0x61. Cela sert à deux fins :
- Insertion dans le petit bloc 4 : Lorsque
malloc
parcourt le bloc non trié et voit ce chunk, il essaiera de l'insérer dans le petit bloc 4 en raison de sa petite taille. Cela fait que le chunk se retrouve en tête de la liste du petit bloc 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 sur le bloc non trié. - Déclenchement d'une vérification de malloc : Cette manipulation de la taille du chunk provoquera des vérifications internes de
malloc
. Lorsqu'il vérifie la taille du faux chunk suivant, qui sera nulle, cela déclenche une erreur et appellemalloc_printerr
.
La manipulation du petit bloc 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 de libc. De plus, une table de saut est créée à l'intérieur de la fausse structure, où un pointeur d'instruction est défini sur 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 le faire rentrer dans un petit bloc.
- Configurer la fausse structure
_IO_FILE
: Faites chevaucher 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 le bloc non trié. 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 de 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 de libc. De plus, une table de saut est créée à l'intérieur de la fausse structure, où un pointeur d'instruction est défini sur l'adresse où un code arbitraire peut être exécuté. Typiquement, il s'agirait de l'adresse de la fonction system
ou d'une autre fonction pouvant exécuter des commandes shell.
L'attaque culmine lorsque l'appel à malloc
déclenche l'exécution du code à travers la structure _IO_FILE manipulée. Cela permet efficacement l'exécution de code arbitraire, aboutissant généralement à un shell ou à l'exécution d'une autre charge malveillante.
Résumé de l'attaque :
- Configurer le chunk supérieur : Allouer un chunk et modifier la taille du chunk supérieur.
- Forcer le chunk supérieur dans le bloc non trié : Allouer un chunk plus grand.
- Fuites d'adresses libc : Utiliser la vulnérabilité pour lire à partir du bloc non trié.
- Effectuer l'attaque sur le bloc non trié : Écrire dans _IO_list_all en utilisant un débordement.
- Réduire l'ancien chunk supérieur : Ajuster sa taille pour qu'il rentre dans un petit bloc.
- Configurer une fausse structure _IO_FILE : Forger une fausse structure de fichier pour détourner le flux de contrôle.
- Déclencher l'exécution de code : Allouer un chunk pour exécuter l'attaque et exécuter du code arbitraire.
Cette approche exploite les mécanismes de gestion de la mémoire heap, les fuites d'informations libc et les débordements de heap pour parvenir à une exécution de code sans appeler directement free
. En concevant 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 standard d'allocation de mémoire. Cela permet l'exécution de code arbitraire, aboutissant potentiellement à un shell ou à d'autres activités malveillantes.
Références
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/
- https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html
{% 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
- Consultez les plans d'abonnement!
- Rejoignez le 💬 groupe Discord ou le groupe Telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de piratage en soumettant des PR aux HackTricks et HackTricks Cloud github repos.