MySQL et MariaDB : alerte à une faille de sécurité "tragiquement comique"
50 % des serveurs seraient touchés

Les rubriques (actu, forums, tutos) de Développez
Tags
Réseaux sociaux


 Discussion forum

Sur le même sujet
Le , par Idelways, Expert Confirmé Sénior
MySQL et son fork MariaDB souffrent d'une grave vulnérabilité à une attaque de force brute, prodigieusement facile à exploiter.

En peu de secondes, un pirate peut contourner l'authentification aux serveurs de base de données pour peu qu'il dispose d'un nom d'utilisateur correct (« root » est en général toujours présent et actif avec un maximum de prévilèges).
Il suffit au pirate de répéter quelques centaines de tentatives de connexion avec un mot de passe erroné et le tour est joué, explique Sergei Golubchi, coordinateur sécurité à MariaDB sur le mailing-list oss-sec.

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). De ce fait, entre 300 et 512 tentatives de connexions devraient suffire pour gagner un accès non autorisé à la base.

Code bash :
$ for i in `seq 1 1000`; do mysql -u root --password=bad -h 127.0.0.1 2>/dev/null; done
Boucle shell pour tester la vulnérabilité de son serveur

Mais tous les builds ne sont pas vulnérables estime HD Moore, un expert en sécurité reconnu. Les builds officiels ne peuvent en l'occurrence être compromis à partir des versions 5.1.61, 5.2.11, 5.3.5 et 5.5.22.
Ce n'est pas le cas de ceux d'Ubuntu Linux 64-bit (versions 8.04 jusqu'à la 12.04), OpenSuSE 12.1 64-bit MySQL 5.5.23-log, Debian Unstable 64-bit 5.5.23-2, Fedora, et Arch Linux.

Les développeurs d'Ubuntu ont annoncé des mises à jour pour toutes les versions de MySQL depuis Ubuntu 8.04.

Sur les 1.74 million de serveurs identifiés, Moore estime 50 % d'entre eux victimes d'une faille qu'il qualifie de « tragiquement comique ».

En effet, le fix ne requiert la modification que d'une seule ligne de code.


Sources :
post de Sergei Golubchik
post de HD Moor
bulletin de sécurité
Notice de sécurité d'Ubuntu

Et vous ?
Vos serveurs sont-ils vulnérables ?
Que pensez-vous de cette vulnérabilité ?


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse

Avatar de alex_vino alex_vino
http://www.developpez.com
Membre Expert
le 15/06/2012 10:08
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
Avatar de eti0123456789 eti0123456789
http://www.developpez.com
Membre du Club
le 15/06/2012 13:23
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 !
Avatar de alex_vino alex_vino
http://www.developpez.com
Membre Expert
le 15/06/2012 13:47
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.
Avatar de jeremya jeremya
http://www.developpez.com
Membre expérimenté
le 15/06/2012 22:44
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).
Avatar de BPiero BPiero
http://www.developpez.com
Membre confirmé
le 16/06/2012 18:31
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.
Avatar de pmithrandir pmithrandir
http://www.developpez.com
Expert Confirmé
le 18/06/2012 8:37
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
Avatar de gangsoleil gangsoleil
http://www.developpez.com
Modérateur
le 18/06/2012 10:47
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 :
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 :
00000000 01010101 11111111 00110011
Dans ce cas, la comparaison tronquee retourne 0, alors que la comparaison sur les 32 bits ne retourne pas 0.
Avatar de rt15 rt15
http://www.developpez.com
Membre éprouvé
le 18/06/2012 10:55
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 :
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 :
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.
Avatar de pmithrandir pmithrandir
http://www.developpez.com
Expert Confirmé
le 18/06/2012 11:38
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
Avatar de RaphAstronome RaphAstronome
http://www.developpez.com
Membre actif
le 18/06/2012 18:39
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.
Avatar de gangsoleil gangsoleil
http://www.developpez.com
Modérateur
le 19/06/2012 8:05
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
Offres d'emploi IT
Chargé d'études si h/f
CDI
DEXIA CREDIT LOCAL - Ile de France - Paris (75000)
Parue le 02/10/2014
ADMINISTRATEUR CITRIX (H/F)
CDI
MMA - Pays de la Loire - LE MANS (72000)
Parue le 30/09/2014
Moe ingénerie études et développement informatique h/f
CDI
Société Générale France - Ile de France - Paris (75000)
Parue le 20/10/2014

Voir plus d'offres Voir la carte des offres IT
 
 
 
 
Partenaires

PlanetHoster
Ikoula