Partage
  • Partager sur Facebook
  • Partager sur Twitter

Question sur l'attaque par buffer overflow

Sujet résolu
    16 décembre 2011 à 14:55:58

    Bonjour,

    Comme le titre l'indique, je me pose des questions sur l'attaque par buffer overflow. Non non, je ne vais pas vous demander comment on fait :p
    En fait je me demandais comment on peut être attaqué de cette façon ? Admettons que je fasse un programme avec des scanf, et que je le fasse partager à d'autre, les gens qui tenteront cette attaque ne pourront attaquer que l'ordi sur lequel se trouve le programme, non ? Et à priori, ce programme doit être sur l'ordinateur de l'utilisateur, donc du hackeur.
    Que risque-t-on sachant que le hackeur ne peut se faire du mal qu'à lui même ?

    J'espère m'être bien exprimé,
    Merci
    • Partager sur Facebook
    • Partager sur Twitter
      16 décembre 2011 à 14:58:33

      Je pense que ce sera plus simple si tu lis ça d'abord : wiki.
      • Partager sur Facebook
      • Partager sur Twitter
      Pour ceux qui souhaiteraient apprendre à développer en Rust, un tuto en français est dispo ici. Pour voir mes projets : github.
        16 décembre 2011 à 15:06:16

        Necati, haha je pensais ça au début ^^

        Bah imagine que le programme soit sur un serveur distant par exemple ^^
        Ou sinon pour les jeux-vidéos aussi t'es pas sensé prendre le contrôle de ta console (malgré le fait que tu l'ai acheté) donc si un jeu à une faille, tu pourras l'exploiter et en faire ce que tu veux (de la console).

        Des exemple hein, bref faut vérifier ses buffer.
        • Partager sur Facebook
        • Partager sur Twitter
          16 décembre 2011 à 15:08:35

          Un exemple simple de buffer overflow :

          char c[10] = "";
          
          printf("Rentrez un truc de plus de 10 caractères :\n");
          scanf("%s", c);
          
          • Partager sur Facebook
          • Partager sur Twitter
          Pour ceux qui souhaiteraient apprendre à développer en Rust, un tuto en français est dispo ici. Pour voir mes projets : github.
            16 décembre 2011 à 15:12:47

            Désolé Imperio, ton lien est très intéressant mais je savais déjà tout ça (enfin pas en détails, mais je savais globalement), je crois que tu as pas compris ma question mais merci quand même ^^

            Mr21, c'est ce que je voulais savoir, merci :p
            • Partager sur Facebook
            • Partager sur Twitter
              16 décembre 2011 à 15:15:52

              imperio un meilleur exemple :D
              #include        <stdio.h>
              #include        <stdlib.h>
              
              int             main(void)
              {
                char          s[6] = "";
                char          admin = 0;
              
                printf("mot de pass: ");
                scanf("%s", s);
              
                if (strcmp(s, "mr21") == 0)
                  admin = 1;
              
                if (admin)
                  printf("Vous etes admin (oopa :D)\n");
                else
                  printf("go away thx\n");
                return 0;
              }
              


              > ./a.out
              mot de pass: lol
              go away thx
              
              > ./a.out
              mot de pass: mr21
              Vous etes admin (oopa :D)
              
              > ./a.out
              mot de pass: aaaaaaa
              Vous etes admin (oopa :D)


              Voilà ^^
              • Partager sur Facebook
              • Partager sur Twitter
                16 décembre 2011 à 15:34:07

                Et bien t'as vu, j'ai écris 7 'a' or mon buffer ne pouvait en accueillir que 6.
                Donc le 'a' en trop, va se loger dans la case qui suit le s[5] à savoir le s[6].

                Sauf qu'en vrai il n'y a pas de s[6] donc la variable derrière ça c'est char admin; comprends tu?
                en résumé: &s[6] == &admin
                • Partager sur Facebook
                • Partager sur Twitter
                  16 décembre 2011 à 15:38:04

                  Là j'crois qu'il lui aurait fallu un p'tit schéma pour représenter la mémoire. Pas mal ton exemple meilleur que le mien en tout cas :lol: ) !
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Pour ceux qui souhaiteraient apprendre à développer en Rust, un tuto en français est dispo ici. Pour voir mes projets : github.
                    16 décembre 2011 à 16:26:56

                    Citation : Mr21

                    Et bien t'as vu, j'ai écris 7 'a' or mon buffer ne pouvait en accueillir que 6.
                    Donc le 'a' en trop, va se loger dans la case qui suit le s[5] à savoir le s[6].

                    Sauf qu'en vrai il n'y a pas de s[6] donc la variable derrière ça c'est char admin; comprends tu?
                    en résumé: &s[6] == &admin



                    Je comprends, merci ^^

                    Mais qui te dis que char admin est juste derrière ?
                    Un petit schéma pour te montrer ce que je veux dire

                    Adresse Contenu
                    105461 Occupé par un autre programme
                    105462 Libre
                    105463 Libre
                    105464 Libre
                    105465 Libre
                    105466 Libre
                    105467 Libre
                    105468 Occupé par un autre programme
                    105469 Occupé par un autre programme
                    105470 Occupé par un autre programme
                    105471 Occupé par un autre programme
                    105472 Libre


                    Dans ce cas-là, le tableau ira se mettre à l'adresse 105462 et occupera les adresses allant de 105462 à 105467, mais comme les adresses suivantes sont déjà utilisés par un autre programme, alors "admin" ira se mettre dans 105472. Donc même si tu mets des caractères en plus à ta chaîne, tu peux pas avoir la certitude que ça va atteindre "admin"...
                    • Partager sur Facebook
                    • Partager sur Twitter
                      16 décembre 2011 à 16:32:50

                      Ah bah au moins on voit que tu as tout compris c'est cool!

                      Et bien à présent tu as à savoir que les variables se collent en mémoire donc ^^
                      C'est comme les structures etc.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        16 décembre 2011 à 16:40:37

                        Je m'attendais à ce que tu dises ça ^^

                        Admettons qu'on a les cases allant de 1000 à 1100. Ne sont occupés que les cases allant jusqu'à 1050. Le tableau ira se mettre à partir de 1050, mais si un programme libère des surfaces et s'éteint entre-temps, et que ce programme occupait les cases allant de 1000 à 1050, elle seront de nouveau "vides", donc les prochaines variables iront se placer avant le tableau, et non pas après.

                        Je me trompe ?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          16 décembre 2011 à 16:57:42

                          En fait, tes variables sont dans une zone de la mémoire que l'on appelle la pile. A priori, tu ne sais pas où est ta pile en mémoire (c'est l'OS qui gère ça), ni même où tu es dans la pile (ça dépend de ce qu'a fait ton programme avant d'appeler la fonction, même si avec main on a une petite idée ^^)(il y a une pile par programme). Par contre, quand tu appelles une fonction, elle prend directement la place dans la pile pour y mettre ses variables, et elle le fait toujours de la même façon, donc si admin est collé après s une fois, ce sera toujours le cas. (Et pour savoir si c'est le cas, il "suffit" de désassembler le code)
                          • Partager sur Facebook
                          • Partager sur Twitter
                          64kB de mémoire, c'est tout ce dont j'ai besoin
                          Anonyme
                            16 décembre 2011 à 16:59:28

                            Je ne m'y connais pas du tout dans ce domaine, mais je pense que c'est le genre de faille qu'un virus peux exploiter une fois installé sur le PC, non ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              16 décembre 2011 à 17:20:32

                              Perso j'y connais rien dans tout ça, mais je ne crois que ça utilise le même genre de procédé non.

                              Les virus sont conçu pour se copier plein de fois et se faire ré-envoyer à tes contacts etc. donc bon j'en sais rien.
                              Pour moi un virus une fois installé cherche ce qu'il veut, se copie et bousille ton ordi stoo, jvois pas ce qu'il chercherai à cracker un logiciel.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                16 décembre 2011 à 18:00:44

                                Pour exploiter un buffer overflow, il faut étudier spécifiquement le programme qui présente cette faille. Sur les programmes très répandus, on trouve rarement ce genre de failles, donc peu de virus vont les cibler.

                                Pour développer les virus, on va préférer viser une faille de sécurité dans le noyau de l'OS, acquérir les droits root, et s'installer en tant qu'application à lancer avec l'OS avec privilèges root (ce qui permet de garder le contrôle de la machine même une fois la mise à jour de sécurité appliquée). Sinon, plus basiquement, on va se greffer sur un soft et utiliser les privilèges de ce soft pour envoyer des mails et ouvrir des pubs sur la machine infectée (dans le cas d'une appli comme firefox par exemple). Pour cela, il suffit de trouver une faille dans le processus d'authentification des greffons de firefox, ou même de demander à l'utilisateur d'installer le programme malveillant.

                                En fait, les programmes malveillants sont de nombreux types différents, et il n'ont pas une manière unique de procéder. Elle dépend souvent de l'objectif du programmeur qui crée le virus.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                64kB de mémoire, c'est tout ce dont j'ai besoin
                                  16 décembre 2011 à 18:06:58

                                  Citation : Nathalya

                                  En fait, tes variables sont dans une zone de la mémoire que l'on appelle la pile. A priori, tu ne sais pas où est ta pile en mémoire (c'est l'OS qui gère ça), ni même où tu es dans la pile (ça dépend de ce qu'a fait ton programme avant d'appeler la fonction, même si avec main on a une petite idée ^^)(il y a une pile par programme). Par contre, quand tu appelles une fonction, elle prend directement la place dans la pile pour y mettre ses variables, et elle le fait toujours de la même façon, donc si admin est collé après s une fois, ce sera toujours le cas. (Et pour savoir si c'est le cas, il "suffit" de désassembler le code)



                                  Citation : Mr21

                                  Et bien à présent tu as à savoir que les variables se collent en mémoire donc ^^



                                  Vous êtes pas d'accord j'ai l'impression :D
                                  D'après Nathalya, il serait fort possible qu'il y ait des espaces vides entre les adresses de la mémoire vive... ou alors j'ai pas bien compris :o
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    16 décembre 2011 à 18:12:25

                                    Nan nan j'crois qu'elle dit la même chose que moi en mode pro-compliqué quoi :D
                                    En tout cas mon exemple parle de lui même, jsuis très terre à terre en prog on va dire.

                                    Essaye de l'executer sur un autre ordi jsuis sûr que le même bug arrivera de la même manière ^^
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      16 décembre 2011 à 18:24:39

                                      Citation : Mr21

                                      Essaye de l'executer sur un autre ordi jsuis que le même bug arrivera de la même manière ^^



                                      Je n'en doute pas, mais la flemme :-°

                                      Bref, merci vous deux de m'avoir instruit :)
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        16 décembre 2011 à 18:41:05

                                        Citation : Mr21

                                        Essaye de l'executer sur un autre ordi jsuis que le même bug arrivera de la même manière ^^


                                        Non, pas forcément. Tu ne maîtrises pas l'évolution de ta pile, donc si le tableau est mis après la variable, ton programme ne 'fonctionnera' pas (le hack). Il faut être sûr de l'architecture de la machine cible (et éventuellement du compilateur qui peut changer des trucs (ce que fait gcc)). ;)
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          16 décembre 2011 à 18:48:59

                                          Citation : Necati

                                          D'après Nathalya, il serait fort possible qu'il y ait des espaces vides entre les adresses de la mémoire vive... ou alors j'ai pas bien compris :o


                                          En fait, c'est ton compilateur qui choisi où il met les variables en mémoire. Chez Mr21, il a mis admin après s. Si tu compiles avec le même compilateur, tu auras le même résultat. En fait tu auras ça sur la plupart des compilateurs, parce qu'il est logique de ne pas laisser de place inutile entre les variables, et que, contraintes d'alignement mises à part, il est logique de mettre les variables dans la mémoire dans l'ordre dans lequel elles sont déclarées. Mais rien n'oblige à avoir exactement cette organisation en mémoire (ce qu'indique Pouet dans son message).

                                          Ce que je dis, c'est que, par contre, une fois compilé, ton programme se comportera toujours de la même façon, et que ton schéma précédent ne peut pas s'appliquer. Le tableau s ne va pas être mis au premier endroit où on trouvera 6 octets de libre en mémoire, mais on va affecter une grande zone de mémoire pour ce qu'on appelle la pile de ton programme, en ton programme sera le seul à l'utiliser. aucun risque donc d'avoir des octets utilisés par d'autres programmes au milieu.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          64kB de mémoire, c'est tout ce dont j'ai besoin
                                            16 décembre 2011 à 18:55:51

                                            Là j'ai bien compris, merci beaucoup ^^
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              16 décembre 2011 à 20:03:50

                                              Citation

                                              Bref, merci vous deux de m'avoir instruit :)

                                              Pour ma part je m'instruis en même temps tsais, donc merci à toi de poser des question :D

                                              pouet, je parlais juste de l'executer pour montrer à Necati que ce n'était pas une question de placement random en mémoire.
                                              Ceci dit jparle sans être sûr c'est juste que non seulement c'est logique que ça se passe comme ça, mais en plus j'ai toujours vu ce comportement.

                                              Rien n'oblige les compilo à faire ça etc. sauf que si ils le font tous ça devient implicitement un standart non?
                                              Comment se fait-il que ce comportement soit naturel pour les structure alors? (ex: faire un fread de structure par exemple)
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                16 décembre 2011 à 21:28:46

                                                C'est peut-être logique, mais ça ne fonctionne pas forcément comme ça. La preuve, chez moi ça ne fonctionne pas :

                                                >> ./a.out 
                                                mot de pass: lol
                                                go away thx
                                                pouet@pouet-imac 
                                                >> ./a.out 
                                                mot de pass: mr21
                                                Vous etes admin (oopa :D)
                                                pouet@pouet-imac 
                                                >> ./a.out 
                                                mot de pass: aaaaaaa
                                                go away thx
                                                pouet@pouet-imac 
                                                >>

                                                Tu as juste à désassembler le programme pour voir où il place les variables. :)
                                                En plus de ça, gcc 'bloque' les buffer overflow (peut-être pas tous) ! Il faut rajouter une option de compilation pour l'autoriser. ^^
                                                Tous les compilos ne le font pas, ils sont libres de le faire comme ils le souhaitent. :)
                                                Pour la structure c'est complètement différent, c'est marqué dans la norme :

                                                Citation : Norme : 6.7.2.1

                                                As discussed in 6.2.5, a structure is a type consisting of a sequence of members, whose storage is allocated in an ordered sequence, and a union is a type consisting of a sequence of members whose storage overlap.


                                                Pour faire une attaque basique, tu as juste à écraser l'adresse de retour de ta fonction en plaçant l'adresse de ton programme, et hop le tour est joué. :)
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                Question sur l'attaque par buffer overflow

                                                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                • Editeur
                                                • Markdown