En étudiant le noyau Linux, je viens de découvrir que, par défaut, un exécutable a une zone de pile 'exécutable'. J'ai naturellement pensé que la seule zone exécutable (nécessaire) est la section de texte. Y a-t-il une raison historique liée à ceci ou à un usage pratique?Pourquoi la zone de pile Linux a-t-elle une protection exécutable?
Répondre
Une pile exécutable est nécessaire dans certains cas, comme le trampoline GCC pour les fonctions imbriquées. Un trampoline est un petit morceau de code qui est créé lors de l'exécution lorsque l'adresse d'une fonction imbriquée est prise. Il réside normalement sur la pile, dans le cadre de la pile de la fonction conteneur. Ces macros indiquent à GCC comment générer du code pour allouer et initialiser un trampoline.
Dans la plupart des distributions en raison des risques d'attaque et de l'utilisation de la pile pour exécuter un shellcode, cette fonctionnalité est désactivée, bien que vous puissiez compiler un code avec -z execstack
pour l'activer. Il est également possible d'utiliser un programme appelé execstack
pour activer ou désactiver cette fonctionnalité après la compilation du programme. Pour que cela soit clair j'ai écrit un programme simple pour exécuter exit
syscall avec le code de sortie de 32. Si cette fonctionnalité est activée, le code fonctionne, sinon il donne un défaut de segmentation.
#include <stdlib.h>
#include <unistd.h>
char shellCode[] = "\xb8\x01\x00\x00\x00" // mov $0x1,%eax
"\xbb\x20\x00\x00\x00" // mov $0x20,%ebx
"\xcd\x80"; // int $0x80
int main(){
int *ret;
ret = (int*) &ret + 2;
*ret = (int) shellCode;
return 5;
}
Dans ce code ret
pointe vers son adresse plus 2. Comme nous le savons de la taille du pointeur de systèmes IA32 est 4bytes et au début de chaque fonction il y a un push ebp
après la compilation. Donc, afin d'atteindre l'adresse de retour de main
nous devons ajouter 2*stack_chunk_size
et en définissant chaque morceau 4byte au moment de la compilation cela fonctionne parfaitement.
compiler le code de ce type d'essai:
gcc -mpreferred-stack-boundary=2 -z execstack -o testShellCode testShellCode.c
-mpreferred-stack-boundary=2
est d'aligner la pile en 4 morceaux d'octets et -z execstack
consiste à compiler en utilisant pile exécutable.
Ce code simple peut donner un aperçu de la raison pour laquelle il existe une protection de pile exécutable.
Regardez les liens suivants pour plus d'informations sur les fonctions imbriquées et execstack
commande:
Wow, je ne m'attendais pas mais c'est tout à fait une histoire. Merci beaucoup! –
Bien sur la seconde, mais sur l'exemple, le contrôle ne devrait pas être transféré à la section de données après l'instruction de retour dans «principal»? Je pense que l'exemple est logique si 'shellCode' a été déclaré dans une portée de fonction. –
GCC sont mises en œuvre de fonctions imbriquées comme trampolines et nécessitent une pile exécutable. Il existe d'autres cas d'utilisation, dont certains sont décrits [ici] (https://wiki.ubuntu.com/SecurityTeam/Roadmap/ExecutableStacks). –