Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Wed, 6 Jul 2011 09:53:47 +0400
From: Solar Designer <solar@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: Re: Either my test script is b0rken or BF has an 8-bit bug

On Mon, Jun 20, 2011 at 07:29:06AM +0400, Solar Designer wrote:
> One idea I had is to provide an external filter() for JtR (after fixing
> the bug in it) to be used when cracking potentially wrong bcrypt hashes
> (produced with the buggy crypt_blowfish).  The translated passwords
> would produce the same bcrypt hashes, but using the correct bcrypt code.
> For example, "\xa3" (pound sign) would be translated to "\xff\xff\xa3",
> which produces the above hash on OpenBSD.
> 
> Unfortunately, there exist passwords with no correct equivalent.  For
> example, "A\xa3" (letter "A" and the pound sign) produces this expanded
> key with the buggy code:
> 
> ffa30041ffffffa3ffffa300ffa30041ffffffa3ffffa300ffa30041ffffffa3ffffa300ffa30041ffffffa3ffffa300ffa30041ffffffa3ffffa300ffa30041ffffffa3ffffa300
> 
> Notice that the pieces separated by NUL bytes are not the same.  We'd
> need to embed NULs to encode this, but a NUL terminates processing of
> the input password.
> 
> Thus, the filter() idea has to be abandoned, or at least the filter()
> will only work for some passwords, but not for all.

Although I implemented support for the bug in 1.7.8 under the $2x$
prefix, here's the filter() as well:

[List.External:bcrypt_x2a]
void filter()
{
	int new[72], src, dst, nuls, length;

	src = dst = nuls = 0;
	length = 72;
	while (dst <= 68) {
		int i, tmp;
		i = tmp = 0;
		while (i < 4) {
			int c;
			tmp <<= 8;
			tmp |= (c = word[src++]) << 24 >> 24; // 32-bit int
			if (!c)
				src = 0;
			i++;
		}
		nuls += !(new[dst++] = (tmp >> 24) & 0xff);
		nuls += !(new[dst++] = (tmp >> 16) & 0xff);
		nuls += !(new[dst++] = (tmp >> 8) & 0xff);
		nuls += !(new[dst++] = tmp & 0xff);
		if (length == 72 && nuls) {
			length = dst - 5;
			while (new[++length])
				continue;
		}
		if (nuls >= 2)
			break;
	}

	dst = 0; src = length + 1;
	while (dst <= length) {
		if (new[dst++] == new[src++])
			continue;
		word = 0; // No corresponding $2a$ password
		return;
	}

	src = dst = 0;
	while (dst < length)
		word[dst++] = new[src++];
	word[dst] = 0;
}

Alexander

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ