JtR is not loading my Hash!
Friday, March 01, 2013 | Author: Deep Flash
If you crack hashes regularly then you might have come across this problem once in a while where JtR does not load your hashes even though you are supplying the right hash type format in the arguments.

As an example, I would consider the bcrypt hashes that were provided in the PHDays 2012 contest. Almost, everyone who had a go at these hashes using JtR faced the problem that they were not loading.

Example of the hashes provided in PhDays2012:

$2a$05$ytuajhsgrtchsqgtdfjdsftBIrnvlIl7cedjJEPkFrSV6FTJOWgNG
$2a$05$ytuajhsgrtchsqgtdfjdsfp73vMcbNqwoqWskiHIGBXyzF6YWWmoy

$2a$05$gs&*(%sgda759127ccasq4NzxE/ry6hQ3mNtQXR2V1ystfMQvnQdS
$2a$05$gs&*(%sgda759127ccasq4EOrPWUFMyOZLfAborHufR6v9TtEGcLa


Are you able to tell what is wrong with these hashes?

Now, lets try loading these hashes into JtR:

./john --fo=bf -w:wordlist.txt bcrypt.txt
No password hashes loaded (see FAQ)

So, even though the hashes provided to us look like bcrypt hashes they do not load in JtR. By default, JtR's output in such cases is not verbose and it does not give the details as to why the hash was not loaded.

Once we check the JtR code which is used to validate the hash type, we will understand.

Before that, here is some information about the salt used in bcrypt hashes.

The actual salt is a 16 byte binary salt. However, it is base64 encoded into 22 characters which is what we see in the hash. Each of the first 21 characters of the encoded salt represent six bits of the 16 byte binary salt. The last character of the encoded salt represents only 2 bits of the binary salt.

21*6+2=128 bits = 16 bytes

This base64 encoding is done using the charset: [./a-zA-Z0-9]

It is a cusom base64 encoding used by OpenBSD.

If we consider the hash:

$2a$05$gs&*(%sgda759127ccasq4NzxE/ry6hQ3mNtQXR2V1ystfMQvnQdS

we can clearly see the reason that why it did not load in JtR because of the invalid salt characters, &*(%.

In this case, it is easy to conclude why JtR did not load the hash.

However, in the case of other hash: 

$2a$05$ytuajhsgrtchsqgtdfjdsftBIrnvlIl7cedjJEPkFrSV6FTJOWgNG

we are unable to spot the invalid salt character.

The details from this hash are:

$2a$ -> current bcrypt
05 -> work factor which translates into the number of iterations as 2^05
ytuajhsgrtchsqgtdfjdsf -> encoded 16 byte binary salt
tBIrnvlIl7cedjJEPkFrSV6FTJOWgNG -> encoded binary hash

Let's check the source code of BF_std.c in JtR's src folder:

Just before the BF_decode function which is used to decode the salt, we see the comment:

/*
 * I'm not doing any error checking in the routines below since the
 * ciphertext should have already been checked to be fmt_BF.valid().
 */


static void BF_decode(BF_word *dst, char *src, int size)
{
     unsigned char *dptr = (unsigned char *)dst;

     ....

So, the validation is being performed in BF_fmt.c

Check the function, valid which accepts a pointer to char as an argument and returns an integer:


static int valid(char *ciphertext)
{
    int rounds;
    char *pos;

    if (strncmp(ciphertext, "$2a$", 4) &&
        strncmp(ciphertext, "$2x$", 4) &&
        strncmp(ciphertext, "$2y$", 4))
    return 0;


This function performs various checks on the ciphertext. If it returns 0, then it means that the ciphertext could not be loaded by JtR.

If every check was successful, then it returns 1 in which case the hash is loaded.

We will make these checks more descriptive by printing out appropriate messages when a check is failed so that instead of just receiving the message, "No password hashes loaded", we receive a more descriptive message that allows us to correct the hash.

The modified function, valid is as shown below:



You can replace the existing function, valid in BF_fmt.c and use the one provided above.

Now, compile JtR:

make -j8 linux-x86-sse2

We run JtR against the bcrypt hash:

$2a$05$ytuajhsgrtchsqgtdfjdsftBIrnvlIl7cedjJEPkFrSV6FTJOWgNG

./john -fo=bf -w:wordlist.txt bcrypt.txt
Please check the last character of the encoded salt
No password hashes loaded (see FAQ)


So, this error message tells us that the last character of the encoded salt is incorrect.

In this case, the last character of the encoded salt is "f" which is the reason for the hashes not loading.

Last Character of the Encoded Salt in Bcrypt Hashes

Let us see why the last character of the encoded salt cannot be "f". The reason is that only 2 bits in the last byte of the binary salt are left to choose the last encoded salt character from the charset [./a-zA-Z0-9]. The remaining bits (126 bits) are used for selecting the first 21 encoded salt characters.

Since only 2 bits are available for encoding the last salt character, 4 bits are padded to the result.

So, total combinations are 4.

The last character of the encoded salt in bcrypt hashes can only be, '.', 'e', 'O', 'u'.

In order to see this, you can grab a large list of bcrypt hashes and check:

perl -pe 'while(<>){chomp; print substr($_,28,1),"\n";}' < bcrypt.txt | sort -u

.
e
O
u


now, we will use the BF_atoi64 array provided in BF_std.c which is used to decode the salt characters and see what are the corresponding binary values which these encoded salt characters represent.

I have written this short C code which will allow us to perform this translation:



output:

~/Programs$ ./arch_index
salt character: . corresponds to 0 and binary: 0
salt character: e corresponds to 32 and binary: 100000
salt character: O corresponds to 16 and binary: 10000
salt character: u corresponds to 48 and binary: 110000


As you can see, the least significant 4 bits of the salt should be set to 0. If any one of these 4 bits are set to 1, then as a result of that the last check in BF_fmt.valid() will return 0 and the hashes will not load.