|
|
Message-ID: <20150929150311.GA547@openwall.com>
Date: Tue, 29 Sep 2015 18:03:12 +0300
From: Solar Designer <solar@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: Re: Reading loaded password hashes inside crypt-all.
Hi Sayantan,
> On Tue, Sep 29, 2015 at 3:05 PM, Sayantan Datta <std2048@...il.com> wrote:
> > Are password hashes removed from database as they are cracked ?
Yes, but only from fields actually used during a given cracking run, and
not necessarily right away. (In "single crack" mode, there's postponed
removal.)
> > Apparently
> > there are discrepancies between salt->count and number of remaining hashes
> > in salt->list. While salt-count is updated, it seems like salt->list is not
> > updated to reflect the cracked hashes.
> >
> > pw = salt -> list;
> > i = 0;
> > do {
> > bin = (int *)pw -> binary;
> > if (bin != NULL) {
> > store_binary();
> > i++ ;
> > }
> > } while ((pw = pw -> next)) ;
> >
> > Running this loop in the middle of cracking results in 'i' being greater
> > than 'salt->count' !!
Yes, and that's "normal". See crk_remove_hash(). It always updates
crk_db->password_count and salt->count, but it only updates the list
when there's no bitmap, and it only updates the bitmap and sometimes
the hash table when there is a bitmap.
OK, you don't actually rely on the list being updated - you only rely on
the removed entries being marked with "binary = NULL". That's easier
for cracker.c to support, and it happened to support this until recently.
> > Some recent change might have triggered this issue.
> > Earlier, such behavior were not noticed.
> >
> > This broke an optimization where hashes are re-loaded onto GPU after some
> > of them are cracked, resulting in better speed!!
Oh. We probably need to do something about this.
On Tue, Sep 29, 2015 at 04:18:57PM +0530, Sayantan Datta wrote:
> This one line patch fixes the issues but I'm not sure to commit it.
There was a good reason for this change (minimizing writes to the
database when running with --fork), so I'd rather not revert it.
> diff --git a/src/cracker.c b/src/cracker.c
> index 0456114..3276e2f 100644
> --- a/src/cracker.c
> +++ b/src/cracker.c
> @@ -308,7 +308,7 @@ static void crk_remove_hash(struct db_salt *salt, struct db_password *pw)
> * "single crack" mode, so mark the entry for removal by "single crack" mode
> * code if that's what we're running, instead of traversing the list here.
> */
> - if (crk_guesses)
> + //if (crk_guesses)
> pw->binary = NULL;
> }
To summarize, the issue is that cracker.c makes assumptions about how
the database is used in a given cracking run, and those assumptions
might not hold true for formats' own use of the database from
crypt_all(). Maybe we need to introduce a format flag and check it
here? Like this:
if (crk_guesses || (crk_params.flags & FMT_REMOVE))
pw->binary = NULL;
and your formats that need this would set FMT_REMOVE.
Moreover, when your code sees "binary = NULL", it will also remove that
entry from the list. crk_remove_hash() doesn't do this when there's a
bitmap to avoid traversing the list on every guess, but you're
traversing the list for transfer to GPU anyway.
The meaning of FMT_REMOVE would then be: if the generic cracker code
doesn't remove a cracked password from salt->list on its own, it must
nevertheless mark that entry for removal by setting its "binary = NULL",
and the format's crypt_all() will then eventually remove the entry from
the list.
How does this sound to you?
Thanks,
Alexander
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.