Le monde de la cryptographie a été largement secoué lorsqu'on a annoncé que l'algorithme MD5 n'était pas sûr et que, moyennant de nouveaux algorithmes, on pouvait créer une collision en moins d'une journée.
Créer une collision, cela signifie pouvoir donc regénérer un mot de passe qui, encodé en MD5, donnera le même résultat et pourra donc être utilisé comme si c'était le vôtre. Le MD5 est utilisé par exemples dans de nombreux projets PHP pour cacher le mot de passe en cas de vulnérabilité, ce qui avait moyennement bien fonctionné jusque la.
Seulement, même si l'algorithme était publique, aucun code source n'était rendu public dans ce sens, ce que Patrick Stach vient de réaliser. Avec son source, un MD4 peut être cassé en quelques secondes et un MD5 en 45 minutes sur un P4 1.6Ghz.
On risque donc maintenant de voir débarquer de nouveaux supers virus, supers trojans ou autres exploits qui utiliseront cette technique pour, par exemple, trouver votre mot de passe sur un forum phpBB compromis.
Créer une collision, cela signifie pouvoir donc regénérer un mot de passe qui, encodé en MD5, donnera le même résultat et pourra donc être utilisé comme si c'était le vôtre. Le MD5 est utilisé par exemples dans de nombreux projets PHP pour cacher le mot de passe en cas de vulnérabilité, ce qui avait moyennement bien fonctionné jusque la.
Seulement, même si l'algorithme était publique, aucun code source n'était rendu public dans ce sens, ce que Patrick Stach vient de réaliser. Avec son source, un MD4 peut être cassé en quelques secondes et un MD5 en 45 minutes sur un P4 1.6Ghz.
On risque donc maintenant de voir débarquer de nouveaux supers virus, supers trojans ou autres exploits qui utiliseront cette technique pour, par exemple, trouver votre mot de passe sur un forum phpBB compromis.
Liens
Travail de Stach (440 Clics)
Code source pour le MD5 (432 Clics)
Code source pour le MD4 (322 Clics)
Plus d'actualités dans cette catégorie
Commentaires
apn:
La collision de MD5 en code source s'il vous plait
Par curiosité, j'ai testé ce fameux script (md5coll.c) et bien que je ne m'attendais pas au miracle des 45Minutes sur un P4 1.6GHz je dois malgré tout déclarer forfait après + de 2heures...
Pour info, j'ai lancé le script selon ces spécs:
CFLAGS: -O3 -march=nocona
NICE Level: -19
Procos: Bi-Xeon (pseudo-64bits donc ok pour la gestion des entiers en 32bits) 2.8GHz HT (4Proco virtuels même si qu'un seul utilisé par le script)
PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
47737 root 1 87 -19 2400K 720K CPU0 0 128:16 99.02% md5coll.bin
Je viens de le relancer via screen car mtnt dodo, on verra combien de temps il mettra
Pour info, j'ai lancé le script selon ces spécs:
CFLAGS: -O3 -march=nocona
NICE Level: -19
Procos: Bi-Xeon (pseudo-64bits donc ok pour la gestion des entiers en 32bits) 2.8GHz HT (4Proco virtuels même si qu'un seul utilisé par le script)
PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
47737 root 1 87 -19 2400K 720K CPU0 0 128:16 99.02% md5coll.bin
Je viens de le relancer via screen car mtnt dodo, on verra combien de temps il mettra
zion:
La collision de MD5 en code source s'il vous plait
T'es courageux dis donc, sur tous les commentaires que j'ai lu sur Slashdot, il n'y en a qu'un qui a lu le code mais aucun qui a essayé de le faire fonctionner jusque la, et je dois dire que moi non plus
apn:
La collision de MD5 en code source s'il vous plait
Bon finallement j'ai pu attendre la fin du traitement, bingo en 1h50 sur la même machine, j'ai du avoir plus de chance ce coup-ci avec random():
#ll md5coll.log
-rw-r--r-- 1 root wheel 868 Nov 17 02:36 md5coll.log
apn@bep-pc1|108#cat md5coll.log
block #1 done
block #2 done
unsigned int m0[32] = {
0x6ca39a0a, 0x0b49ac46, 0x6a1b6742, 0xaeabf3fe,
0xcd3b0462, 0x82ffcb54, 0xe43b104d, 0x862307b6,
0x06352d55, 0xe4738c0a, 0x8d93003b, 0x14e10332,
0x362468e9, 0x8138d5b1, 0x705dbbed, 0x7be8d9d7,
0xb4cfaea6, 0x4e1fb981, 0x0a919194, 0xe54b9263,
0xb5a68ecf, 0xfd462a97, 0x75b1f942, 0xdf8d4bd2,
0x327bc6e5, 0x4c5f6fb7, 0x334f976a, 0x6551d053,
0xab86fcd4, 0x55c79950, 0x27c0fcbe, 0xfb1a6516,
};
unsigned int m1[32] = {
0x6ca39a0a, 0x0b49ac46, 0x6a1b6742, 0xaeabf3fe,
0x4d3b0462, 0x82ffcb54, 0xe43b104d, 0x862307b6,
0x06352d55, 0xe4738c0a, 0x8d93003b, 0x14e18332,
0x362468e9, 0x8138d5b1, 0xf05dbbed, 0x7be8d9d7,
0xb4cfaea6, 0x4e1fb981, 0x0a919194, 0xe54b9263,
0x35a68ecf, 0xfd462a97, 0x75b1f942, 0xdf8d4bd2,
0x327bc6e5, 0x4c5f6fb7, 0x334f976a, 0x65515053,
0xab86fcd4, 0x55c79950, 0xa7c0fcbe, 0xfb1a6516,
};
Mais je vois pas trop comment utiliser ces données hexa pour trouver le mot de passe qui a généré la collision, faudra pe un peu lire le code tout de même :s
#ll md5coll.log
-rw-r--r-- 1 root wheel 868 Nov 17 02:36 md5coll.log
apn@bep-pc1|108#cat md5coll.log
block #1 done
block #2 done
unsigned int m0[32] = {
0x6ca39a0a, 0x0b49ac46, 0x6a1b6742, 0xaeabf3fe,
0xcd3b0462, 0x82ffcb54, 0xe43b104d, 0x862307b6,
0x06352d55, 0xe4738c0a, 0x8d93003b, 0x14e10332,
0x362468e9, 0x8138d5b1, 0x705dbbed, 0x7be8d9d7,
0xb4cfaea6, 0x4e1fb981, 0x0a919194, 0xe54b9263,
0xb5a68ecf, 0xfd462a97, 0x75b1f942, 0xdf8d4bd2,
0x327bc6e5, 0x4c5f6fb7, 0x334f976a, 0x6551d053,
0xab86fcd4, 0x55c79950, 0x27c0fcbe, 0xfb1a6516,
};
unsigned int m1[32] = {
0x6ca39a0a, 0x0b49ac46, 0x6a1b6742, 0xaeabf3fe,
0x4d3b0462, 0x82ffcb54, 0xe43b104d, 0x862307b6,
0x06352d55, 0xe4738c0a, 0x8d93003b, 0x14e18332,
0x362468e9, 0x8138d5b1, 0xf05dbbed, 0x7be8d9d7,
0xb4cfaea6, 0x4e1fb981, 0x0a919194, 0xe54b9263,
0x35a68ecf, 0xfd462a97, 0x75b1f942, 0xdf8d4bd2,
0x327bc6e5, 0x4c5f6fb7, 0x334f976a, 0x65515053,
0xab86fcd4, 0x55c79950, 0xa7c0fcbe, 0xfb1a6516,
};
Mais je vois pas trop comment utiliser ces données hexa pour trouver le mot de passe qui a généré la collision, faudra pe un peu lire le code tout de même :s
rfr:
La collision de MD5 en code source s'il vous plait
Le source windows ne marche pas chez moi, si vous essayez et que vous avez un problème, changez la fonction initRandom par celle-ci:
int initRandom(void)
{
#ifdef _MSC_VER
if (!CryptAcquireContext(&cryptHandle, "Container", NULL, PROV_RSA_FULL, 0))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&cryptHandle, "Container", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
char buf[100];
StringCbPrintf(buf, sizeof(buf), "error getting crypto context: 0x%x", GetLastError());
MessageBox(0, buf, "error", MB_ICONERROR|MB_OK);
return 0;
}
}
}
// Or, acquire Context of container that is shared across the machine.
if (!CryptAcquireContext(&cryptHandle, "Container", NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&cryptHandle, "Container", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET))
{
char buf[100];
StringCbPrintf(buf, sizeof(buf), "error getting crypto context: 0x%x", GetLastError());
MessageBox(0, buf, "error", MB_ICONERROR|MB_OK);
return 0;
}
}
}
/*
if(!CryptAcquireContext(&cryptHandle, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET ))
{
char buf[100];
StringCbPrintf(buf, sizeof(buf), "error getting crypto context: 0x%x", GetLastError());
MessageBox(0, buf, "error", MB_ICONERROR|MB_OK);
return 0;
}
*/
#else
srandom(time(NULL) ^ (getpid() << 16));
#endif
return 1;
}
C'est ma petite contribution au projet
int initRandom(void)
{
#ifdef _MSC_VER
if (!CryptAcquireContext(&cryptHandle, "Container", NULL, PROV_RSA_FULL, 0))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&cryptHandle, "Container", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
char buf[100];
StringCbPrintf(buf, sizeof(buf), "error getting crypto context: 0x%x", GetLastError());
MessageBox(0, buf, "error", MB_ICONERROR|MB_OK);
return 0;
}
}
}
// Or, acquire Context of container that is shared across the machine.
if (!CryptAcquireContext(&cryptHandle, "Container", NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&cryptHandle, "Container", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET))
{
char buf[100];
StringCbPrintf(buf, sizeof(buf), "error getting crypto context: 0x%x", GetLastError());
MessageBox(0, buf, "error", MB_ICONERROR|MB_OK);
return 0;
}
}
}
/*
if(!CryptAcquireContext(&cryptHandle, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET ))
{
char buf[100];
StringCbPrintf(buf, sizeof(buf), "error getting crypto context: 0x%x", GetLastError());
MessageBox(0, buf, "error", MB_ICONERROR|MB_OK);
return 0;
}
*/
#else
srandom(time(NULL) ^ (getpid() << 16));
#endif
return 1;
}
C'est ma petite contribution au projet
thorgull:
La collision de MD5 en code source s'il vous plait
Ben il était temps, les gens vont p'tet enfin ce décider à utiliser d'autres algo. J'ose pas imaginer ce que l'on pourrait faire avec un fichier /etc/shadow mal protégé...
Il faut aussi noter qu'il n'y a pas que le problème des mots de passe. On utilise souvent le MD5 pour "signer" un fichier (car c plus rapide). "Si le md5 est le même c'est que le fichier n'est pas altéré ...", ... ben maintenant on sais que c'est plus vrai. Va faloir trouver autre chose ... on va rentrer dans l'aire du SHA ... ou du ou bien ils vont nous sortir un MD6
Il faut aussi noter qu'il n'y a pas que le problème des mots de passe. On utilise souvent le MD5 pour "signer" un fichier (car c plus rapide). "Si le md5 est le même c'est que le fichier n'est pas altéré ...", ... ben maintenant on sais que c'est plus vrai. Va faloir trouver autre chose ... on va rentrer dans l'aire du SHA ... ou du ou bien ils vont nous sortir un MD6
rfr:
La collision de MD5 en code source s'il vous plait
SHA-1 est déjà dans le colimateur et n'est plus recommandé ... note qu'IE 6.0 ne supporte toujours pas les certificats signé en utilisant "sha256WithRSA"
zion:
La collision de MD5 en code source s'il vous plait
MD5 était aussi utilisé sur les photos des radars automatiques en Australie pour en certifier l'authenticité... mais du coup les infractions ont été contestées
Ppxl:
La collision de MD5 en code source s'il vous plait
En france ils ont trouvé mieux avec les radars que un script :
- repeindre le radar
- lui tirer dessus à la chevrotine comme une cible
- le fracturer au marteau (au niveau des vitres)
- l'arracher à la peleteuse
...
Allez, allez, il en reste encore
- repeindre le radar
- lui tirer dessus à la chevrotine comme une cible
- le fracturer au marteau (au niveau des vitres)
- l'arracher à la peleteuse
...
Allez, allez, il en reste encore
cauet:
La collision de MD5 en code source s'il vous plait
C'est bien, vive la france