ASLR
Informations de base
La randomisation de l'espace d'adressage (ASLR) est une technique de sécurité utilisée dans les systèmes d'exploitation pour randomiser les adresses mémoire utilisées par les processus système et d'application. Ce faisant, il devient significativement plus difficile pour un attaquant de prédire l'emplacement de processus et de données spécifiques, tels que la pile, le tas et les bibliothèques, réduisant ainsi certains types d'exploitations, en particulier les débordements de tampon.
Vérification du statut de l'ASLR
Pour vérifier le statut de l'ASLR sur un système Linux, vous pouvez lire la valeur du fichier /proc/sys/kernel/randomize_va_space
. La valeur stockée dans ce fichier détermine le type d'ASLR appliqué :
0 : Aucune randomisation. Tout est statique.
1 : Randomisation conservatrice. Les bibliothèques partagées, la pile, mmap(), la page VDSO sont randomisées.
2 : Randomisation complète. En plus des éléments randomisés par la randomisation conservatrice, la mémoire gérée via
brk()
est randomisée.
Vous pouvez vérifier le statut de l'ASLR avec la commande suivante :
Désactiver ASLR
Pour désactiver ASLR, vous définissez la valeur de /proc/sys/kernel/randomize_va_space
sur 0. Désactiver ASLR n'est généralement pas recommandé en dehors des scénarios de test ou de débogage. Voici comment vous pouvez le désactiver :
Vous pouvez également désactiver ASLR pour une exécution avec :
Activation de l'ASLR
Pour activer l'ASLR, vous pouvez écrire une valeur de 2 dans le fichier /proc/sys/kernel/randomize_va_space
. Cela nécessite généralement des privilèges root. L'activation d'une randomisation complète peut être effectuée avec la commande suivante :
Persistance à travers les redémarrages
Les modifications effectuées avec les commandes echo
sont temporaires et seront réinitialisées lors du redémarrage. Pour rendre la modification persistante, vous devez éditer le fichier /etc/sysctl.conf
et ajouter ou modifier la ligne suivante :
Après avoir modifié /etc/sysctl.conf
, appliquez les changements avec :
Cela garantira que vos paramètres ASLR restent inchangés après les redémarrages.
Contournements
Force brute 32 bits
PaX divise l'espace d'adressage du processus en 3 groupes :
Code et données (initialisées et non initialisées) :
.text
,.data
, et.bss
—> 16 bits d'entropie dans la variabledelta_exec
. Cette variable est initialisée de manière aléatoire à chaque processus et ajoutée aux adresses initiales.Mémoire allouée par
mmap()
et bibliothèques partagées —> 16 bits, nommédelta_mmap
.La pile —> 24 bits, appelé
delta_stack
. Cependant, elle utilise effectivement 11 bits (du 10e au 20e octet inclus), alignés sur 16 octets —> Cela donne 524 288 adresses de pile réelles possibles.
Les données précédentes sont pour les systèmes 32 bits et l'entropie finale réduite permet de contourner l'ASLR en réessayant l'exécution encore et encore jusqu'à ce que l'exploit réussisse.
Idées de force brute :
Si vous avez un débordement suffisamment important pour accueillir un grand toboggan NOP avant le shellcode, vous pourriez simplement forcer les adresses dans la pile jusqu'à ce que le flux saute par-dessus une partie du toboggan NOP.
Une autre option pour cela, dans le cas où le débordement n'est pas si important et que l'exploit peut être exécuté localement, est de ajouter le toboggan NOP et le shellcode dans une variable d'environnement.
Si l'exploit est local, vous pouvez essayer de forcer la base de l'adresse de la libc (utile pour les systèmes 32 bits) :
Lors d'une attaque sur un serveur distant, vous pourriez essayer de forcer l'adresse de la fonction
usleep
de lalibc
, en passant 10 comme argument. Si à un moment le serveur met 10 secondes supplémentaires à répondre, vous avez trouvé l'adresse de cette fonction.
Sur les systèmes 64 bits, l'entropie est beaucoup plus élevée et cela n'est pas possible.
Informations locales (/proc/[pid]/stat
)
/proc/[pid]/stat
)Le fichier /proc/[pid]/stat
d'un processus est toujours lisible par tout le monde et il contient des informations intéressantes telles que :
startcode & endcode : Adresses au-dessus et en dessous avec le TEXT du binaire
startstack : L'adresse du début de la pile
start_data & end_data : Adresses au-dessus et en dessous où se trouve le BSS
kstkesp & kstkeip : Adresses actuelles de ESP et EIP
arg_start & arg_end : Adresses au-dessus et en dessous où se trouvent les arguments de la ligne de commande
env_start & env_end : Adresses au-dessus et en dessous où se trouvent les variables d'environnement
Par conséquent, si l'attaquant se trouve sur le même ordinateur que le binaire exploité et que ce binaire ne s'attend pas à un dépassement à partir d'arguments bruts, mais à partir d'une entrée qui peut être créée après la lecture de ce fichier. Il est possible pour un attaquant de récupérer certaines adresses de ce fichier et de construire des décalages à partir d'elles pour l'exploitation.
Pour plus d'informations sur ce fichier, consultez https://man7.org/linux/man-pages/man5/proc.5.html en recherchant /proc/pid/stat
Avoir une fuite
Le défi est de donner une fuite
Si vous disposez d'une fuite (dans le cadre de défis CTF faciles), vous pouvez calculer des décalages à partir de celle-ci (en supposant par exemple que vous connaissez la version exacte de la libc utilisée dans le système que vous exploitez). Cet exemple d'exploitation est extrait de l'exemple d'ici (consultez cette page pour plus de détails) :
ret2plt
En exploitant un dépassement de tampon, il serait possible d'exploiter un ret2plt pour exfiltrer une adresse d'une fonction de la libc. Vérifiez :
Lecture arbitraire de chaînes de format
Tout comme dans ret2plt, si vous avez une lecture arbitraire via une vulnérabilité de chaînes de format, il est possible d'exfiltrer l'adresse d'une fonction libc à partir du GOT. L'exemple suivant est tiré d'ici:
Vous pouvez trouver plus d'informations sur la lecture arbitraire de chaînes de format dans:
Ret2ret & Ret2pop
Essayez de contourner l'ASLR en abusant des adresses à l'intérieur de la pile:
Last updated