Failles de sécurité dans openssl

Posté par  . Modéré par Fabien Penso.
Étiquettes :
0
30
juil.
2002
Sécurité
Des failles de sécurité dans openssl 0.9.6d ou inférieur ou 0.9.7-beta2 ou inférieur ont été découvertes par A.L. Digital Ltd et The Bunker lors d'un audit de securité. Pas moins de 4 vulnerabilités sont exploitables.

Aller plus loin

  • # heu

    Posté par  . Évalué à 10.

    "4 vulnerabilités exploitables" ca vaudrait peut etre le coup de mettre un s a "faille" non ? :)
    bon allez tous a vos upgrades!!!
    • [^] # Re: heu

      Posté par  . Évalué à 7.

      4 vulnerabilité exploitables
      on peut aussi mettre un s à vulnérabilité non ? :)
    • [^] # Re: heu

      Posté par  . Évalué à 10.

      bon allez tous a vos upgrades!!!
      C'est amusant, on a toujours ce genre de réaction.. à croire que tout le monde utilise son PC pour faire des serveurs..
      C'est passé de mode d'utiliser son PC comme Ordinateur Personnel ? Moi, j'ai betement un seul compte (le mien) et aucun ports ouverts en permanence..
      -> -1 bien sur
      • [^] # Re: heu

        Posté par  . Évalué à 10.

        Bof, même sans être serveur, j'ai quand même AU MOINS ssh sur toutes mes machines. C'est vraiment pratique. Même sur le portable, quand je fais dans un bureau d'un collègue, ça peut servir...
  • # petite erreur

    Posté par  . Évalué à 10.

    C'est pas "openssl 0.9.6d ou supérieur" mais, d'après l'alerte sur le site d'openssl "OpenSSL 0.9.6d or earlier". Donc les versions 0.9.6{a|b|c} qui sont dans toutes les distros linux sont concernées !

    Grrrr.
    • [^] # Re: petite erreur

      Posté par  . Évalué à 10.

      dans tout les cas IL FAUT UPGRADER c'est important!!
      moi dans ma boite je me bat pour les mises a jours!! De plus le droit francais rend l'utilisateur responsable de la securité de sa machine !!
      • [^] # Re: petite erreur

        Posté par  . Évalué à 8.

        De plus le droit francais rend l'utilisateur responsable de la securité de sa machine !!

        As tu plus d'information à ce sujet (lien vers un texte de loi, jurisprudence ...) ?

        Ca m'intéresse au plus haut point.
  • # Putain, ça va être chiant

    Posté par  . Évalué à 10.

    Lu dans l'advisory :

    Apply the attached patch to OpenSSL 0.9.6d, or upgrade to OpenSSL 0.9.6e. Recompile all applications using OpenSSL to provide SSL or TLS.

    Il va falloir tout recompiler (ou upgrader tous les packges pour ceux qui utilisent des paquets precompilés) ?
    • [^] # Re: Putain, ça va être chiant

      Posté par  . Évalué à 10.

      A mon avis ça doit être comme pour la zlib, il faut recompiler tous les packages qui sont liés statiquement à la lib. Pour les autres je pense que la recompilation de openssl suffit.
      Enfin je dis peut-être des conneries....
      • [^] # Re: Putain, ça va être chiant

        Posté par  . Évalué à 3.

        Ouais mais comment savoir, comme ça hop, si un package est compilé dynamiquement ou statiquement. Je m'amuse pas à noter ce qui passe quand je compile, moi... (et je ne parle pas des paquets binaires : impossible de savoir de manière évidente)
  • # Quelques programmes concernés

    Posté par  . Évalué à 10.

    mod_ssl
    apache-ssl
    openssh
    postfix-tls

    je précise, c'est pas forcément évident pour tout le monde que SSH soit basé sur OpenSSL...

    tous à vos compilos, ou apt/rpm/autoinstallerX !
  • # Le pire...

    Posté par  . Évalué à 10.

    C'est que ce sont vraiment des bugs communs :

    1. The client master key in SSL2 could be oversized and overrun a
    buffer. This vulnerability was also independently discovered by
    consultants at Neohapsis (http://www.neohapsis.com/(...)) who have also
    demonstrated that the vulerability is exploitable. Exploit code is
    NOT available at this time.

    2. The session ID supplied to a client in SSL3 could be oversized and
    overrun a buffer.

    3. The master key supplied to an SSL3 server could be oversized and
    overrun a stack-based buffer. This issues only affects OpenSSL
    0.9.7 before 0.9.7-beta3 with Kerberos enabled.

    4. Various buffers for ASCII representations of integers were too
    small on 64 bit platforms.


    En clair : buffers overflows et types de données mal utilisés. Pffff, mettre à jour pour ça ! Si encore c'était de la cryptanalyse de la mort qui tue, on se consolerait en admirant la formidable construction théorique qui mènerait à la mise en évidence de la vulnérabilité. Mais là, non, rien d'intéressant à se mettre sous la dent, que dalle, juste la routine glabre des mises à jour pluvieuses.

    En plus, c'est dans la procédure d'échange de clés, bref le moment crucial dans ce type de protocole. Et hop, en plein au milieu ! Des bugs d'informaticien de base, tout ça dans la partie critique de packages hyper-sensibles... :-(
    • [^] # Re: Le pire...

      Posté par  . Évalué à 7.

      C'est que ce sont vraiment des bugs communs [...] En clair : buffers overflows et types de données mal utilisés.

      Je ne vais pas être très constructif avec ce message mais je suis réellement surpris qu'on puisse encore laisser des bugs pareils. Ils utilisent encore des strcpy() et des sprintf() au lieu de strncpy() et snprintf() ? Ca donne envie de n'utiliser que des programmes écrits par Daniel Bernstein (qmail (mailer daemon sans faille connue), djbdns (bind mais sans trous), et j'en oublie) malgré la licence un peu restrictive (on ne peut pas redistribuer du code modifié sous le nom original, seulement des patches, il faut lui soumettre pour approbation et intégration), mais il ne peut pas tout faire !

      Je suis encore plus surpris et déçu par OpenSSH, dont s'occupe Theo de Raadt, pour qui la sécurité justifiait un "fork" de OpenBSD. Quand on voit les bugs/trous de sécurité trouvés dans OpenSSH ces derniers mois, je crois me souvenir qu'il y a eu des "buffer overflow".

      J'ai entendu parler récemment d'un analyseur de code capable de détecter une bonne partie des fonctions douteuses et des risques de bugs de sécurité. Quelqu'un se souvient de quoi il s'agit ?
      • [^] # Est-ce que tu programme ?

        Posté par  (site web personnel) . Évalué à 10.

        Ils utilisent encore des strcpy() et des sprintf() au lieu de strncpy() et snprintf()

        Tu sais, il y a aussi des buffer overflows qui sont exploitables avec les fonctions que tu proposes ? Ce n'est pas tout de dire qu'il faut les utiliser, encore faut-il le faire correctement. Et crois-moi, c'est loin d'être le cas pour tout le monde.

        Par exemple, sais-tu comment est géré la caractère de fin de chaîne pour les fonctions dont tu parles (et strncpy que tu as omis) ? Si je peux me permettre un coup de pub, tu devrais acheter le dernier MISC où il y a un excellent article là-dessus.

        Et puis il y a d'autres moyens d'arriver à des overflows (realpath(), gets(), scanf(), ...) Tu ne t'es jamais dit que si c'était facile de trouver toutes ces failles simplement en faisant un egrep "printf|strcpy|strcat" *c, ça fait longtemps que la question serait réglée ?
        • [^] # Re: Est-ce que tu programme ?

          Posté par  . Évalué à 1.

          Tu sais, il y a aussi des buffer overflows qui sont exploitables avec les fonctions que tu proposes ? Ce n'est pas tout de dire qu'il faut les utiliser, encore faut-il le faire correctement.

          Si tu as un exemple de buffer overflow avec strncpy() et snprintf() à montrer, je suis preneur, ça m'intéresse (sérieux).
          Cela dit, tu as raison qu'il faut malgré tout utiliser correctement les fonctions en question. J'ai été étonné de voir des collègues sensés être expérimentés (plusieurs années) coder sans aucune sécurité. Personnellement (et pour répondre à ton titre) je teste toujours les valeurs de retour et je vérifie beaucoup de choses. C'est là qu'on voit que l'expérience a une valeur relative car des "petits jeunes" codent parfois beaucoup mieux qu'un supposé expérimenté.

          Par exemple, sais-tu comment est géré la caractère de fin de chaîne pour les fonctions dont tu parles (et strncpy que tu as omis) ?

          En cas d'oubli, un petit coup de "man strncpy" et c'est bon (je viens de le faire). Au fait je n'ai pas omis strncpy, j'en parlais justement dans mon message précédent (et tu l'as cité) ?!

          il y a d'autres moyens d'arriver à des overflows (realpath(), gets(), scanf(), ...)

          Il est déconseillé d'utiliser gets(), c'est même marqué dans la page de man : "No check for buffer overrun is performed (see BUGS below)", il est conseillé d'utiliser fgets() à la place.

          Au fait, printf() ne permet pas de faire de buffer overflow que je sache (sprintf() oui puisqu'on écrit dans un buffer).
          • [^] # un exemple

            Posté par  (site web personnel) . Évalué à 1.

            Et hop, puisque tu le demandes :)
            Je précise que cet exemple a été construit par OUAH et que je l'ai aussi utilisé dans ma présentation sur la programmation sécurisée aux LSM.

            /*
            * « Is this really exploitable ? »
            * « yes ! »
            * « But ... I'm trying to use the safe function strncpy() !!! »
            * « Do, or do not, there is no try »
            *
            * vuln-stack-ov3.c
            * By Olivier Gay (OUAH) <olivier.gay@dimail.epfl.ch>
            * Adapted for my needs by Frédéric Raynal <pappy@miscmag.com>
            * (c) 2002
            */

            #include <string.h>

            void func(char *str) {
            char buffer[12];
            strcpy(buffer, str);
            }

            main(int argc, char *argv[])
            {
            char arg2[24];
            char arg1[8];

            printf("Welcome in the strncpy secure program :)\n");
            if (argc > 2) {
            strncpy(arg1, argv[1], sizeof(arg1));
            strncpy(arg2, argv[2], sizeof(arg2));
            func(arg1);
            }
            }


            La solution est (entre autre) dans MISC :-)

            Quant à gets)(, merci je sais. Le compilo, s'il est récent, te préviens même. Mais les gens n'ont pas encore compris que faire gets() ou scanf("%s", str), c'est pareil ...

            PS: désolé pour l'indentation, mais avec <pre>, ça fait n truc de 3Km de long...
            • [^] # Re: un exemple

              Posté par  . Évalué à 0.

              void func(char *str) {
              char buffer[12];
              strcpy(buffer, str);
              }


              Tu es gentil, tu as utilisé un strcpy() !!
              Montre-moi un programme vulnérable qui ne contient que des strncpy() bien utilisés.
              La simple lecture de la fonction "func" m'a fait frémir avant même de lire la suite.
              Et à quoi sert "arg2", il n'est pas utilisé ?
              • [^] # Re: un exemple

                Posté par  . Évalué à 0.

                Réfléchis 3 secondes...
                strcpy est utilisé, certes.
                Mais si les choses se passaient bien, arg1 serait copié dans buffer. arg1 a une taille de 8 octets, buffer de 12. C'est pas le fait que strcpy soit utilisé qui pose problème ici.

                La problématique ici, c'est les 2 appels successif à strncpy sans 0 terminal.

                qui entraine le fait que arg1 se retrouve avec une taille supérieure à 8.
                • [^] # Re: un exemple

                  Posté par  . Évalué à 1.

                  C'est pas le fait que strcpy soit utilisé qui pose problème ici

                  Et bien si justement, puisqu'avec un strcpy on prend le risque d'avoir le buffer copié plus grand que celui de destination. Il ne faut pas réfléchir plus loin, PAS DE strcpy.

                  La problématique ici, c'est les 2 appels successif à strncpy sans 0 terminal.

                  Le problème c'est que la personne qui a programmé ne sait pas lire la page de man (cf la remarque de PLuG plus bas).
                  • [^] # Re: un exemple

                    Posté par  . Évalué à 4.

                    Et bien si justement, puisqu'avec un strcpy on prend le risque d'avoir le buffer copié plus grand que celui de destination. Il ne faut pas réfléchir plus loin, PAS DE strcpy.
                    Evidémment, pas de strcpy. La dessus on est tous d'accord ;)
                    Par contre, les fonctions strn*, comme l'explique pappy, peuvent elles aussi, si elles sont mal employées etre des sources de danger.
                    A partir du moment que ta chaine peut etre non-terminée, tu cours des risques insensés à l'utiliser.

                    Le problème c'est que la personne qui a programmé ne sait pas lire la page de man

                    Certes, mais si tt le monde lisait correctement les mans et programmaient sans failles, y'aurait pas de problème et on vivraient tous dans le meilleur des mondes :)

                    Je rappelle pour info que le man de strcpy lui aussi prévient des dangers d'une mauvaise utilisation de cette derniere.

                    A là limite, si quitte à proposer une alternative à strcpy, autant proposer les fonctions strl*(et encore, il arrive bien souvent que la taille spécifiée en 3ème paramètre soit fournie de façon dangereuse par le programmeur(qu'elle soit manipulable)...)...
                    • [^] # Le man ne suffit pas

                      Posté par  . Évalué à 2.

                      C'est quand même problématique ce que vous racontez, parce qu'à cause de ça je vais devoir me taper tout le code de la glibc avant de me décider à utiliser une fonction. Mon Dieu!

                      Je suis admin, pas programmeur, mais je développe parfois des petits progs en perl ou c, comme des cgi et autres. Et la plupart du temps, je me pose pas la question de savoir si une fonction est vraiment sûre pour l'usage que j'en fais (j'ai honte), parce que ça demande un sacré boulot de le vérifier ! Et je pense pas être le seul à ne pas le faire...

                      N'y aurait-il pas une qqpart une liste des fonctions de la libc dont on peut être sûr, ou accompagnée d'indications exhaustives (mieux que le man) concernant leur fonctionnement?

                      Ne pourrait-on pas programmer une libc sécurisée et compatible? J'ai entendu parler de partchs de sécurité à la glibc. Quid?
                      • [^] # Re: Le man ne suffit pas

                        Posté par  . Évalué à 0.

                        N'y aurait-il pas qqpart une liste des fonctions de la libc dont on peut être sûr

                        Houla pas tant d'inquiétude.
                        Toutes les fonctions sont potentiellement dangereuses, ça dépend comment tu t'en sers.
                        Que le strpcy() puisse être dangereux, c'est une question de bon sens car la copie s'arrête quand elle rencontre un '\0' (caractère de fin de chaîne en C), et s'il n'y a pas de zéro avant longtemps, la copie finit par déborder.
                        Pour faire un programme sûr, il faut ne pas faire confiance à ce qui entre (vérifier les tailles des paramètres, les valeurs pour les quantités). Pour la libc, de préférence utiliser les fonctions avec le "n" comme strncpy et snprintf, qui assurent de ne pas déborder le buffer dans lequel on écrit puisqu'on peut fixer une limite. Il suffit de regarder une fois la page de man pour les quelques fonctions de manipulation de chaîne que tu utilises, et c'est bon.
                        Je n'en ai pas sous la main mais il y a des URL qui t'expliquent comment programmer de la façon la plus sûre possible.
              • [^] # Un autre ? Pas de pb :)

                Posté par  (site web personnel) . Évalué à 2.

                Tu es gentil aussi ;-)

                Tu as au moins vu le problème ? Parce que figure toi que le problème, il ne vient pas du strcpy() ...
                L'argument de func() est en fait arg1, qui compte 8 caractères. Et arg1 est recopié dans buffer, qui en fait 12. Donc pas de problème (ou presque ;-)

                Mais pour te faire plaisir, voici un autre exemple tiré du même article (et tu devrais vraiment aller acheter MISC ;-)

                1 #include <stdio.h>
                2 #include <string.h>
                3
                4 func(char *sm) {
                5 char buffer[128]="kab00m!!";
                6 char entry[1024];
                7
                8 strncpy(entry, sm, sizeof(entry)-1);
                9 entry[sizeof(entry)-1] = '\0';
                10
                11 strncat(buffer, entry, sizeof(buffer)-strlen(buffer));
                12
                13 printf ("%s\n", buffer);
                14 }
                15
                16 main(int argc, char *argv[])
                17 {
                18
                19 if (argc > 1) func(argv[1]);
                20
                21 }

                Que du strn*(),ça devrait te plaire :)

                Et pourtant ...
                • [^] # Re: Un autre ? Pas de pb :)

                  Posté par  . Évalué à 0.

                  Mais pour te faire plaisir, voici un autre exemple tiré du même article (et tu devrais vraiment aller acheter MISC ;-)

                  Un seul mot, In-dis-pen-sable! :)
                • [^] # Re: Un autre ? Pas de pb :)

                  Posté par  . Évalué à 1.

                  comme d'hab il faut lire les pages de man ...

                  exemple:
                   The  strncpy()  function  is similar, except that not more
                  than n bytes of src are copied. Thus, if there is no null
                  byte among the first n bytes of src, the result will not
                  be null-terminated.
                  • [^] # oui ! mais la bonne ;-)

                    Posté par  (site web personnel) . Évalué à 2.

                    En ligne 9, le caractère de fin de chaîne est bien placé, juste après le strncpy(). Comme ça, même si il y a le pb que tu mentionnes avec strncpy(), on est quand même certain d'avoir un octet NULL à la fin de la chaîne.

                    Le problème vient ici du strncat() en ligne 11, mais je n'en dis pas plus pour laisser monter le suspense ;-)
                • [^] # Re: Un autre ? Pas de pb :)

                  Posté par  . Évalué à 2.

                  Parce que figure toi que le problème, il ne vient pas du strcpy()

                  Je ne suis pas d'accord, regarde ma réponse précédente à Iluvatar.

                  strncat(buffer, entry, sizeof(buffer)-strlen(buffer));

                  Il ne faut jamais perdre de vue que dans un buffer de taille n (char buffer[n]) on ne met réellement que n-1 caractères puisqu'il y a le '\0' terminal (en l'occurence les lignes 8 et 9 de ton exemple le prennent en compte).
                  Je pense que comme strncat rajoute un '\0' à la fin de buffer après avoir copié au max (sizeof(buffer)-strlen(buffer)) (cf la page de man), il faudrait mettre sizeof(buffer)-strlen(buffer) - 1
                  Je n'ai pas testé pour voir mais ça doit être la solution.
                  • [^] # Re: Un autre ? Pas de pb :)

                    Posté par  . Évalué à 1.

                    Il est évident qu'une fonction, si elle est bien
                    utilisée ne pose pas de problème.

                    Pourtant, démontrer que

                    char buf[42];
                    strcpy(buf, "hello");

                    n'est pas vulnérable ne démontre pas pour autant que strcpy est une *bonne* fonction.

                    Il faut juste noter que strncpy, tout comme strcpy sont des fonctions souvent mal utilisées, et ce malgré les avertissements dans les mans respectifs.
      • [^] # Re: Le pire...

        Posté par  . Évalué à 6.

        il y en a plusieurs, une rechercher sur freshmeat retourne entre autre R.A.T.S, un soft que je n'ai jamais eu le temps de tester mais qui m'avais paru sympa ....
        http://www.securesoftware.com/rats.php(...)

        d'un autre cote il ne faut pas croire que passer un test automatique prouve que le soft est sûr, tout comme passer a "lint" ne prouve pas qu'il n'y aura pas de bugs ...

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.