IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MySQL Discussion :

MySQL/MariaDB : alerte à une faille de sécurité "tragiquement comique"


Sujet :

MySQL

  1. #21
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    Par défaut
    Cela me conforte sur ce que je pense de MySQL et cie \o/ Merci
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  2. #22
    Membre émérite

    Homme Profil pro
    Software Developer
    Inscrit en
    Mars 2008
    Messages
    1 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Software Developer

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 470
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par gb_68 Voir le message
    J'avoue ne pas avoir tout de suite compris ce bug ayant une probabilité de 1/256.
    Voici quelques morceaux codes complémentaires :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /*
        Check that scrambled message corresponds to the password; the function
    [...]
      RETURN VALUE
        0  password is correct
        !0  password is invalid
    */
     
    my_bool
    check_scramble(const char *scramble_arg, const char *message,
                   const uint8 *hash_stage2)
    {
    Donc la fonction doit renvoyer 0 si le mot de passe est correcte et un nombre quelconque différent de zéro dans le cas contraire.
    C'est bien ce que fait memcmp
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
    Le hic est que le type retourné par memcmp est un int alors que my_bool est défini comme suit (/include/my_global.h)
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef char		my_bool; /* Small bool */
    Le cast int -> char revient à faire un modulo 256, soit transformer toutes les valeurs multiples de 256 en 0. Si l'on considère que memcmp va nous renvoyer de manière uniforme toutes les valeurs possibles alors l'on obtient cette roulette russe de 1/256 pour le mot de passe.
    Merci beaucoup pour toutes ces précisions

  3. #23
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    657
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 657
    Points : 1 240
    Points
    1 240
    Par défaut
    En même temps cela prouve l'utilité de l'open source.
    Combien de bugs inconnus et failles existent dans les SGBD dont le code est fermé ? de plus le fix est simple suffit de corriger et de recompiler.

    Bref on peut tout à faire faire du proprio , mais l’accès aux sources d'un produit permet finalement de pointer facilement des bugs ou des failles de sécurités.

    Comment savoir si tel ou tel système proprio n'a pas de backdoor ?

  4. #24
    Membre émérite

    Homme Profil pro
    Software Developer
    Inscrit en
    Mars 2008
    Messages
    1 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Software Developer

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 470
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par camus3 Voir le message
    En même temps cela prouve l'utilité de l'open source.
    Combien de bugs inconnus et failles existent dans les SGBD dont le code est fermé ? de plus le fix est simple suffit de corriger et de recompiler.

    Bref on peut tout à faire faire du proprio , mais l’accès aux sources d'un produit permet finalement de pointer facilement des bugs ou des failles de sécurités.

    Comment savoir si tel ou tel système proprio n'a pas de backdoor ?
    Bah l'avantage de ne pas avoir acces au code sources empeche les hackers de trouver des failles en regardant juste le code source.
    Ca leur demande beaucoup plus de travail aux hackers et d'avancer a tatonnement

  5. #25
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 7
    Points : 43
    Points
    43
    Par défaut
    Citation Envoyé par alex_vino Voir le message
    Bah l'avantage de ne pas avoir acces au code sources empeche les hackers de trouver des failles en regardant juste le code source.
    Ca leur demande beaucoup plus de travail aux hackers et d'avancer a tatonnement
    Celà n'empêche pas non plus les logiciels propriétaires d'être également touchés par des failles simplement exploitables, on a vu par exemple la CVE-2010-4669, où le fait de lancer un grand nombre de RA IPv6 sur un réseau avec un sipmple script fait planter les machines Windows du réseau... Et on pourrait noter que contrairement à la faille de MySQL, celle-ci ne semble toujours pas corrigée !

  6. #26
    Membre émérite

    Homme Profil pro
    Software Developer
    Inscrit en
    Mars 2008
    Messages
    1 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Software Developer

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 470
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par eti0123456789 Voir le message
    Celà n'empêche pas non plus les logiciels propriétaires d'être également touchés par des failles simplement exploitables, on a vu par exemple la CVE-2010-4669, où le fait de lancer un grand nombre de RA IPv6 sur un réseau avec un sipmple script fait planter les machines Windows du réseau... Et on pourrait noter que contrairement à la faille de MySQL, celle-ci ne semble toujours pas corrigée !
    Je suis entierement d'accord avec toi.

    Je disais juste que les pirates ont une lame en moins dans leur couteau suisse avec du code propriétaire.

  7. #27
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mars 2006
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Mars 2006
    Messages : 400
    Points : 562
    Points
    562
    Par défaut
    Citation Envoyé par Idelways Voir le message
    La faille se situe au niveau d'une librairie C dont dépendent ces SGBD. Il s'agit d'une erreur de casting qui a une chance sur 256 fois de se produire lors de la vérification du résultat de comparaison des mots de passe fournis et attendus (avec la fonction memcmp).
    Corrigez moi si je me trompe, mais il me semble que la faille en question ne se situe pas au niveau d'une fonction d'une bibliothèque tierce, mais est liée à la manière d'interpréter le résultat de cette fonction.

    En l'occurence, la fonction incriminée doit renvoyer 0 ou !0 sur 8 bits, mais se contente de renvoyer la valeur de retour de memcmp, 0 ou !0 sur 32 bits.
    Seuls les 8 bits de poids faible seront donc exploités par un code appelant cette fonction.

    Il s'agit donc d'un mauvais usage de la valeur de retour d'une fonction (memcmp).

  8. #28
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2011
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ariège (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2011
    Messages : 154
    Points : 282
    Points
    282
    Par défaut
    Citation Envoyé par alex_vino Voir le message
    Je disais juste que les pirates ont une lame en moins dans leur couteau suisse avec du code propriétaire.
    Loupé!
    Au contraire, l'obfuscation ne résout rien, elle donne simplement un sentiment de sécurité. Du coup quand le code est ouvert, plus de personnes lisent le code, (y compris des hackers qui publient leurs découvertes), et plus de personnes corrigent les failles, donc à priori le code est mieux sécurisé. Et puis dans le logiciel libre, quand on trouve une faille, on le dit. Du coup y'a plein de trolls comme toi qui disent que les logiciels libre sont moins sécurisés puisqu'ils communiquent sur leurs failles.

  9. #29
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut
    Citation Envoyé par gb_68 Voir le message
    Le cast int -> char revient à faire un modulo 256, soit transformer toutes les valeurs multiples de 256 en 0. Si l'on considère que memcmp va nous renvoyer de manière uniforme toutes les valeurs possibles alors l'on obtient cette roulette russe de 1/256 pour le mot de passe.
    Bon, j'ai toujours pas compris...

    En gros, la valeur renvoie 0 quand faux, ou un nombre entre 1 et plusieurs millions selon l'erreur du mot de passe et le degré de différence.

    Mais si j'essaye de transformer "2000" en char, il ne devrait pas y avoir une erreur de casting relevée par le moteur ? Ca ne me semble pas du tout évident de trouver ce genre d'erreur et de détecter que 512 = 0...

    Par ailleur, si on essaye toujours le même mot de passe, ca veut dire que l'on devrait avoir les même valeur, donc la même comparaison, donc le même modulo... donc finalement pas tant de problèmes que cela non?

    Quelqu'un pour m'éclairer ?

    Merci,
    Pierre

  10. #30
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 148
    Points : 28 113
    Points
    28 113
    Par défaut
    Citation Envoyé par pmithrandir Voir le message
    Bon, j'ai toujours pas compris...

    En gros, la valeur renvoie 0 quand faux, ou un nombre entre 1 et plusieurs millions selon l'erreur du mot de passe et le degré de différence.
    valeur de retour 0 : le mot de passe est le bon
    valeur de retour != 0 : le mot de passe n'est pas le bon.

    Maintenant, regardons de plus pres ce different de 0.

    Citation Envoyé par pmithrandir Voir le message
    si on essaye toujours le même mot de passe, ca veut dire que l'on devrait avoir les même valeur, donc la même comparaison, donc le même modulo... donc finalement pas tant de problèmes que cela non?
    Non, pas si c'est bien fait, ce qui est le cas. Tu ne hash pas le mot de passe, mais un couple mot de passe + grain de sel, donc le hash est different a chaque fois.

    Bien, nous avons donc un hash sur 32 bits, mais une comparaison qui va tronquer ca sur un char, c'est a dire sur 8 bits. Il suffit donc que les 8 bits de comparaison soient les memes pour que l'acces soit donne.

    Exemple foireux juste pour comprendre :
    hash qui va bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    00000000 11111111 01010101 00110011
    hash qui ne devrait pas aller, mais qui va bien si on ne regarde que les 8 premiers ou les 8 derniers bits :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    00000000 01010101 11111111 00110011
    Dans ce cas, la comparaison tronquee retourne 0, alors que la comparaison sur les 32 bits ne retourne pas 0.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  11. #31
    Membre éclairé Avatar de rt15
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2005
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 262
    Points : 665
    Points
    665
    Par défaut
    Citation Envoyé par pmithrandir Voir le message
    Quelqu'un pour m'éclairer ?
    Dans certaines (rares) implémentation de memcmp, la valeur de retour est "aléatoire" et ne "dépend pas" des valeurs en entrée. Tout en étant conforme à la norme bien sûr. Par exemple, comparer "a" et "b" renverra tantôt -1, -516, -2000... Que des nombres négatifs, mais de valeurs différentes d'un appel à l'autre. Apparemment c'est le cas de l'implémentation de la glibc sous Linux qui utilise SSE pour aider à obtenir une comparaison très rapide (Mais cette implémentation n'est pas souvent utilisée par gcc qui utilise une built-in). L'aléatoire est certainement introduit par utilisation d'une valeur non initialisée par la fonction elle même.

    Ensuite, pour ce qui est de la perte des octets de poids fort, il n'y a pas de "moteur", le code est en C. Donc au mieux on aurait une erreur ou un warning à la compilation, pas à l'exécution. Tout le souci est dans le cast implicite au niveau du return. Je ne sais pas pourquoi aucun warning n'est donné... Ce serait peut être pas mal que le compilo réclame un cast explicite à ce niveau. Avec un cast explicite, le problème aurait sauté au yeux des développeurs.

    gangsoleil -> Relit le code de alex_vino. Je ne pense pas que tu sois sur la bonne piste. Il n'y a pas troncation des valeurs comparées. Et il y a de bonne chance pour que le hash soit toujours le même, car le sel doit rester le même. Ce qu'on compare, c'est Hash(tentative + sel) avec la valeur stockée dans la table "user" de MySQL, qui elle même à été généré avec Hash(pwd + même sel).

    Code de simulation :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
    typedef char my_bool;
     
    /**
     * Implémentation de memcmp correcte, mais renvoyant des valeurs aléatoires.
     */
    int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
    {
      unsigned char* lpArea1;
      unsigned char* lpArea2;
      int nResult;
      int i;
     
      lpArea1 = (unsigned char*)ptr1;
      lpArea2 = (unsigned char*)ptr2;
     
      nResult = 0;
      for (i = 0; i < num; i++)
        if (lpArea1[i] != lpArea2[i])
        {
          nResult = rand() + 1;
          nResult = nResult * ((lpArea1[i] > lpArea2[i]) ? 1 : -1);
          break;
        }
      return nResult;
    }
     
    /**
     * Fonction vérifiant le mot de passe dans MySQL.
     */
    my_bool checkPwd(char* ref, char* pwd)
    {
      int nMemCmpResult;
     
      nMemCmpResult = my_memcmp(ref, pwd, 4);
      printf("%d -> ", nMemCmpResult);
     
      /* Le souci est dans la ligne suivante où on ne récupère que l'octet de poid faible de nMemCmpResult */
      return nMemCmpResult;
    }
     
    int main()
    {
      my_bool nMemCmpResult;
     
      srand(time(NULL));
     
      /* On essaie toujours le même mot de passe jusqu'à ce qu'il soit correcte */
      while (1)
      {
        nMemCmpResult = checkPwd("bbbb", "aaaa");
        printf("%d\n", nMemCmpResult);
        if (! nMemCmpResult)
        {
          printf("Pwd OK !\n");
          break;
        }
      }
     
      return 0;
    }

    Sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32208 -> -48
    17727 -> 63
    5728 -> 96
    19104 -> -96
    7460 -> 36
    25916 -> 60
    26045 -> -67
    21198 -> -50
    5390 -> 14
    29278 -> 94
    27887 -> -17
    2476 -> -84
    600 -> 88
    3870 -> 30
    6687 -> 31
    25618 -> 18
    2180 -> -124
    2750 -> -66
    4626 -> 18
    31743 -> -1
    ...
    9425 -> -47
    30113 -> -95
    4156 -> 60
    2683 -> 123
    10749 -> -3
    7017 -> 105
    10044 -> 60
    13231 -> -81
    19968 -> 0
    Pwd OK !
    [edit]
    A partir de gcc 4.3, -Wconversion permet de détecter ce problème.

  12. #32
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut
    Merci pour ces éclaircissements.

    Effectivement, je pensais qu'une méthode avec la même entrée(le sel est fixe sur un login donné) donnait toujours le même résultat. Je comprends mieux ma méprise.

    Le bon point, c'est que ca serait detecté par java sans problème, et je pense que meêm en PHP je ne pourrais pas avoir le même soucis.

    Pierre

  13. #33
    Membre actif
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 164
    Points : 227
    Points
    227
    Par défaut
    Pour ceux qui pensent être protégés par le fait que le serveur est ouvert que sur localhost faites tout de même attention.

    Si vous utilisez un système permettant de ce logger par l'intermédiaire d'un script (exemple typique phpmyadmin) il suffit théoriquement au pirate d'utiliser ces scripts.

    En pratique c'est un peu plus compliqué car avec phpmyadmin sauf astuce que je ne connais pas il faut faire 2 connexions (une pour entrer dans le logiciel avec le login+pass , une autre pour la requête) donc ça fait 256² requêtes ce qui est plus délicat mais suffisant pour être cassé rapidement.

  14. #34
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 148
    Points : 28 113
    Points
    28 113
    Par défaut
    Citation Envoyé par rt15 Voir le message
    Il n'y a pas troncation des valeurs comparées.
    Effectivement, mon exemple naif est trop naif, j'ai tronque les valeurs comparees, et non pas la valeur de retour.

    Je corrige donc naivement :

    comparaison qui retourne faux : 00000000 11111111 01010101 00110011

    Mais si on ne regarde que le 1er octet, ce qui se passe dans notre cas, la comparaison est vue comme juste.

    Merci de m'avoir alerte sur ma connerie
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

Discussions similaires

  1. Réponses: 34
    Dernier message: 19/06/2012, 09h05
  2. Réponses: 15
    Dernier message: 17/07/2009, 23h18
  3. Réponses: 0
    Dernier message: 15/07/2009, 12h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo