0

I'm making a program in C to crack DES-based encrypted password, It takes the password as an argument and gives me the password.

What I did was trying 500000 words by encrypting them in the same salt (first 2 letters) and then compare it with argv[1] (which is the encrypted password that I want to crack). I think it's called brute force (trying everything possible). anyway my problem is when I encrypt the words I get different encryption (same salt and same key) as you see I print the number, words and the encryption (just to check if it works) you can remove them if you want!

btw I got the code that reads the line from file from some website, since I'm new to C and I haven't learnt about files yet!

Please be gentle I'm really new here :D, and if you got a comment of the design or code just tell me :)!

BTW I'm taking cs50 course from XHarved, and this is in the hacker edition, so I don't have to do it. It's like extra homework!

Example: when I crypt the word "crimson" in the crypt function it becomes 50yoN9fp966dU but when I import it from a file and then crypt it, it's something else (50fy...).

Sorry for the long question :|!

See it if you want: http://d2o9nyf4hwsci4.cloudfront.net/2014/x/psets/2/hacker2/hacker2.html#_passwords_em_et_cetera_em

#include <stdio.h>
#include <unistd.h>
#include <cs50.h>
#include <string.h>

#define _XOPEN_SOURCE

char *crypt(const char *key, const char *salt);


int main(int argc, char *argv[])
{
    static string cryptedText[500000];
    static char word[500000][50];
    string salt;
    int i = 0;

    if (argc != 2) 
        return 1;

    FILE *fp;

    fp=fopen("wordsTest.txt","r");
      if(fp==NULL)
    {
      printf("Unable to open file.\n");
      exit(1);
    }

    // the first 2 characters are the salt.
    salt = strcat(&argv[1][0], &argv[1][1]);

    /*crypt every word in wordsTest with the same "salt" and 
    test if it equals argv[1](crypted pass) */
    do
    {

    if(fgets(word[i],50,fp)!=NULL)
        printf("%i ----> %s",i , word[i]);

    cryptedText[i] = crypt(word[i], salt);
    printf("%s\n", cryptedText[i]);

    i++;

    }
    while (strcmp(cryptedText[i - 1], argv[1]) != 0);


    printf ("%s\n", word[i - 1]);

}

I think the cryptedText variable doesn't need to be 500000 (I can overwritte it everytime)

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Ehab Younes
  • 3
  • 1
  • 4
  • 1
    I'm not sure what you're asking. Do you have a question that's more specific than "my DES brute force cracker doesn't work"? – Michael Burr May 03 '14 at 02:01
  • What I meant is, when I compile and run my program it crypts 500000 words from a file called "wordsTest" and then compares each one with the encrypted password (the one with argv[1]). My problem is when it crypts words from files it gives me different encryption! – Ehab Younes May 03 '14 at 06:48
  • 1
    The input from `fgets()` includes the newline; you don't eliminate it. Therefore, you're comparing the encryption of `"crimson"` with the encryption of `"crimson\n"` and the answers must be different. – Jonathan Leffler May 03 '14 at 12:34
  • Thx @JonathanLeffler!!!, I guess that's what I get for not reading the manual page for the fgets function :P. It's working now, but for some reason I had to replace the strcmp (I didn't compare like it's suppose to) in the while loop to strncmp and set the "int n" to 13. anyway shouldn't you answer not comment :P! – Ehab Younes May 04 '14 at 15:07

1 Answers1

1

As noted in my comment:

The input from fgets() includes the newline; you don't eliminate it. Therefore, you're comparing the encryption of "crimson" with "crimson\n" and the answers must be different.

You mentioned in a comment:

…for some reason I had to replace the strcmp (it didn't compare like it's supposed to) in the while loop to strncmp and set the "int n" to 13.

With general encryption, since the encrypted data is a blob of binary data that might include embedded null bytes '\0', you would probably use memcmp() rather than use either strcmp() or strncmp().

However, since you're using crypt(), the output has an encoding similar to Base-64. It produces a (fixed length) string, but you have to copy that string to preserve the value. It will be overwritten by the next call to crypt(). So, you are probably busy stashing the same pointer into the array of pointers. (Aside: that <cs50.h> header, and in particular its string type, are annoying!)

Aside:

To be of any use, defines like #define _XOPEN_SOURCE must appear before any system headers are included. Also, you should specify the version number you want; you should probably use 600 or 700, depending on what your platform supports. You shouldn't have to write the declaration of the crypt() function in your code. The problem occurred because the #define _XOPEN_SOURCE was misplaced and misvalued.

Also, the line salt = strcat(&argv[1][0], &argv[1][1]); is weird and invokes undefined behaviour. It is weird because it tries to add the string starting at the second character of argv[1] to the end of argv[1], and invokes undefined behaviour because (a) the strings overlap and (b) you're writing into space that isn't available.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Yeah, well. I'll learn about pointers this weeks lecture (finally :p) so I'll be using char * instead of string! and thanks for the design advise :D! - btw in the cs50 page it didn't specify which version to use and I don't know what it is. but I think this explains it! [link] http://stackoverflow.com/questions/5378778/what-does-d-xopen-source-do-mean – Ehab Younes May 04 '14 at 15:38
  • Yup; that is a decent explanation. – Jonathan Leffler May 04 '14 at 15:40
  • Just wanted to add, I just found out that this is called dictionary attack xD, looks like I'll have to add the REAL brute force attack! – Ehab Younes May 04 '14 at 15:51
  • And again, I didn't read the man page about strcat :|, strncpy(salt, argv[1], 2); and then (char not char *) salt[3] = '\0';I didn't get error on the first one although as you explain I should get one! – Ehab Younes May 05 '14 at 14:58