1

My program is supposed to be a brute force password cracker (school assignment). The input arguments are as follows..

./crack threads keysize target

The program needs to check passwords of length keysize, but also need to check shorter ones. I am unsure of how to go about writing something that will just change one letter at a time, and then continue doing this.. (keysize max is going to 8)

Example..

keysize = 5, so a loop (I think) would need to modify something that is equal to "aaaaa" to "aaaab" to "aaaac", putting each result into crypt_r(), along with the salt (first two characters of target) until a match is found.

I'm using crypt_r because the next step is to add multi-threading.

Unsure if anything else is really needed to explain this question. Would be glad to clarify.

4

2 回答 2

2

Let's see. There are 10^n possible n-digit decimal numbers. So there are 26^8 possible 8-character passwords that use only the letters a-z. That works out to 208,827,064,576.

You can keep track of the numbers with a simple 64-bit counter, and then convert the number to a base-26 representation. Something like:

long max = 208827064576;
longlong counter = 0;

while (counter < max)
{
    char password[9];
    GetPassword(counter, password);
    // do whatever you want with the password
    ++counter;
}

void GetPassword(longlong count, char* pass)
{
    int i;
    int rem;
    if (count == 0)
    {
        pass[0] = 'a';
        pass[1] = '\0';
        return;
    }
    i = 0;
    do
    {
        int rem = count % 26;
        pass[i] = 'a' + rem;
        ++i;
        count /= 26;
    } while (count > 0)
}

You can easily make this available to multiple threads by using interlocked increments of the counter variable. Or you can split the search space so that one thread starts at 0, one thread starts at 26^7 (which would be baaaaaaa), etc.

200 billion is a reasonably large number. A billion seconds works out to something close to 32 years. Even if you could check a few thousand of these per second (unlikely), it would take you quite some time to do an exhaustive search.

于 2013-09-26T18:46:45.443 回答
1

This code will cycle through all passwords no longer than given lengh and containing only letters from a to z:

#include <stdio.h>
int main(void) {
    char password[9] = {0};
    int keysize = 5;
    for (;;) {
        // get next password value
        // we do it by adding 1 in 26-al system
        int level = 0; // current level, starts at 0
        while (level < keysize) {
            if (password[level] == 0) {
                password[level] = 'a';
                break;
            }
            if (password[level] >= 'a' && password[level] < 'z') {
                password[level]++;
                break;
            }
            if (password[level] == 'z') {
                password[level] = 'a';
                level++;
            }
        }
        if (level >= keysize)
            break; // we have checked all passwords!
        // check if password matches:
        //printf("Checking password: '%s'\n", password);
        if (check_password(password)) {
            printf("Hooray! Password found: %s\n", password);
            break;
        }
    }
    return 0;
}

If you limit aphabet to a, b, c and set keysize=4, it checks following passwords:

a b c aa ba ca ab bb cb ac bc cc aaa baa caa aba bba cba aca bca cca aab bab cab abb bbb cbb acb bcb ccb aac bac cac abc bbc cbc acc bcc ccc aaaa baaa caaa abaa bbaa cbaa acaa bcaa ccaa aaba baba caba abba bbba cbba acba bcba ccba aaca baca caca abca bbca cbca acca bcca ccca aaab baab caab abab bbab cbab acab bcab ccab aabb babb cabb abbb bbbb cbbb acbb bcbb ccbb aacb bacb cacb abcb bbcb cbcb accb bccb cccb aaac baac caac abac bbac cbac acac bcac ccac aabc babc cabc abbc bbbc cbbc acbc bcbc ccbc aacc bacc cacc abcc bbcc cbcc accc bccc cccc

See this example at IdeOne DEMO.

于 2013-09-26T05:11:30.670 回答