Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Mon, 30 Apr 2012 16:27:59 -0500
From: "jfoug" <>
To: <>
Subject: New JtR functionality, re-build lost salts

I have added some code, that will allow john to find Password/Salts in
certain situations, if all that is available is the MD5 hash.   Frequently,
in large hash lists, there are some of these salted hashes in there, but
with missing salts.   This modification to JtR will allow these to be found
(albeit, pretty slowly).   This patch has not been put into the .git repo
(magnum-jumbo) yet, but it properly patches a clean pull from magnum-jumbo.


To detect this situation (if there is likely some hashes out there, that are
not straight raw-md5), build a dictionary, which contains the md5 hex string
of some very highly seen passwords (such as JtR's prebuilt password.lst


Then run this as a password input file (the file is the 32 byte hashes).
Run this with rules that append some 2 byte strings (numerous), append some
3 byte strings, and append some single digit numbers and a dash.


So, the input file would be contain  5f4dcc3b5aa765d61d8327deb882cf99 which
is the md5 for password.  And these 'type' passwords would be the ones














NOTE, It will likely require quite a few of the appended 3 to find
candidates.   However, if running tests like this, you start to see some JtR
cracks, then you certainly have some of these type hashes scattered within
the hashes.  The #-hash is a media-wiki hash type.  It is dynamic_9, which
is md5($s . '-' . md5($p))  The $s used by some versions of media wiki is
the user number (which may start at 1 or 0, and often there is less than
1000 users in the wiki).  The other type (appended 3 byte to the hash), is
PHPS (vBulletin, etc).  It is dynamic_6 which is md5(md5($p).$s)


The other type of hash to 'look' for, is the OsCommerce type hash.  This
hash is of this format:   dynamic_4, md5($s.$p) with a 2 byte salt.  To find
these, run a high value password file, appending 2 bytes of random values.


So the password file might contain 'password'  (not the hex string), and the
candidates to test would be 





.  (the salt is any 2 chars from '  ' to '~~' i.e. 2 spaces to 2 tilde's)
The PHPS are 3 spaces to 3 tildes.  NOTE, for these OsCommerce type hashes,
you can never fully be sure if it is an OSC hash, or a true raw-md5 hash.
Often times you 'can' tell, but at other times, you cannot. So, if the
password cracked is  Password  and the 'salt' was 12, was this an OSC hash,
with a salt of 12, or is this a raw-md5 hash of the password 12Password
Hard to tell.  However if the salt was B{ and the password was Password,
then it is much more likely that this really was the password of Password,
of the 2 byte salt OSC type, with the salt being B{  which would be this pot
line: $dynamic_4$510100617ba341539587cdbd356fc2dd$B{:Password vs this one:
$dynamic_0$510100617ba341539587cdbd356fc2dd:B{Password    The other 2 types
handled by this patch (the mediawiki, and PHPS), are NOT going to be
possible to be mistaken identity.  They are not a simple md5($s.$p).  They
append the salt to the md5 hex of the password.  When one of those found are
found, the ambiguity is not there.



What this patch does, is to load the raw hashes into one of these 3 'thin'
formats, but adds a fake salt to each loaded hash.  The fake salt is the
exact same salt each time.   These 3 formats are:  mediawiki_fmt.c
PHPS_fmt.c and a new OSC_fmt.c    There is a new flag added to JtR
(documented in the OPTIONS document, but does not show on JtR's usage
screen, NOTE, just changed and added a option flag to JtR's output, so I can
add tests in the Test suite later).  This flag is -regenerate-lost-salts=N.
It takes an enumeration.  You have to use the proper enumeration and the
proper -format= value.  Once all of the hashes are loaded, they are assigned
to exactly the same salt since when we built the 'fake' input hashes with
same salt.  JtR will then build an array of salt objects. It will assign ALL
of the pointers from that original salt record (the one that contained all
of our hashes), setting the next pointers up properly to build our list, and
allocating the proper salt 'data' item for this salt.   So, in essence, we
have loaded all of the hashes, and all of the hashes belong to all salt
records, and we have allocated ALL possible salt records.  From this point
on, JtR simply runs as normal.


So, for the media-wiki, we have salts from 0- to 999- which is 1000 salts
(or 1000- to 9999- or 10000- to 99999- ).  For OsCommerce, we have 95**2
salt records - 9025 (space to tilde).  And for PHPS, we have 95**3 - 857375
salt records.  Every candidate hash is located in each of these salts.


There are a few additional changes needed to pull this off.  Since we do not
'know' what the salt is, until we find it, we have to 'fix' the internal
data at a few locations (writing pot file, cleaning up our data when reading
from the pot file at startup, etc).  To fix, we take the 'known' correct
salt, and fix the place holder salt, so that things work properly.  So in
the end, the .pot lines will be in proper $dynamic_6$ (or dyna_4 or dyna_9)
with the proper salt added, AND the password found.   I also added some code
which will output in the $HEX$ format if the hash type is a dynamic type,
and there is a ':' char (or \r \n \x0, etc) in the salt value.  Also, upon
reloading, within the prepare function of dynamic, if a salt is found with a
$HEX$, it is 'undone', so that comparisons can be done.

The changes to JtR in this patch, should not interfere with any JtR running,
unless the -regenerate-lost-salts=N flag is used.  Thus, unless some really
wants to use this logic, it does not bother anyone else's runtime.  I have
wanted this type functionality several times in the past, and most recently
in the 143 million 'dirty' raw-md5 hashes released in the KoreLogic torrent.
I had been doing this by building large dictionary files, reading a few
PW's, converting to md5 hex, and appending 3 bytes (building 857375 lines
that are 36 bytes long, for each password).  That works fine, but is a huge
disk IO hog.  This new method is faster, and does not suck up huge amounts
of disk IO (and can rebuild the proper salt and password, without having to
later 'fix up' converting salt to a password).




Content of type "text/html" skipped

Download attachment "JtR_PHPS_Missing_Salts_Crack_Hack.diff" of type "application/octet-stream" (37145 bytes)

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.