Shellcode
En informatique, un shellcode est un programme en langage assembleur qui exécute traditionnellement un shell , tel que le shell Unix '/bin/sh' ou le shell command.com sur les systèmes d'exploitation DOS et Microsoft Windows . Un shellcode peut être utilisé pour exploiter un bogue au travers d'un exploit , permettant à un hacker ou cracker d'accéder à la ligne de commande d'un ordinateur , ou plus généralement d'exécuter du code arbitraire .
Descriptif
Types de shellcode
Il existe deux types de shellcode différents, local et distant. La distinction dépend du type de contrôle que l'exécution du shellcode fournit sur la machine cible, qui peut être local ou distant (si cela se produit sur le réseau).
Locale
Un shellcode local est utilisé par un attaquant qui a un accès limité à la machine, mais qui exploitant une vulnérabilité dans un processus avec des privilèges plus élevés, par exemple un débordement de buffer, peut obtenir les mêmes privilèges si l'exécution du shellcode réussit. .
Distant
Le shellcode distant est utilisé à la place lorsqu'un attaquant veut exploiter une vulnérabilité d'un processus d'une autre machine sur le réseau local ou sur un intranet. Si le Shellcode est exécuté correctement, il rend le contrôle de la machine cible sur le réseau. Les shellcodes distants utilisent normalement le socket TCP/IP standard pour permettre l'accès au shell de la machine cible. D'autres distinctions peuvent être classées selon la méthode par laquelle la connexion est établie. Si c'est le shellcode lui-même qui peut établir la connexion, cela s'appelle un "shell inversé" ou un shellcode de reconnexion, car le shellcode exécuté sur la machine distante se connecte à la machine de l'attaquant. Si, d'autre part, l'attaquant a besoin de créer la connexion, le shellcode est appelé bindshell , car le shellcode se lie à un certain port, qui sera utilisé par l'attaquant pour se connecter et contrôler la machine cible. Un troisième type de shellcode, moins courant, est le shellcode socket-reuse . Ce type de shellcode est généralement utilisé lorsqu'un exploit établit une connexion au processus vulnérable qui n'est pas fermée avant l'exécution du shellcode. Le shellcode peut réutiliser cette connexion pour communiquer avec l'attaquant. Le shellcode de réutilisation de Socket est plus complexe à implémenter, car le shellcode doit identifier quelle connexion il peut utiliser (parmi celles possibles ouvertes sur la machine). [1] Un pare -feu peut être utilisé pour identifier les connexions sortantes établies par un shellcode de reconnexion et la tentative de connexion entrante d'un bindshell. Le pare-feu peut fournir une protection supplémentaire contre un attaquant, même si le système est vulnérable, en empêchant de manière préventive l'accès au shell créé par l'exécution du shellcode. C'est l'une des raisons pour lesquelles une socket réutilisant le shellcode est parfois utilisée, car ne pas créer de nouvelles connexions est plus difficile à identifier et à bloquer.
Téléchargez et exécutez
Télécharger et exécuter est un type de shellcode distant qui effectue un téléchargement et exécute une forme de logiciel malveillant sur le système cible. Ce type de shellcode ne crée pas de shell, mais demande à la machine de télécharger un certain fichier exécutable depuis le réseau, de l'enregistrer sur le disque, puis de l'exécuter. De nos jours, il est couramment utilisé dans les attaques par téléchargement , lorsqu'une victime visite un site malveillant qui tente de lancer un téléchargement et d'exécuter un shellcode pour installer un logiciel sur la machine victime. Une variante de ce type de shellcode est "télécharger et charger une bibliothèque". [2] [3] Les avantages de cette technique sont que le code shellcode peut être plus petit, qu'il ne nécessite pas la création d'un nouveau processus sur la machine cible, et que le shellcode n'a pas besoin d'implémenter le code pour nettoyer la cible. process , mais cela peut être fait à partir d'une bibliothèque chargée dans le processus.
Mise en scène
Lorsque la quantité de données qu'un attaquant peut injecter dans un processus cible est trop petite pour que le shellcode s'exécute correctement, il peut être exécuté par étapes. Tout d'abord, un petit morceau de shellcode (étape 1) est exécuté. Ce code vide une plus grande partie du shellcode (phase 2) dans la mémoire du processus et l'exécute.
Chasse aux œufs
La chasse aux œufs est un autre type de shellcode par phases. Il est utilisé lorsqu'un attaquant a la capacité d'insérer un gros shellcode dans un processus, mais ne peut pas déterminer où il sera placé en mémoire. Ensuite, une petite chasse aux œufs est insérée dans le processus dans un endroit prévisible, puis exécutée. Le code recherche dans l'espace mémoire un shellcode plus grand (l'oeuf) et l'exécute.
Omelette
Ce type de shellcode est similaire à la chasse aux œufs, mais recherche des blocs plus petits (œufs) et les recombine en un plus grand (omelette) qui est ensuite exécuté. Cette technique est utilisée lorsqu'un attaquant est limité, pour une raison quelconque, à insérer de petits blocs de données dans le processus. [4]
Opération
Stratégie d'exécution du shellcode
Un exploit insère généralement un shellcode dans le processus cible avant ou en même temps qu'un exploit de vulnérabilité se produit, pour prendre le contrôle du compteur de programme . Le compteur de programme est dirigé pour pointer vers le shellcode à exécuter. L'injection du shellcode se fait souvent en stockant le code dans les données envoyées sur le réseau au processus vulnérable, en le rendant disponible dans un fichier lu par le processus ou via la ligne de commande ou des variables d'environnement dans le cas d'exploits locaux.
Encodage du shellcode
Étant donné que de nombreux processus filtrent ou limitent les données pouvant être saisies, le shellcode doit souvent être écrit pour surmonter ces restrictions, ce qui rend le code petit, exempt de caractères nuls ou alphanumériques. Plusieurs solutions ont été trouvées pour contourner ces restrictions :
- Optimisations de conception et d'implémentation pour réduire la taille du shellcode.
- Changements d'implémentation pour contourner les limitations dans la plage d'octets utilisés dans le shellcode.
- Code auto-modifiable qui modifie le nombre d'octets de son code avant de les exécuter, afin de recréer des octets qui ne peuvent normalement pas être insérés dans le processus.
Étant donné que les outils de détection d'intrusion peuvent identifier la signature de simples shellcodes envoyés sur le réseau, ils sont encodés et rendus auto-déchiffrants ou polymorphes pour éviter d'être reconnus.
Codage en pourcentage
Les exploits ciblant les navigateurs codent généralement le shellcode dans une chaîne JavaScript en utilisant la notation de codage en pourcentage ou de codage d'URL, en échappant "\ uXXXX" ou en utilisant entity . Certains exploits obscurcissent davantage le shellcode codé en chaîne pour éviter d'être détectés par les outils IDS . Par exemple, sur une architecture IA-32 , deux instructions (sans opération) NOPont cette forme avant d'être codées.
90 NOP 90 NOP
Ils sont codés dans une chaîne avec un codage en pourcentage. (en utilisant la méthode unescape () pour le décodage)
unescape ("% u9090");
Il est alors encodé dans la notation "\uXXXX":
"\u9090" ;
Et enfin dans l'encodage des entités.
"& # x9090;"
ou
"& # 37008;"
Shellcode Null-Free
De nombreux shellcodes sont écrits sans utiliser null bytes , car ils sont conçus pour être insérés dans le processus cible via une chaîne terminée par null. Lorsqu'une chaîne terminée par un caractère nul est copiée, la copie inclura le premier caractère nul , mais les octets suivants ne seront pas traités. Lorsque le shellcode contenant le null est entré de cette manière, seule une partie du shellcode sera insérée, le rendant incapable de s'exécuter plus tard. Pour produire un shellcode sans null commençant par un qui contient des octets nuls, les instructions machine qui contiennent des zéros peuvent être remplacées par des instructions qui produisent le même effet mais n'ont pas d'octets nuls. Par exemple sur une architecture IA-32 ce remplacement pourrait être effectué :
B8 01000000 MOV EAX, 1 // Définir le registre EAX sur 0x000000001
cette instruction contient des zéros dans le cadre du littéral (1 est développé en 0x000000001) avec ces instructions :
33C0 XOR EAX, EAX // Mettre le registre EAX à 0x000000000 40 INC EAX // Augmente la valeur EAX à 0x00000001
qui ont le même effet mais nécessitent moins d'octets pour l'encodage et sont libres d'octets nuls.
Shellcodes alphanumériques et imprimables
Dans certaines circonstances, un processus cible peut filtrer tous les octets du shellcode entré qui ne sont pas imprimables ou alphanumériques. Dans ces conditions, la gamme d'instructions utilisables pour écrire un shellcode devient très limitée. Une solution à ce problème a été publiée par Rix dans Phrack 57 [5] où il est montré comment il est possible de convertir n'importe quel type de code en code alphanumérique. Une technique largement utilisée consiste à créer du code auto-modifiable, car cela permet au code de modifier ses propres octets pour en inclure d'autres qui ne sont pas inclus parmi ceux autorisés et d'élargir la gamme d'instructions utilisables. Avec ce genre d'astuce, un décodeur auto-modifiable peut initialement être créé en utilisant uniquement des octets dans la plage autorisée. Lorsque le shellcode sortant entre en exécution, le décodeur peut modifier son code pour pouvoir utiliser toute instruction requise pour lui permettre de fonctionner correctement et en même temps continuer à décoder le shellcode d'origine. Après avoir effectué le décodage, le décodeur transfère le contrôle au shellcode, afin qu'il puisse fonctionner normalement. Il a été montré comment il est possible de créer des shellcodes de complexité arbitraire qui ressemblent à du texte anglais normal. [6]
Shellcode Unicode à l'épreuve des caractères
De nombreux programmes modernes utilisent le codage de chaîne au format Unicode pour permettre l'internalisation du texte. Souvent, ces programmes convertissent les chaînes ASCII d'entrée avant de les traiter. Les chaînes Unicode codées en UTF-16 utilisent deux octets pour décoder chaque caractère (ou quatre octets pour certains caractères spéciaux). Lorsqu'une chaîne ASCII est convertie en UTF-16, un octet zéro est inséré après chaque octet de la chaîne d'origine. Obscu a montré dans Phrack 61 [7] qu'il est possible d'écrire des shellcodes qui peuvent s'exécuter correctement même après cette transformation. Il existe des programmes qui peuvent changer automatiquement chaque shellcode en un seul codé par UTF-16 et sont basés sur le même principe qu'un décodeur auto-modifiant qui décode le shellcode d'origine.
Plates-formes
De nombreux shellcodes sont écrits en code machine en raison du bas niveau auquel la vulnérabilité devient exploitable. Le shellcode est souvent créé pour attaquer une combinaison spécifique de processeur, de système d'exploitation et de service pack, communément appelée plate-forme. Pour certains exploits, du fait des contraintes imposées par le processus cible, il est nécessaire de créer un shellcode spécifique. Cependant, il n'est pas toujours possible pour un shellocde de fonctionner pour plusieurs exploits, service packs, systèmes d'exploitation et éventuellement processeurs. [8] Une polyvalence peut être donnée en créant différentes versions du shellcode, basées sur les différentes plates-formes à attaquer et en créant un en-tête qui identifie la version correcte pour la plate-forme utilisée. Lorsqu'il est exécuté, le code se comporte différemment selon la plate-forme et est capable d'exécuter la version correcte du shellcode.
Remarques
- ^ BHA, Shellcode / Socket-reuse , sur blackhatlibrary.net , 6 juin 2013. Récupéré le 7 juin 2013 .
- ^ Sortie du shellcode SkyLined, Download and LoadLibrary , sur skypher.com , 11 janvier 2010. Récupéré le 19 janvier 2010 (archivé de l' original le 23 janvier 2010) .
- ^ SkyLined, Download and LoadLibrary shellcode for x86 Windows , sur code.google.com , 11 janvier 2010. Récupéré le 19 janvier 2010 .
- ^ SkyLined, w32 SEH omelet shellcode , sur skypher.com , 16 mars 2009. Récupéré le 19 mars 2009 (archivé de l' original le 23 mars 2009) .
- ^ Rix, Rédaction de shellcodes alphanumériques ia32 , phrack.org , Phrack, 8 novembre 2001. Récupéré le 29 février 2008 .
- ^ Joshua Mason, Small, Sam, Monrose, Fabian et MacManus, Greg, Shellcode anglais ( PDF ), cs.jhu.edu , novembre 2009. Récupéré le 10 janvier 2010 .
- ^ Obscou, Building IA32 'Unicode-Proof' Shellcodes , phrack.org , Phrack, 13 août 2003. Récupéré le 29 février 2008 .
- ^ Eugene, Architecture Spanning Shellcode , phrack.org , Phrack, 11 août 2001. Récupéré le 29 février 2008 .
Objets associés
- Débordement de tampon
- Débordement de tas
- sécurité informatique
- Assemblée
- code auto-modifiable
- système de détection d'intrusion
Liens externes
- Shell-Storm.org Base de données de shellcodes multi-plateforme.
- https://web.archive.org/web/20080302111910/http://www.metasploit.com/shellcode/ Contient des exemples de shellcode x86 et non x86 et une interface en ligne pour la génération et l'encodage automatiques du shellcode.
- http://www.vividmachines.com/shellcode/shellcode.html Tutoriel sur les shellcodes sous Windows et Linux avec des exemples étape par étape.
- http://www.orkspace.net/software/libShellCode/ bibliothèque open source pour la création automatique de ShellCode. Il peut être utilisé pour créer des ShellCodes dynamiques dans un exploit ou pour créer des ShellCodes statiques grâce à l'utilisation d'un frontal .