Skip to content
shellcodes

Qu'est-ce qu'un shellcode ? Le guide complet

Le shellcode expliqué : ce que c'est, pourquoi les exploits l'utilisent, comment il s'écrit et s'encode, et comment le générer et le tester sans risque dans ton navigateur.

Publié le 4 min de lecture

Un shellcode est un petit fragment de code machine indépendant de la position qui s'exécute comme payload d'un exploit. Quand un bug te donne le contrôle du pointeur d'instruction, c'est le shellcode qui s'exécute ensuite. Ce guide couvre ce que c'est, les types courants, les contraintes qui le cassent, et comment le générer et l'analyser sans risque.

Qu'est-ce qu'un shellcode ?

Un shellcode, ce sont des instructions CPU brutes, pas un programme que tu lances depuis un shell. Il n'a pas de loader, pas d'en-têtes, pas d'éditeur de liens — juste des octets qu'un processeur exécute directement une fois que ton exploit y redirige le contrôle. Comme il atterrit à une adresse que tu ne connais pas à l'avance, il doit être indépendant de la position : aucune adresse absolue en dur, tout est relatif.

Pourquoi parle-t-on de « shellcode » ?

Les premiers payloads faisaient une seule chose : lancer un shell de commande (/bin/sh sous Unix, cmd.exe sous Windows), donnant à l'attaquant un contrôle interactif. Le nom a survécu à ce sens étroit. Aujourd'hui, « shellcode » désigne n'importe quel petit payload en code machine, qu'il ouvre un shell, rappelle un serveur ou charge un étage plus gros.

Comment fonctionne un shellcode

Un déroulé typique :

  1. Une vulnérabilité (dépassement de pile, use-after-free, format string) te permet d'écraser une valeur de contrôle.
  2. Tu rediriges l'exécution vers un buffer que tu contrôles.
  3. Le CPU commence à exécuter tes octets comme des instructions.
  4. Le shellcode prépare les registres et invoque un appel système pour agir.

Sous Linux, cette dernière étape est généralement une instruction syscall/int 0x80 ; sous Windows, il résout et appelle des fonctions d'API. Dans les deux cas, le code doit être autonome et survivre aux protections mémoire en place.

Les types de shellcode

  • Exec / local — exécute une commande sur place. Compact et discret. Utile quand tu disposes déjà d'un canal.
  • Reverse TCP — se reconnecte vers ton listener pour une session interactive.
  • Bind — ouvre un port sur la cible et attend.
  • À étages (staged) vs sans étage (stageless) — un petit stager télécharge un payload plus gros, par opposition à tout embarquer d'un coup.

Le choix dépend de la primitive et de l'environnement, pas de l'option qui paraît la plus impressionnante. Voir Linux exec ou reverse TCP pour l'arbitrage.

À quoi ressemble un shellcode

Un execve("/bin/sh") Linux x86 de 25 octets :

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80

Ces octets mettent un registre à zéro, empilent /bin//sh sur la pile, préparent les arguments d'execve et déclenchent le syscall. Pour aller plus loin, avec le désassemblage en regard, voir exemples de shellcode.

Bad chars et octets nuls

La livraison fait souvent passer tes octets par des fonctions de chaîne. Un seul 0x00 peut tronquer une copie de type strcpy et couper ton payload en deux ; les retours à la ligne, espaces et slashs cassent d'autres parsers. C'est pour ça qu'on encode les payloads afin d'éviter certaines valeurs d'octets. C'est aussi d'où viennent la plupart des échecs « ça marchait dans le debugger, pas sur la cible » — voir les octets nuls dans le shellcode.

Comment générer un shellcode

Trois voies courantes — l'assembleur écrit à la main, un framework comme msfvenom, ou un générateur qui assemble et encode pour toi. Elles diffèrent par le contrôle, la portabilité et la confiance que tu places dans les octets de quelqu'un d'autre. La comparaison complète est dans comment générer un shellcode. Tu peux construire et encoder des payloads entièrement côté client dans le builder Shellcodes, sans installer de framework.

Comment analyser un shellcode

Avant d'exécuter des octets — surtout des octets que tu n'as pas écrits — décode-les et désassemble-les. Transformer un blob échappé en \x en mnémoniques te dit ce qu'il fait vraiment et fait apparaître les bad chars. Le convertisseur Shellcodes désassemble avec Capstone ; le workflow est dans décoder et désassembler un shellcode.

Usage légal et éthique

Le shellcode est à double usage. L'écrire, le générer et le tester est légitime pour des tests d'intrusion autorisés, des CTF, de la recherche d'exploits et de l'ingénierie de détection — et illégal contre des systèmes que tu ne possèdes pas ou que tu n'es pas autorisé à tester. Garde-le dans des labs et des missions cadrées. Voir la politique d'usage responsable.

FAQ

Un shellcode est-il un virus ? Non. C'est une technique de payload. Il ne devient malveillant qu'associé à un exploit contre une cible que tu n'es pas autorisé à tester.

Dans quel langage écrit-on un shellcode ? En assembleur, ensuite assemblé en octets de code machine bruts. On prototype souvent la logique en C pour trouver les bons syscalls.

Comment exécuter un shellcode sans risque ? Dans une VM ou un conteneur de lab isolés que tu contrôles, après l'avoir décodé et désassemblé pour savoir exactement ce qu'il fait.

Articles associés

Retransformer des octets de shellcode bruts en assembleur — décoder les formats hexa et échappés, désassembler avec Capstone et repérer les bad chars avant d'exécuter.
Des exemples de shellcode annotés pour Linux x86 et x64 — execve /bin/sh et reverse TCP — avec les octets, le désassemblage et les pièges.
Comment fonctionne un shellcode Linux — syscalls, registres et code indépendant de la position — et comment l'assembler, l'encoder et le tester sans risque.