Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 20 Jun 2011 16:57:13 -0500
From: "Jim Fougeron" <Jim.Fougeron@...ventdtn.com>
To: <john-dev@...ts.openwall.com>
Subject: RE: Even more mscash & mscash2 fixes

From: magnum [mailto:rawsmooth@...dband.net] 
>
>> Still, there is a major problem in mscash2: As far as I can tell, the 
>> maximum supported salt length is supposed to be 19 characters. Unless 
>> my generator script is to blame, John fails to crack any hash with a 
>> salt longer than 8 characters. The self-test I included with saltlen 
>> 19 is currently commented out. Unless this is fixed, the max length 
>> check in valid() should be really be decreased from 19 to 8.
>
>I haven't disabled saltlen >8 but the above still stands, mscash2 can 
>only handle salts (=usernames) up to eight characters - which 
>disqualifies the Administrator account, just as a random example...
>
>Haven't heard from S3nf so I'm hoping Jim can nail it. You lose me as 
>soon as you reverse steps.

I have put a little time into trying to figure out where the problem is, and do not see it.  I was able to pull down some code (the original, I think, found at www.fiveanddime.net/openssl-0.9.7g/crypto/evp/p5_crpt2.c.html) commented as:

/* p5_crpt2.c */
/* Written by Dr Stephen N Henson (shenson@...foot.com) for the OpenSSL
 * project 1999. ... */   

And put that together with enough other helper code (a few headers and a cryptolib.c) to where this would link properly against OpenSSL, but allow me to edit and test, and to step the code.  This code was tested against the sample project from john's wiki describing the mscash2 algorithm, which also has the bug.   The john wiki code is found at:  http://openwall.info/wiki/MSCash2-Algorithm?s=mscash2.   I dug into this, but was not able to find a solution in the PBKDF2_DCC2() code.

I did however, through the comment still left in the john-wiki code, and the name of the oSSL function in the p5_crypt2.c file, find a work around.  This is far from optimal work around.  What I have done is to use the PBKDF2_DCC2() function if the user name is 8 chars or less, and then use the oSSL function of PKCS5_PBKDF2_HMAC_SHA1() for user names from 9 to 19 chars.  NOTE, in the PKCS5_PBKDF2_HMAC_SHA1(), is looks like salts up to 21 characters (buffer is 44 bytes, so I am not sure if that is 21 or 22 chars), are possible.  However, the way we have mscash2_fmt.c laid out, only 19 chars can be valid, and the upper 4 bytes are used as salt length.  If 21 (or 22) char user names are valid, then we should look at growing the salt by an extra 4 bytes, or compute the salt length from the salt being passed in, vs stealing part of the needed salt buffer for the length.

Here is the code.  It is slower, but it DOES work.  NOTE: I am not sure if there are multi-tread issues in PKCS5_PBKDF2_HMAC_SHA1() in some versions/builds of oSSL.

	output1x[4 * i + 2] = (c >> 24) | ((c << 8) & 0x00FF0000) | ((c >> 8) & 0x0000FF00) | (c << 24);
	output1x[4 * i + 3] = (d >> 24) | ((d << 8) & 0x00FF0000) | ((d >> 8) & 0x0000FF00) | (d << 24);
#endif
    // PBKDF2_DCC2() fails for salts longer than 8 chars.  Until we find out why, we switch over to old OpenSSL
    // PKCS5_PBKDF2_HMAC_SHA1() function, which has NO problems, but is quite a bit slower.
    if (salt_len <= 16) {
      // PBKDF2 for new Domain Cached Credentials (MS Cash 2)
      PBKDF2_DCC2((unsigned char *)&output1x[4 * i], (unsigned char *)salt_buffer, salt_len, (unsigned char *)&output1x_dcc2[4 * i]);
    } else {
      // the even slower OpenSSL PBKDF2 implementation (compile with -lssl)  Also have to include <openssl/evp.h> to avoid declaration warnings.
      PKCS5_PBKDF2_HMAC_SHA1((unsigned char*)&output1x[4 * i], 16, (unsigned char *)salt_buffer, salt_len, 10240, 16, (unsigned char *)&output1x_dcc2[4 * i]);
    }
  }


The old code was:

		output1x[4 * i + 2] = (c >> 24) | ((c << 8) & 0x00FF0000) | ((c >> 8) & 0x0000FF00) | (c << 24);
		output1x[4 * i + 3] = (d >> 24) | ((d << 8) & 0x00FF0000) | ((d >> 8) & 0x0000FF00) | (d << 24);
#endif
		// PBKDF2 for new Domain Cached Credentials (MS Cash 2)
		PBKDF2_DCC2((unsigned char *)&output1x[4 * i], (unsigned char *)salt_buffer, salt_len, (unsigned char *)&output1x_dcc2[4 * i]);
	}


Certainly NOT a final solution. But at least, it gets mscash2 working.  The other option at this time, is to simply have valid drop user names > 8 chars, until someone can nail down the problem.   However, I have uncommented the 18 and 19 character test strings. They work fine.

Jim.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.