Le shellcode Linux expliqué : du C aux octets
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.
Un shellcode Linux est compact parce que le noyau fait le gros du travail via les syscalls. Tu ne te lies pas à la libc ; tu prépares les registres et tu demandes directement au noyau. Si le mot « shellcode » est nouveau pour toi, lis d'abord qu'est-ce qu'un shellcode.
Syscalls : x86 vs x64
Les deux architectures diffèrent sur trois points qui comptent pour le shellcode :
| x86 | x64 | |
|---|---|---|
| Instruction de syscall | int 0x80 | syscall |
| Numéro de syscall | eax | rax |
| Arguments | ebx, ecx, edx, … | rdi, rsi, rdx, … |
execve est le syscall 11 sous x86 et 59 sous x64. Trompe-toi de numéro pour l'architecture et tu appelles autre chose que prévu — un bug classique de débutant.
Code indépendant de la position
Tes octets atterrissent à une adresse que tu ne contrôles pas, donc tu ne peux pas coder de pointeurs en dur. La manœuvre standard pour les chaînes consiste à les empiler sur la pile et à faire pointer un registre vers la pile :
xor eax, eax
push eax ; terminator
push 0x68732f2f ; "//sh"
push 0x6e69622f ; "/bin"
mov ebx, esp ; ebx now points at the string, wherever it is
Pas de section .data, pas d'adresse absolue — ça marche quel que soit l'endroit où le code s'exécute.
Éviter les octets nuls
xor eax, eax plutôt que mov eax, 0 n'est pas une question de style ; la seconde forme s'assemble avec des octets nuls qui cassent la livraison par chaîne. Tout l'art du shellcode Linux compact consiste à obtenir la bonne logique tout en esquivant les valeurs d'octets interdites. Voir les octets nuls dans le shellcode.
Assembler en octets
Écris l'assembleur, assemble-le, puis extrais les octets du .text. Prototyper la logique en C d'abord est une bonne façon de trouver les bons syscalls et arguments avant de peaufiner l'assembleur à la main. Des exemples fonctionnels avec les chaînes d'octets complètes sont dans exemples de shellcode.
Ordre des passes d'encodage
Si ta cible interdit certains octets, tu encodes — mais l'ordre des encodeurs compte : une seconde passe peut réintroduire des octets que la première avait supprimés. C'est une erreur récurrente ; le raisonnement est dans l'ordre du pipeline d'encodeurs.
Teste-le
Assemble, encode pour ton jeu de bad chars et vérifie — entièrement côté client — dans le builder Shellcodes, puis exécute uniquement dans une VM de lab isolée que tu contrôles. Tests autorisés uniquement : usage responsable.