I am trying to develope a small brute force application in C. As operating system I use Ubuntu 14.04. My CPU is an Intel Core [email protected](stock).
My question is, how can I use MD5_Init, MD5_Update and MD5_Final with openmp without strange cautious during runtime?
For example my main()-function looks like the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#include <openssl/md5.h>
#include <time.h>
const char LiteralsLower[] = "abcdefghijklmnopqrstuvwxyz";
const int NLiteralsLower = sizeof( LiteralsLower ) - 1;
char HexByteHash[16];
time_t StartTime, EndTime;
/* Prototypes */
static void MD5Hash( const char * );
static void BruteForce( const int * restrict, const int * restrict, const char *, const int *, int );
int main()
{
const char HashAsString[] = "172522ec1028ab781d9dfd17eaca4427"; // 'david'
const int *BFOptionSize = &NLiteralsLower;
const char *BFOption = LiteralsLower;
int PasswordLength = 6;
int StrLength = strlen( HashAsString );
for( int i = 0; i < StrLength / 2 ; i++ )
{
if( !sscanf( HashAsString + 2 * i, "%02x", ( unsigned int * ) &HexByteHash[i] ) )
{
fprintf( stderr, "FEHLER!!! -> '%s' ist kein Hash-Wert!\n", HashAsString );
exit( EXIT_FAILURE );
}
}
fprintf( stdout, "Hash: %s mit einer Länge von %li Zeichen.\n", HashAsString, strlen( HashAsString ) / 2 );
/* Timer starten */
time( &StartTime );
#pragma omp parallel shared( PasswordLength, BFOptionSize )
for( int PWLength = 0; PWLength < PasswordLength + 1; ++PWLength )
{
/* Array-Größe für FstEntry und LstEntry festlegen */
int FstEntry[PWLength], LstEntry[PWLength];
/* Array-Felder mit 0 initialisieren */
for( int j = 0; j < PWLength; ++j )
FstEntry[j] = LstEntry[j] = 0;
#pragma omp for schedule( dynamic )
for( int i = 0; i < *BFOptionSize; ++i )
{
FstEntry[0] = i;
LstEntry[0] = i + 1;
BruteForce( FstEntry, LstEntry, BFOption, BFOptionSize, PWLength );
}
}
/* Timer stoppen */
time( &EndTime );
puts( "!!! Wort nicht gefunden !!!" );
printf( "Elapsed time: %ld minutes %ld seconds\n\n", ( EndTime - StartTime ) / 60, ( EndTime - StartTime ) % 60 );
return EXIT_FAILURE;
}
I'm not sure but I think that until here everything is okay.
The next code is my bruteforce-function:
static void BruteForce( const int * restrict FirstEntry, const int * restrict LastEntry, const char *Letters, const int *NLetters, int PSSWDLength )
{
char Password[PSSWDLength];
int Entry[PSSWDLength + 1];
int i, j;
/* Null-Byte hinzufügen */
memset( Entry, '\0', PSSWDLength );
memset( Password, '\0', PSSWDLength );
/* FirstEntry in Entry kopieren */
for( i = 0; i < PSSWDLength; ++i )
Entry[i] = FirstEntry[i];
i = 0;
while( i < PSSWDLength )
{
/* Generiere Passwort für Hash-Vergleich */
for( i = 0; i < PSSWDLength; ++i )
Password[i] = Letters[Entry[i]];
/* generiertes Wort hashen */
MD5Hash( Password );
/* Entry inkrementieren */
for( i = 0; i < PSSWDLength && ++Entry[PSSWDLength-i-1] == *NLetters; i++ )
Entry[PSSWDLength-i-1] = 0;
/* Return wenn Entry != LastEntry raus aus der Schleife */
for( j = 0; j < PSSWDLength; ++j )
if( Entry[j] != LastEntry[j] )
break;
/* wenn Entry == LastEntry Funktion verlassen */
if( j == PSSWDLength )
return;
}
}
At least my hash-function:
static void MD5Hash( const char *PasswordStringPointer )
{
unsigned char Digest[16];
/* MD5-Hash erzeugen */
MD5_CTX md5;
MD5_Init( &md5 );
MD5_Update( &md5, PasswordStringPointer, strlen( PasswordStringPointer ) );
MD5_Final( Digest, &md5 );
if( memcmp( HexByteHash, Digest, 16 ) == 0 )
{
printf( "!!! Wort gefunden: '%s' !!!\n", PasswordStringPointer );
/* Timer stoppen */
time( &EndTime );
printf( "Elapsed time: %ld minutes %ld seconds\n\n", ( EndTime - StartTime ) / 60, ( EndTime - StartTime ) % 60 );
/* Passwortsuche war erfolgreich */
exit( EXIT_SUCCESS);
}
}
The problem is that when I use all of my eight cores, sometimes if I start the application, it doesn't find the word that is to be search. For example: 172522ec1028ab781d9dfd17eaca4427 <-- 'david' <-- the word to search For example I say the max. length of the words to generate is 6. So normaly when I start the application I should have this output:
Hash: 172522ec1028ab781d9dfd17eaca4427 mit einer Länge von 16 Zeichen.
!!! Wort gefunden: 'david' !!!
Elapsed time: 0 minutes 1 seconds
But sometimes it can happens that I have this output instead:
Hash: 172522ec1028ab781d9dfd17eaca4427 mit einer Länge von 16 Zeichen.
!!! Wort nicht gefunden !!!
Elapsed time: 0 minutes 14 seconds
That means that for what reason ever, it doesn't generate the right hash. So the application runs until 'zzzzzz' was generated. I cannot understand why.
I am not professional in openmp , but with printing some debugging information, I find that the generated passwords don't have '\0' at the end, they contain characters like: abrv▒♣▒, to solve this, just add Password[PSSWDLength] = '\0'; in line 105.
to compile use : gcc my_md5.c -o my_md5 -fopenmp -lcrypto
OS windows 7 using Cygwin.
by replacing restrict with __restrict
using password azor instead of david
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#include <openssl/md5.h>
#include <time.h>
const char LiteralsLower[] = "abcdefghijklmnopqrstuvwxyz";
const int NLiteralsLower = sizeof( LiteralsLower ) - 1;
char HexByteHash[16];
time_t StartTime, EndTime;
/* Prototypes */
static void MD5Hash( const char * );
static void BruteForce( const int * __restrict , const int * __restrict , const char *, const int *, int );
int omp_get_num_threads(void);
int main()
{
//const char HashAsString[] = "172522ec1028ab781d9dfd17eaca4427"; // 'david'
const char HashAsString[] = "f68d28e078cc6aa6c163f787da7572eb"; // 'azor'
const int *BFOptionSize = &NLiteralsLower;
const char *BFOption = LiteralsLower;
int PasswordLength = 6;
int StrLength = strlen( HashAsString );
int i;
for(i = 0; i < StrLength / 2 ; i++ )
{
if( !sscanf( HashAsString + 2 * i, "%02x", ( unsigned int * ) &HexByteHash[i] ) )
{
fprintf( stderr, "FEHLER!!! -> '%s' ist kein Hash-Wert!\n", HashAsString );
exit( EXIT_FAILURE );
}
}
fprintf( stdout, "Hash: %s mit einer L?nge von %li Zeichen.\n", HashAsString, strlen( HashAsString ) / 2 );
/* Timer starten */
time( &StartTime );
int PWLength;
#pragma omp parallel shared( PasswordLength, BFOptionSize )
{
for(PWLength = 0; PWLength < PasswordLength + 1; ++PWLength )
{
int nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
/* Array-Gr??e für FstEntry und LstEntry festlegen */
int FstEntry[PWLength], LstEntry[PWLength];
/* Array-Felder mit 0 initialisieren */
int j ;
for( j= 0; j < PWLength; ++j )
FstEntry[j] = LstEntry[j] = 0;
int i ;
#pragma omp for schedule( dynamic )
for( i= 0; i < *BFOptionSize; ++i )
{
FstEntry[0] = i;
LstEntry[0] = i + 1;
BruteForce( FstEntry, LstEntry, BFOption, BFOptionSize, PWLength );
}
}
}
/* Timer stoppen */
time( &EndTime );
puts( "!!! Wort nicht gefunden !!!" );
printf( "Elapsed time: %ld minutes %ld seconds\n\n", ( EndTime - StartTime ) / 60, ( EndTime - StartTime ) % 60 );
return EXIT_FAILURE;
}
static void BruteForce( const int * __restrict FirstEntry, const int * __restrict LastEntry, const char *Letters, const int *NLetters, int PSSWDLength )
{
char Password[PSSWDLength];
int Entry[PSSWDLength + 1];
int i, j;
/* Null-Byte hinzufügen */
memset( Entry, '\0', PSSWDLength );
memset( Password, '\0', PSSWDLength );
/* FirstEntry in Entry kopieren */
for( i = 0; i < PSSWDLength; ++i )
Entry[i] = FirstEntry[i];
i = 0;
while( i < PSSWDLength )
{
/* Generiere Passwort für Hash-Vergleich */
for( i = 0; i < PSSWDLength; ++i )
Password[i] = Letters[Entry[i]];
//houssam
Password[PSSWDLength] = '\0';
printf("%s length = %d %d \n ", Password , PSSWDLength , strlen(Password));
/* generiertes Wort hashen */
MD5Hash( Password );
/* Entry inkrementieren */
for( i = 0; i < PSSWDLength && ++Entry[PSSWDLength-i-1] == *NLetters; i++ )
Entry[PSSWDLength-i-1] = 0;
/* Return wenn Entry != LastEntry raus aus der Schleife */
for( j = 0; j < PSSWDLength; ++j )
if( Entry[j] != LastEntry[j] )
break;
/* wenn Entry == LastEntry Funktion verlassen */
if( j == PSSWDLength )
return;
}
}
static void MD5Hash( const char *PasswordStringPointer )
{
unsigned char Digest[16];
/* MD5-Hash erzeugen */
MD5_CTX md5;
MD5_Init( &md5 );
MD5_Update( &md5, PasswordStringPointer, strlen( PasswordStringPointer ) );
MD5_Final( Digest, &md5 );
if( memcmp( HexByteHash, Digest, 16 ) == 0 )
{
printf( "!!! Wort gefunden: '%s' !!!\n", PasswordStringPointer );
/* Timer stoppen */
time( &EndTime );
printf( "Elapsed time: %ld minutes %ld seconds\n\n", ( EndTime - StartTime ) / 60, ( EndTime - StartTime ) % 60 );
/* Passwortsuche war erfolgreich */
exit( EXIT_SUCCESS);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With