Buffer overflow

obtenu avec du code généré par gcc 2.95.4

Pré-requis

Quelques notions de programmation (C, assembleur)
Une plateforme linux (ou cygwin pour windows) avec gcc, gdb, as

Execution de code

Un processus chargé en mémoire, est divisé en plusieurs régions :

Déroulement d'un appel de fonctions

Appel de fonctions (code appelant)
  1. empiler les paramètres
  2. empiler l'adresse de retour
Entrée dans une fonction (code appelée)
  1. sauver l'emplacement de la base de la pile
  2. empiler les variables locales

Traduction C/assembleur

tiprog.c
Extrait de tiprog.s

gcc -S tiprog.c -o tiprog.s
Explications basiques
 
void ma_fonction(int a, int b, int c) {
        char buffer1[5];
        char buffer2[10];
}


void main() {
        ma_fonction(1,2,3);
}











          
ma_fonction:
        pushl %ebp
        movl %esp,%ebp
        subl $40,%esp
        leave
        ret

main:
        pushl %ebp
        movl %esp,%ebp
        subl $8,%esp
        addl $-4,%esp
        pushl $3
        pushl $2
        pushl $1
        call ma_fonction
        addl $16,%esp
        leave
        ret
	  


Sauvegarder base pile (Base Pointer)
Base pile prend valeur de Sommet pile (Stack Pointer)
Réservation mémoire pour les variables locales



main:
Sauvegarder base pile (Base Pointer)
Base pile prend valeur de Sommet pile (Stack Pointer)


Empiler >>>    (3)
>>> les >>>    (2)
>>> paramètres (1)
Appel de la fonction ma_fonction




	  
call : empile l'adresse de retour et modifie le registre d'instruction (Instruction Pointer)

Programme tout simple (qui va bientôt être violé :o=)

simpleprog.c
Désassemblage
$ gcc simpleprog.c -o simpleprog
$ gdb simpleprog
(gdb) disassemble bufover
(gdb) disassemble main
Explications basiques
void bufover() {
        char buffer[5];
        buffer[0] = 0;
}

int main() {
        int x;
        x = 0;
        bufover();
        x = 1;
        printf("%d\n", x);
        return 0;
}
          
Dump of assembler code for function bufover:
0x08048400 <bufover+0>: push   %ebp
0x08048401 <bufover+1>: mov    %esp,%ebp
0x08048403 <bufover+3>: sub    $0x18,%esp
0x08048406 <bufover+6>: movb   $0x0,0xfffffff8(%ebp)
0x0804840a <bufover+10>:        leave
0x0804840b <bufover+11>:        ret

Dump of assembler code for function main:
0x08048408 <main+0>:    push   %ebp
0x08048409 <main+1>:    mov    %esp,%ebp
0x0804840b <main+3>:    sub    $0x18,%esp
0x0804840e <main+6>:    movl   $0x0,0xfffffffc(%ebp)
0x08048415 <main+13>:   call   0x8048400 <bufover>
0x0804841a <main+18>:   movl   $0x1,0xfffffffc(%ebp)
0x08048421 <main+25>:   add    $0xfffffff8,%esp
0x08048424 <main+28>:   mov    0xfffffffc(%ebp),%eax
0x08048427 <main+31>:   push   %eax
0x08048428 <main+32>:   push   $0x8048560
0x0804842d <main+37>:   call   0x8048310 <__deregister_frame_info+32>
0x08048432 <main+42>:   add    $0x10,%esp
0x08048435 <main+45>:   xor    %eax,%eax
0x08048437 <main+47>:   jmp    0x8048440 <main+56>
0x08048439 <main+49>:   lea    0x0(%esi),%esi
0x08048440 <main+56>:   leave
0x08048441 <main+57>:   ret
0x08048442 <main+58>:   nop
          

empiler ebp (de la fonction main)


buffer[0] = 0;







x = 0;
Appel de la fonction bufover()
x = 1;












          

Modifier l'adresse de retour

On va modifier le programme précédent avec un buffer overflow, pour que l'instruction " x = 1; " ne soit pas exécutée
Pour sauter l'instruction " x = 1; "

Programme violé (enfin :)

simpleprog_viol.c :

void bufover() {
    char buffer[5];
    buffer[12] += 7;
}

int main() {
    int x;
    x = 0;
    bufover();
    x = 1;
    printf("%d\n", x);
    return 0;
}

Références

Les buffer overflows sur www.inet-sec.org

home envoyer un mail

Debian Get FireFox Valid HTML 4.01! Valid CSS!