Pourquoi l'emplacement des variables d'environnement varie-t-il autant?

9

En lisant le livre Hacking: The Art of Exploitation de Jon Erickson, j'essaie d'approximer l'adresse d'une variable d'environnement SHELLCODEpour exploiter un programme.

Chaque fois que je cours getenv("SHELLCODE");pour obtenir l'emplacement, le résultat est complètement différent.

Extrait de ma coque:

> for i in $(seq 10); do ./a.out SHELLCODE; done
SHELLCODE is at 0xff9ab3a3
SHELLCODE is at 0xffcdb3a3
SHELLCODE is at 0xffb9a3a3
SHELLCODE is at 0xffa743a3
SHELLCODE is at 0xffdb43a3
SHELLCODE is at 0xfff683a3
SHELLCODE is at 0xffef03a3
SHELLCODE is at 0xffc1c3a3
SHELLCODE is at 0xff85a3a3
SHELLCODE is at 0xff8e03a3

Je comprends que si le nom du programme est modifié ou de nouvelles variables d'environnement sont ajoutées, la position serait légèrement différente, mais pourquoi l'emplacement varie-t-il autant?

Janman
la source
Le getenvmanuel indique qu'il renvoie un pointeur sur une chaîne contenant la valeur de la variable. Tout le reste n'est pas spécifié, donc votre noyau et / ou votre compilateur peuvent coller la valeur où ils veulent, tant que cette promesse de pointeur reste vraie. Je suppose que la réponse exacte à cela peut être une sorcellerie lourde et dépend de divers détails d'implémentation de la cartographie de la mémoire et de la phase de la lune. (Je ne suis pas assez sorcier pour vous donner la réponse exacte.)
Anko
"Je comprends que si le nom du programme est modifié ou si de nouvelles variables d'environnement sont ajoutées, la position serait légèrement différente, mais pourquoi l'emplacement varie-t-il autant?" C'est vrai dans la plus simple de toutes les implémentations possibles, mais ce n'est certainement pas nécessaire.
dmckee --- chaton ex-modérateur

Réponses:

13

Ce que vous décrivez est une fonctionnalité anti-exploitation appelée randomisation de la mise en page de l'espace adresse (ASLR). Fondamentalement, le noyau place l'adresse la plus haute de la pile d'appels de fonction d'un programme à une adresse légèrement différente ("aléatoire") à chaque fois que le noyau charge le fichier ELF du programme à partir du disque. Les adresses argvet les variables d'environnement, dont votre shellcode est un, se retrouvent à une adresse variable à chaque appel de programme.

ASLR est censé rendre plus difficile l'exploitation des dépassements de tampon et d'autres vulnérabilités liées à la pile. L'exploitant doit écrire du code ou faire quelque chose pour tenir compte des adresses variables des variables et des valeurs sur la pile d'appels de fonction.

On dirait que vous pouvez désactiver ASLR en faisant quelque chose comme:

echo 0 > /proc/sys/kernel/randomize_va_space

en tant qu'utilisateur root. Puisque vous citez explicitement Ubuntu, la commande ci-dessus est différente:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Bruce Ediger
la source
Oui, ça a fait l'affaire. J'ai remarqué que l'auteur du livre utilise Ubuntu 10.04, qui n'avait pas encore d'ASLR.
Janman