hacktricks/binary-exploitation/heap/unsorted-bin-attack.md

90 lines
10 KiB
Markdown

# Attaque de la liste non triée
<details>
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert Red Team AWS de HackTricks)</strong></a><strong>!</strong></summary>
Autres façons de soutenir HackTricks :
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
</details>
## Informations de base
Pour plus d'informations sur ce qu'est une liste non triée, consultez cette page :
{% content-ref url="bins-and-memory-allocations.md" %}
[bins-and-memory-allocations.md](bins-and-memory-allocations.md)
{% endcontent-ref %}
Les listes non triées peuvent écrire l'adresse de `unsorted_chunks (av)` dans l'adresse `bk` du chunk. Par conséquent, si un attaquant peut **modifier l'adresse du pointeur bk** dans un chunk à l'intérieur de la liste non triée, il pourrait être en mesure d'**écrire cette adresse dans une adresse arbitraire** ce qui pourrait être utile pour divulguer des adresses libc ou contourner certaines défenses.
Donc, fondamentalement, cette attaque permet de **écraser une adresse arbitraire avec un grand nombre** (une adresse qui pourrait être une adresse de tas ou une adresse libc) comme une adresse de pile qui pourrait être divulguée ou une restriction comme la variable globale **`global_max_fast`** pour permettre de créer des bacs rapides avec des tailles plus grandes (et passer d'une attaque de liste non triée à une attaque de bac rapide).
{% hint style="success" %}
En examinant l'exemple fourni dans [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#principle) et en utilisant 0x4000 et 0x5000 au lieu de 0x400 et 0x500 comme tailles de chunk (pour éviter les tcaches), il est possible de voir que de nos jours l'erreur **`malloc(): unsorted double linked list corrupted`** est déclenchée.
Par conséquent, cette attaque de liste non triée nécessite maintenant (parmi d'autres vérifications) également de pouvoir corriger la liste doublement chaînée afin que cela soit contourné `victim->bck->fd == victim` ou non `victim->fd == av (arène)`. Ce qui signifie que l'adresse où nous voulons écrire doit avoir l'adresse du faux chunk dans sa position `fd` et que le faux chunk `fd` pointe vers l'arène.
{% endhint %}
{% hint style="danger" %}
Notez que cette attaque corrompt la liste non triée (donc aussi les petites et grandes). Nous ne pouvons donc **utiliser que des allocations du bac rapide 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.**
Notez que rendre **`global_max_fast`** plus grand pourrait aider dans ce cas en faisant confiance au bac rapide pour gérer toutes les autres allocations jusqu'à ce que l'exploit soit terminé.
{% endhint %}
Le code de [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin\_attack/unsorted\_explanation/index.html) l'explique très bien, bien que si vous modifiez les mallocs pour allouer suffisamment de mémoire pour ne pas aboutir à un tcache, vous pouvez voir que l'erreur précédemment mentionnée apparaît, empêchant cette technique : **`malloc(): unsorted double linked list corrupted`**
## Attaque d'Infoleak de la liste non triée
Il s'agit en fait d'un concept très basique. Les chunks dans la liste non triée vont avoir des pointeurs double pointeurs pour créer le bac. Le premier chunk dans la liste non triée aura en fait les liens **FD** et **BK** **pointant vers une partie de l'arène principale (libc)**.\
Par conséquent, si vous pouvez **mettre un chunk à l'intérieur d'un bac non trié et le lire** (utilisation après libération) ou **l'allouer à nouveau sans écraser au moins 1 des pointeurs** pour ensuite **le lire**, vous pouvez obtenir une **fuite d'informations libc**.
## Références et autres exemples
* [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted\_bin\_attack/#hitcon-training-lab14-magic-heap)
* L'objectif est de remplacer une variable globale par une valeur supérieure à 4869 pour pouvoir obtenir le drapeau et le PIE n'est pas activé.
* Il est possible de générer des chunks de tailles arbitraires et il y a un débordement de tas avec la taille souhaitée.
* L'attaque commence en créant 3 chunks : chunk0 pour exploiter le débordement, chunk1 pour être débordé et chunk2 pour que le chunk supérieur ne consolide pas les précédents.
* Ensuite, chunk1 est libéré et chunk0 est débordé pour que le pointeur `bk` de chunk1 pointe vers : `bk = magic - 0x10`
* Ensuite, chunk3 est alloué avec la même taille que chunk1, ce qui déclenchera l'attaque de la liste non triée et modifiera la valeur de la variable globale, permettant ainsi d'obtenir le drapeau.
* [**https://guyinatuxedo.github.io/31-unsortedbin\_attack/0ctf16\_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin\_attack/0ctf16\_zerostorage/index.html)
* La fonction de fusion est vulnérable car si les deux index passés sont les mêmes, elle va realloc dessus puis le libérer mais renvoyer un pointeur vers cette région libérée qui peut être utilisé.
* Par conséquent, **2 chunks sont créés** : **chunk0** qui sera fusionné avec lui-même et chunk1 pour empêcher la consolidation avec le chunk supérieur. Ensuite, la **fonction de fusion est appelée avec chunk0** deux fois ce qui provoquera une utilisation après libération.
* Ensuite, la fonction **`view`** est appelée avec l'index 2 (qui est l'index du chunk utilisé après libération), ce qui va **divulguer une adresse libc**.
* Comme le binaire a des protections pour allouer uniquement des tailles plus grandes que **`global_max_fast`** donc aucun fastbin n'est utilisé, une attaque de liste non triée va être utilisée pour écraser la variable globale `global_max_fast`.
* Ensuite, il est possible d'appeler la fonction edit avec l'index 2 (le pointeur utilisé après libération) et écraser le pointeur `bk` pour pointer vers `p64(global_max_fast-0x10)`. Ensuite, en créant un nouveau chunk, l'adresse de libération compromise précédemment (0x20) va **déclencher l'attaque de la liste non triée** en écrasant le `global_max_fast` avec une valeur très grande, permettant maintenant de créer des chunks dans les bacs rapides.
* Maintenant une **attaque de bac rapide** est effectuée :
* Tout d'abord, il est découvert qu'il est possible de travailler avec des **chunks rapides de taille 200** à l'emplacement de **`__free_hook`** :
* <pre class="language-c"><code class="lang-c">gef➤ p &#x26;__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 &#x3C;__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
<strong>0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6076f &#x3C;list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f &#x3C;_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
* Si nous parvenons à obtenir un chunk rapide de taille 0x200 à cet emplacement, il sera possible de remplacer un pointeur de fonction qui sera exécuté
* Pour cela, un nouveau chunk de taille `0xfc` est créé et la fonction fusionnée est appelée avec ce pointeur deux fois, de cette manière nous obtenons un pointeur vers un chunk libéré de taille `0xfc*2 = 0x1f8` dans le fast bin.
* Ensuite, la fonction edit est appelée dans ce chunk pour modifier l'adresse **`fd`** de ce fast bin afin de pointer vers la fonction **`__free_hook`** précédente.
* Ensuite, un chunk de taille `0x1f8` est créé pour récupérer du fast bin le chunk inutile précédent, puis un autre chunk de taille `0x1f8` est créé pour obtenir un chunk fast bin dans le **`__free_hook`** qui est écrasé avec l'adresse de la fonction **`system`**.
* Enfin, un chunk contenant la chaîne `/bin/sh\x00` est libéré en appelant la fonction delete, déclenchant la fonction **`__free_hook`** qui pointe vers system avec `/bin/sh\x00` comme paramètre.
<details>
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Autres façons de soutenir HackTricks:
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF** Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** nous sur **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
</details>