1

I've been working on a password guessing program, and now I've been trying to figure out how to make it guess a password that's hashed. My problem is that the output of my guessed password is nothing similar to the hashed password. I was wondering if someone could point me in the correct direction.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crypt.h>
#include <sys/random.h>

#define BUFFERSIZE 10000

const char saltchars[]="abcdefghikjlmnopqrstuvWxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+@£[]}";
static const int saltcharsSize = sizeof(saltchars) -1;
int counter = 100;
char saltCopy[13];
char passwordCopy[22];

I initialize an alphabet, and some global variables for the functions.

void crack(char* string, int index, int maxSize) {
    for (int i = 0; i < saltcharsSize; ++i) {
        char* guessPassword = crypt(string, saltCopy);

        if(strcmp(guessPassword, passwordCopy) == 0) {
            printf("Found password: %s\n", string);
        }
        string[index] = saltchars[i];

        if (index == maxSize -1) {
            printf("%s\n", guessPassword);
        }
        else crack(string, index + 1, maxSize);
    }
}

void crackRecursive(int maxLength) {
    char* buffer = malloc(maxLength + 1);

    for (int i = 1; i <= maxLength; ++i) {
        memset(buffer, 0, maxLength + 1);
        crack(buffer, 0, i);
    }
    free(buffer);
}

here I try to ask it to crypt a password using the same salt, and compare it to the copy.

void readDictionary(char* file) {
    FILE *filePointer = fopen(file, "r");

    char buffer[BUFFERSIZE];

    while(fgets(buffer, BUFFERSIZE -1, filePointer) != NULL && counter != 0) {
        char* guessPasswordNew = crypt(buffer, saltCopy);

        if(strcmp(guessPasswordNew, passwordCopy) == 0){
            printf("found password: %s\n", buffer);
        }
        counter--;
    }
    fclose(filePointer);
    free(filePointer);
    printf("\nEnd of program\n");
}

here I read a file in my dictionary and try to guess if it's one of the words in the file. Same procedure in guessing the password here.

int cryptPassword(char* password){
    char salt[13]="$1$abcdefgh$";
    getrandom(salt+3,8,0);
    for(unsigned int i=3;i<11;i++){
        salt[i]=saltchars[salt[i] & 0x3f];
    }
    printf("password is: %s\n", password);
    printf("salt is: %s\n", salt);
    strcpy(saltCopy, salt);
    char* encrypted=crypt(password,salt);
    strcpy(passwordCopy, encrypted);
    printf("hashed password is: %s\n", encrypted);
    free(encrypted);
    return 0;
}

this is the encryption, it's just for setting the salt, and then using "crypt" to encrypt the password with the salt.

int main(int argc, char *argv[]) {
    cryptPassword("earlybird");
    crackRecursive(2);
    readDictionary("dictionary.txt");
}

finally, this is the main method, where I set the password to "earlybird", which is in the dictionary.txt file. I've also tried with "aA", and that didn't work.

The methods print out everything I want, the crack prints "aa" and then "ab" and continues iterating over the alphabet I provided until the end. The dictionary is read in properly. Of course, this is only when I tell it to printf the string in "crack" and the "buffer" in readDictionary.

I suspect it's some mistake I am making with the salt, as it looks like the hashed password has the salt in front, but my guesses do not.

kveola92
  • 69
  • 4
  • Without even looking at the code: Are you sure it isn't a hash collision? – HolyBlackCat Nov 06 '18 at 15:08
  • What's a hash collision? I'm not sure how to avoid that. – kveola92 Nov 06 '18 at 15:22
  • Different passwords can have a same hash. If hash for the password you get is the same as the hash of the original password, then everything works as it should. Otherwise your code is indeed broken. – HolyBlackCat Nov 06 '18 at 15:29
  • Password is different, I think. It won't find it at least. I should probably print out the hash and compare it, now that you mention it. – kveola92 Nov 06 '18 at 15:33
  • 1
    Your `saltchars` is not the standard `crypt` alphabet. Where did it come from? It's 68 bytes long! Also I'm confused by a function named `crackRecursive` that isn't recursive, and suspicious of `fgets` with no `'\n'` cleanup. –  Nov 06 '18 at 16:02
  • `fgets(buffer, ...` retains the `'\n'` on input. Yet `"earlybird"` does not. – chux - Reinstate Monica Nov 06 '18 at 16:04
  • 1
    For debugging, start by fixing the salt to a constant value, which will help you decide whether the problem is or isn't the salt. Really, there is a lot you can do on your own to simplify this rather than posting the whole code and ask why it is not working. See: https://stackoverflow.com/help/mcve – TheGreatContini Nov 06 '18 at 17:53

0 Answers0