5

SPOILERS (maybe)

Hi, I have just started working on crack. I have no previous experience, at least not too much but I'm trying to grasp the logic behind this and it seems my biggest issue for this is pointers (or rather ignoring their existence for crypt)

What I figure out could potentially work is:

1) check if there are 2 arg

2) declare an array of all letters of the alphabet (I was thinking this may be unnecessary and taking unnecessary space but to simplify it for now - baby steps - I decided to do so)

3) iterate through the array (4 nested loops for 1, 2, 3 and 4 letters passwords) while checking if the output of crypt with same salt and my current guess is same as the hashed password.

I started writing the loops but after I wanted to test it for 1 letter first it did not wanted to compile (pointers I think).

This is the relevant fragment of my code (with 1 loop only for now):

//Declare an array of all the letters in the alphabet
char letters[52] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

string hashed = argv[1];
char salty[3] = {hashed[0], hashed[1], '\0'};
string salt = salty;

for (int i = 0; i < 52; i++)
{

    if (crypt(letters[i], salt) == argv[1])
    {
        printf("Password: %s\n", letters[i]);
    }
}

This is what I (not surprisingly) get from clang:

warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'; take the address with & [-Wint-conversion]
        if (crypt(letters[i], salt) == argv[1])
                  ^~~~~~~~~~
                  &
/usr/include/crypt.h:32:33: note: passing argument to parameter '__key' here
extern char *crypt (const char *__key, const char *__salt)
                                ^
warning: format specifies type 'char *' but the argument has type 'char' [-Wformat]
            printf("Password: %s\n", letters[i]);
                              ~~     ^~~~~~~~~~
                              %c

I know it may be a lot to ask for but could anybody explain to me what should I do with this? Just a hint would be great I wanna use this as a learning experience.

Thank you.

1 Answer 1

6

Your problem is that letters[i] is a char, but the crypt() function expects a char * (string) as its first argument. So what you really want to do is pass a string with a single character, not a single character.

You need to pass this char array ['a', '\0'], not this char 'a'.

A simple fix can be to declare a char array with a length of 2, with the second char always being '\0', and just change the first char of this array in every loop, like so:

working example

#include <stdio.h>
#include <string.h>
#include <crypt.h>

int main(int argc, char const *argv[])
{
    printf("Hashing password Z with salt 50: %s\n", crypt("Z", "50"));

    //Declare an array of all the letters in the alphabet
    char letters[52] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

    const char *hashed = argv[1];
    char salt[3] = {hashed[0], hashed[1], '\0'};

    // initialize the whole array to '\0's
    char pass[2] = {'\0'};

    for (int i = 0; i < 52; i++)
    {
        // change the first letter of the password string
        pass[0] = letters[i];

        if (!strcmp(crypt(pass, salt), argv[1]))
        {
            printf("Password: %s\n", pass);
            break;
        }
    }

    return 0;
}

I added the printf() at the beginning to find a valid encrypted password, which was 50R.6FuTGui8U for plaintext Z and salt 50.

So when I run the code I get:

Hashing password Z with salt 50: 50R.6FuTGui8U
Password: Z

You might notice some changes.

  1. You can use the array salt as the salt. You don't need another string.

  2. To compare the output of crypt() with the original hash, you can't use == which would compare the pointers of the two strings. You have to use strcmp() to check for equality.

  3. I added a break if the password was found to not continue the search.

I know it's been a month since the question was asked, but I felt someone should answer it. If by chance you are still stuck, I hope this will help.

Happy coding!

1
  • 1
    Very belated and very honest THANK YOU! This is super informative and really helpful. I got it and solved the problem with your help!
    – Karvin
    Sep 29, 2018 at 4:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .