|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
BRUTEFORCING D'UN CHECKSUM MD5
Description
Bon alor l'histoire commence ici : http://www.phpcs.com/code.aspx?ID=19322 J'ai pas testé le script, mais l'idée m'intéressait de savoir qu'elle est le puissance nécéssaire pour trouver un mot de passe valide sur mon site, et en combien de temps. J'ai donc codé ça en C (LccWin32, m'enfin ça devrait tourner sur n'importe quel autre compilo sans trop de problèmes) en vitesse, le code est vraiment cochon (j'ai même repris 3 fonctions venant de BCX, et j'ai une tonne d'includes qui servent a rien, je sais, mais j'ai commenté comme j'ai pu pour le rendre compréhenssible), j'ai pas vraiment optimisé et ça me donne quand même dans les 10000 'mot de passes' testé par seconde, avec mon simple athlon 1.3 Ghz (sans compter toutes les taches de fond qui me pompe le CPU) ! J'ai donc essayer de 'décrypter' l'exemple de mavounet (aa36dc6e81e2ac7ad03e12fedcb6a2c0=mdp), et comme vous le voyez sur la capture il met que 6s !!! Bon d'acord après ça se complique si on passe au dessus de 3 caractères, et c'est considérablement ralenti, et ça devient quasi-impossible. Conclusion: N'utilisez QUE des mots de passes complexes contenants un bon nombre de caractères, et le mieux seraient encore d'éviter de rendre public la liste des md5 !
Source
- #include <windows.h>
- #include <stdio.h>
- #include "md5.h" //Le fichier magique qui permet d'encoder en md5
-
-
- // *************************************************
- // System Variables
- // *************************************************
-
- COORD cursor;
- HANDLE hConsole;
- int color_fg = 7;
- int color_bg = 0;
-
-
- // *************************************************
- // Standard Prototypes
- // *************************************************
-
- void cls(void);
- void color (int,int);
- void locate (int,int,int=1,int=12);
-
- // *************************************************
- // Main Program
- // *************************************************
-
- DWORD BrutesMade=0;
- DWORD NumberFounds=0;
- BOOL Tourne=TRUE;
- md5_byte_t buffer[1024];
- DWORD nForceChars=0;
- md5_byte_t searched[16];
-
-
- /* ChangeLog
- -les déclarations des variables pour calculer le md5 sont déclarés AVANT la boucle et plus pendant
- -j'ai changé le char par un WORD (le int était pas une mauvaise idée, mais j'ai l'impression que c'est un peu plus lent chez moi)
- -suprimé la conversion du md5 format brut vers le format héxa, et je compare le digest lui même (sans oublier de convertir avant le md5 que l'on recherche en format brut), mainteant sur mon pc ça tourne a 600000/s au lieu de 10000, 60x plus rapide !!!
- -supression de la récusivité qui se fesait quand même bien sentir, merci à ccarniel
- -adaptation a VC++ : plus grand rapidité que avec Lcc, mais mauvaise portabilité (il se trouv que le même exe, compilé sur une machine tourne moins bien sur une autre machine plus puissante !!!)
- -et amélioration de la fonction de monitoring qui est maintenant plus précise (encore merci a ccarniel)
- */
-
-
- void brute_force(DWORD max, md5_byte_t searched[16]) {
- char md5buf[33];
- DWORD maxm1=max-1;
- unsigned char ChiffreDebut = ' ', ChiffreFin = 254;
- int Curseur;
- bool Termine = false;
- md5_state_t state;
- md5_byte_t digest[16];
-
- // Combinaison = new unsigned char[max+1];
- memset(buffer, ChiffreDebut, (sizeof(char))*max);
- while (!Termine) {
- BrutesMade++; //On ajoute 1 au compteur de 'pass' testés
-
- //On fait un checksum md5 sur le buffer
- md5_init(&state);
- md5_append(&state, (const md5_byte_t*)buffer, max);
- md5_finish(&state, digest);
-
- if (!memcmp(digest, searched, 16)) { //memcmp est bcp plus rapide que strcmp, mais ne fait pas de comparaisons entre les minusucules et les majusucules, attention a ça quand vous mettez votre md5 a 'décrypter' !
- locate(++NumberFounds, 29); //Si trouvé, on place le curseur a droite dans la console
- for (int di = 0; di < 16; ++di) sprintf(md5buf + di * 2, "%02x", digest[di]); //Ok c'est pas le plus puissant mais on s'en fout, on le fait qu'une seule fois
- printf(": md5('%s')='%s'\n", buffer, md5buf); //On affiche le md5 et le pass qui correspond (c'est vrai il y a des chances de pas trouver le vrai mot de passe, mais on s'en fout, si on entre ça l'ordi va le comprendre comme le vrai mot de passe !!!)
-
- Tourne=FALSE; //On arrête le thread de monitoring
- ExitProcess(0); //Et on quite
- }
-
- Curseur = 0;
- if (buffer[Curseur]>ChiffreFin) {
- do {
- buffer[++Curseur]++;
- if (Curseur == max) return ; // On a pas trouvé la combinaison
- } while (buffer[Curseur]>ChiffreFin);
- memset(buffer, ChiffreDebut, Curseur);
- }
- }
- }
-
- //Un ptit thread pour savoir où en est le prog parce que sinon on se fait un peu chier lol
- void ThreadMonitor(void) {
- DWORD LastBrutes=0, Secs=0;
- #if defined (_MSC_VER) && (_MSC_VER >= 1020)
- __int64 Freq,StartTime,CurTime;
- #else
- unsigned long StartTime,CurTime;
- #endif // defined (_MSC_VER) && (_MSC_VER >= 1020)
-
- #if defined (_MSC_VER) && (_MSC_VER >= 1020)
- QueryPerformanceFrequency((LARGE_INTEGER*)&Freq);
- QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);
- #else
- StartTime = GetTickCount();
- #endif // defined (_MSC_VER) && (_MSC_VER >= 1020)
-
- do {
- //Secs = GetTickCount() - Start;
- #if defined (_MSC_VER) && (_MSC_VER >= 1020)
- QueryPerformanceCounter((LARGE_INTEGER*)&CurTime);
- Secs = (CurTime - StartTime)*1000/Freq;
- #else
- CurTime = GetTickCount();
- Secs = (CurTime - StartTime);
- #endif // defined (_MSC_VER) && (_MSC_VER >= 1020)
- if( Secs >= 1000 ) {
- cls(); //On efface l'écran et on met le curseur en haut a gauche. Ok j'avoue la fonction vient tout droit de BCX j'ai pas eu le courage d'aller mieux chercher et g pri le premier truc qui m'est tombé sous la main
- printf("%d décryptés.\n",BrutesMade);
- printf("%d/s (%ds écoulée(s)) \n",BrutesMade/(Secs/1000),(Secs/1000));
- printf("Le mot de passe a au moins %d chars.\n\n== %s ==\n\n\n", nForceChars, buffer); //On affiche les stats
- LastBrutes=BrutesMade; //9a c'est pour le compteur de pass par secondes
- }
- Sleep(1000); //On attenton une seconde
- } while (Tourne==TRUE); //Une boucle jusqu'a se que un pass correct soit trouvé
- }
-
- int main(int argc, char *argv[]) {
- hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
-
- // "aa36dc6e81e2ac7ad03e12fedcb6a2c0" = mdp
- // "1eec414adf814acbc887f59327db58fb" = ?
- // "02c425157ecd32f259548b33402ff6d3" = zzzz
- // "95ebc3c7b3b9f1d2c40fec14415d3cb8" = zzzzz
-
- char * md5s="02c425157ecd32f259548b33402ff6d3";
- char cbit[3];
- cbit[2]='\0';
- for (int i=0; i<32; i+=2) {
- memcpy(cbit, md5s+i, 2);
- searched[i/2]=strtol(cbit, NULL, 16);
- }
-
- DWORD MaxSize=16; //Le nb maximum de caractères que le pass peut faire
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMonitor, NULL, 0, NULL); //On démarre le monitoring en tant que thread seconde ==> comme ça, ça ralenti a peine le scanning, et c'est plus simple pour les fénéants^^
- for (nForceChars=1; nForceChars<=MaxSize; nForceChars++) {
- ZeroMemory(buffer, MaxSize+1); //On efface le buffer pour plus de sécurité
- brute_force(nForceChars, searched); //Et on brute force ça
- }
- return 0;
- }
-
- // *************************************************
- // Run Time Functions
- // *************************************************
-
- void locate (int row,int col,int show,int shape)
- {
- CONSOLE_CURSOR_INFO cci = {0};
- cursor.X = col-1;
- cursor.Y = row-1;
- SetConsoleCursorPosition(hConsole,cursor);
- cci.bVisible = show;
- cci.dwSize = shape;
- SetConsoleCursorInfo(hConsole,&cci);
- }
-
-
- void cls (void)
- {
- COORD coordScreen = {0,0};
- DWORD cCharsWritten;
- CONSOLE_SCREEN_BUFFER_INFO csbi = {0};
- DWORD dwConSize;
- register int attr;
- cursor.X = 0;
- cursor.Y = 0;
- GetConsoleScreenBufferInfo( hConsole, &csbi );
- dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
- FillConsoleOutputCharacter (hConsole, 32, dwConSize,coordScreen, &cCharsWritten);
- attr = color_fg + color_bg * 16;
- FillConsoleOutputAttribute (hConsole, attr, dwConSize,coordScreen, &cCharsWritten);
- locate(1,1,1);
- }
-
-
- void color (int fg, int bg)
- {
- SetConsoleTextAttribute (hConsole,fg+bg*16);
- color_fg = fg;
- color_bg = bg;
- }
-
-
#include <windows.h>
#include <stdio.h>
#include "md5.h" //Le fichier magique qui permet d'encoder en md5
// *************************************************
// System Variables
// *************************************************
COORD cursor;
HANDLE hConsole;
int color_fg = 7;
int color_bg = 0;
// *************************************************
// Standard Prototypes
// *************************************************
void cls(void);
void color (int,int);
void locate (int,int,int=1,int=12);
// *************************************************
// Main Program
// *************************************************
DWORD BrutesMade=0;
DWORD NumberFounds=0;
BOOL Tourne=TRUE;
md5_byte_t buffer[1024];
DWORD nForceChars=0;
md5_byte_t searched[16];
/* ChangeLog
-les déclarations des variables pour calculer le md5 sont déclarés AVANT la boucle et plus pendant
-j'ai changé le char par un WORD (le int était pas une mauvaise idée, mais j'ai l'impression que c'est un peu plus lent chez moi)
-suprimé la conversion du md5 format brut vers le format héxa, et je compare le digest lui même (sans oublier de convertir avant le md5 que l'on recherche en format brut), mainteant sur mon pc ça tourne a 600000/s au lieu de 10000, 60x plus rapide !!!
-supression de la récusivité qui se fesait quand même bien sentir, merci à ccarniel
-adaptation a VC++ : plus grand rapidité que avec Lcc, mais mauvaise portabilité (il se trouv que le même exe, compilé sur une machine tourne moins bien sur une autre machine plus puissante !!!)
-et amélioration de la fonction de monitoring qui est maintenant plus précise (encore merci a ccarniel)
*/
void brute_force(DWORD max, md5_byte_t searched[16]) {
char md5buf[33];
DWORD maxm1=max-1;
unsigned char ChiffreDebut = ' ', ChiffreFin = 254;
int Curseur;
bool Termine = false;
md5_state_t state;
md5_byte_t digest[16];
// Combinaison = new unsigned char[max+1];
memset(buffer, ChiffreDebut, (sizeof(char))*max);
while (!Termine) {
BrutesMade++; //On ajoute 1 au compteur de 'pass' testés
//On fait un checksum md5 sur le buffer
md5_init(&state);
md5_append(&state, (const md5_byte_t*)buffer, max);
md5_finish(&state, digest);
if (!memcmp(digest, searched, 16)) { //memcmp est bcp plus rapide que strcmp, mais ne fait pas de comparaisons entre les minusucules et les majusucules, attention a ça quand vous mettez votre md5 a 'décrypter' !
locate(++NumberFounds, 29); //Si trouvé, on place le curseur a droite dans la console
for (int di = 0; di < 16; ++di) sprintf(md5buf + di * 2, "%02x", digest[di]); //Ok c'est pas le plus puissant mais on s'en fout, on le fait qu'une seule fois
printf(": md5('%s')='%s'\n", buffer, md5buf); //On affiche le md5 et le pass qui correspond (c'est vrai il y a des chances de pas trouver le vrai mot de passe, mais on s'en fout, si on entre ça l'ordi va le comprendre comme le vrai mot de passe !!!)
Tourne=FALSE; //On arrête le thread de monitoring
ExitProcess(0); //Et on quite
}
Curseur = 0;
if (buffer[Curseur]>ChiffreFin) {
do {
buffer[++Curseur]++;
if (Curseur == max) return ; // On a pas trouvé la combinaison
} while (buffer[Curseur]>ChiffreFin);
memset(buffer, ChiffreDebut, Curseur);
}
}
}
//Un ptit thread pour savoir où en est le prog parce que sinon on se fait un peu chier lol
void ThreadMonitor(void) {
DWORD LastBrutes=0, Secs=0;
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
__int64 Freq,StartTime,CurTime;
#else
unsigned long StartTime,CurTime;
#endif // defined (_MSC_VER) && (_MSC_VER >= 1020)
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
QueryPerformanceFrequency((LARGE_INTEGER*)&Freq);
QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);
#else
StartTime = GetTickCount();
#endif // defined (_MSC_VER) && (_MSC_VER >= 1020)
do {
//Secs = GetTickCount() - Start;
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
QueryPerformanceCounter((LARGE_INTEGER*)&CurTime);
Secs = (CurTime - StartTime)*1000/Freq;
#else
CurTime = GetTickCount();
Secs = (CurTime - StartTime);
#endif // defined (_MSC_VER) && (_MSC_VER >= 1020)
if( Secs >= 1000 ) {
cls(); //On efface l'écran et on met le curseur en haut a gauche. Ok j'avoue la fonction vient tout droit de BCX j'ai pas eu le courage d'aller mieux chercher et g pri le premier truc qui m'est tombé sous la main
printf("%d décryptés.\n",BrutesMade);
printf("%d/s (%ds écoulée(s)) \n",BrutesMade/(Secs/1000),(Secs/1000));
printf("Le mot de passe a au moins %d chars.\n\n== %s ==\n\n\n", nForceChars, buffer); //On affiche les stats
LastBrutes=BrutesMade; //9a c'est pour le compteur de pass par secondes
}
Sleep(1000); //On attenton une seconde
} while (Tourne==TRUE); //Une boucle jusqu'a se que un pass correct soit trouvé
}
int main(int argc, char *argv[]) {
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// "aa36dc6e81e2ac7ad03e12fedcb6a2c0" = mdp
// "1eec414adf814acbc887f59327db58fb" = ?
// "02c425157ecd32f259548b33402ff6d3" = zzzz
// "95ebc3c7b3b9f1d2c40fec14415d3cb8" = zzzzz
char * md5s="02c425157ecd32f259548b33402ff6d3";
char cbit[3];
cbit[2]='\0';
for (int i=0; i<32; i+=2) {
memcpy(cbit, md5s+i, 2);
searched[i/2]=strtol(cbit, NULL, 16);
}
DWORD MaxSize=16; //Le nb maximum de caractères que le pass peut faire
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadMonitor, NULL, 0, NULL); //On démarre le monitoring en tant que thread seconde ==> comme ça, ça ralenti a peine le scanning, et c'est plus simple pour les fénéants^^
for (nForceChars=1; nForceChars<=MaxSize; nForceChars++) {
ZeroMemory(buffer, MaxSize+1); //On efface le buffer pour plus de sécurité
brute_force(nForceChars, searched); //Et on brute force ça
}
return 0;
}
// *************************************************
// Run Time Functions
// *************************************************
void locate (int row,int col,int show,int shape)
{
CONSOLE_CURSOR_INFO cci = {0};
cursor.X = col-1;
cursor.Y = row-1;
SetConsoleCursorPosition(hConsole,cursor);
cci.bVisible = show;
cci.dwSize = shape;
SetConsoleCursorInfo(hConsole,&cci);
}
void cls (void)
{
COORD coordScreen = {0,0};
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi = {0};
DWORD dwConSize;
register int attr;
cursor.X = 0;
cursor.Y = 0;
GetConsoleScreenBufferInfo( hConsole, &csbi );
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter (hConsole, 32, dwConSize,coordScreen, &cCharsWritten);
attr = color_fg + color_bg * 16;
FillConsoleOutputAttribute (hConsole, attr, dwConSize,coordScreen, &cCharsWritten);
locate(1,1,1);
}
void color (int fg, int bg)
{
SetConsoleTextAttribute (hConsole,fg+bg*16);
color_fg = fg;
color_bg = bg;
}
Conclusion
A oui et pour ceux qui connaissent pas, le md5 s'est une sorte de cryptage a sens unique, on peut pas décrypter, il fait 16 octects (ben oui 16 au lieu de 32, nous on en voit la version 'humaine' qui est décodée en héxadécimal) Un octect=256 combinaisons. 16 octets=256^16 combinaisons, soit environ 3.4 puissance 38 combinaisons possibles, ou même d'après PowerCalc exactement 340282366920938463463374607431768211456... Donc autant dire que c'est quasi impossible de tomber dessus par hasard ! Le md5 est utilisé par exemple par la plus part des logiciels peer2peer pour reconnaitre un fichier vu qu'il est statistiquement impossible que deux fichiers aient le même md5. Et il est aussi utilisé dans les site webs, quand vous entrez votre mot de passe il est tout de suite crypté en md5, et gardé sous cette forme dans la base de données, comme ça le webmaster où même un pirate ne peux avoir votre mot de passe, mais juste sa version cryptée en md5. (Sa évite les piratages quand sur tous les même sites vous mettez le même mot de passe, compte mail inclu...) Des commentaires seraient les bien venus si vous avez de meilleures idées que moi pour trouver un mot de passe valide.
Fichier Zip
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
Télécharger le zip
Historique
- 07 août 2004 21:26:16 :
- 07 août 2004 22:26:38 :
- 08 août 2004 18:46:28 :
Sources de la même categorie
Sources en rapport avec celle ci
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
md5 etc.... [ par xlsd ]
Salut, est il possible (oui forcement) d'utiliser md5 en C/C++ je n'arrive pas a trouvé les fonctions etc..merci :)
Cryptage par l'algorithme MD5 [ par LSRS ]
[red]Salut tout le monde!!!J'ai un problème avec l'algorithme MD5 de RSA... je voudrais bien comprendre le mécanisme avec lequel il travaille...En plu
Le cryptage par MD5 de RSA [ par LSRS ]
Salut tout le monde...J'ai un très grand problème avec l'algorithme de hachage MD5 qui réprésente le squelette de mon stage d'été... Je n'arrive pas à
utilisation du fichier md5.h [ par flatmax ]
salut a tousje viens de recuperer les fichiers md5.h, md5.cpp, et j'aimerais savoir comment m'en servir pour obtenir le hash md5 d'un mot.quels foncti
cryptage md5 [ par laflef ]
salut je cherche le code source de l'algorithme de cryptage md5 base sur le hachage inversible
RAW SOCKET - IP - Sendto() - Erreur 'WSAEADDRNOTAVAIL' [ par dark1933 ]
Salut à tous,J'essaye désespérément d'envoyer un Ping en forgeant le datagramme IP adéquat.J'obtiens l'erreur "WSAEADDRNOTAVAIL" au moment de l'appel
md5 [ par coockiesch ]
Hello!!!Je cherche une fonction qui produise le meme cryptage que la fonction md5 de PHP. C'est possible???Merci@++Raf"On dit que seulement 10 personn
pb avec communication rs232 [ par kekenobi ]
salut a tous et a toutes!voila j'ai un petit pb avec mon programme portant sur la communication RS232:en fait je reçoit une trame de 19 caractères et
recvfrom et checksum [ par nyarzduk ]
Bonjour,juste une petite question, est-ce-que la fonction recvfrom() réalise un contrôle sur la trame reçue (checksum) et si oui quel est le code d'er
Faire marcher CryptAcquireContext [ par Nebula ]
Bonsoir à tous !J'essaie actuellement d'utiliser les fonctions de cryptographie de Windows (ce qui m'intéresse est le calcul de hash MD5 ou SHA, pour
|
Téléchargements
Logiciels à télécharger sur le même thème :
Comparez les prix Nouvelle version
|