Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--regen-lost-salts NULL pointer dereference #4517

Closed
solardiz opened this issue Dec 10, 2020 · 5 comments
Closed

--regen-lost-salts NULL pointer dereference #4517

solardiz opened this issue Dec 10, 2020 · 5 comments
Assignees
Labels

Comments

@solardiz
Copy link
Member

As reported by @kernelr00ter in #1463 (comment):

in file hash_dump.txt
c4ca4238a0b923820dcc509a6f75849b
d3d9446802a44259755d38e6d163e820

run john --regen-lost-salts
Result:
0                (?)

*** Process received signal ***
Signal: Segmentation fault (11)
Signal code: Address not mapped (1)
Failing at address: (nil)
[ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f4d13061390]
[ 1] /john[0x47b785]
[ 2] /john[0x6bee8b]
[ 3] /john[0x6bfe30]
[ 4] /john[0x6c0605]
[ 5] /john[0x6dd359]
[ 6] /john[0x6cdd51]
[ 7] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f4d12ca6840]
[ 8] /john[0x407099]
*** End of error message ***
Segmentation fault (core dumped)

In this case, the utility correctly detects the hash result, but does not show the salt. And the report file remains empty.

But if you swap hashes
d3d9446802a44259755d38e6d163e820
c4ca4238a0b923820dcc509a6f75849b

Everything works perfectly.

Reproduced by me:

$ cat pw
c4ca4238a0b923820dcc509a6f75849b
d3d9446802a44259755d38e6d163e820
$ ./john pw --regen-lost-salts='@dynamic=md5($s.$p)@:32:?d' --mask='?d' --format='dynamic=md5($s.$p)' pw
Using default input encoding: UTF-8
Loaded 2 password hashes with no different salts (dynamic=md5($s.$p) [128/128 AVX 4x3])
Warning: no OpenMP support for this hash type, consider --fork=32
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 10 candidates left, minimum 24 needed for performance.
0                (?)     
Segmentation fault
@magnumripper
Copy link
Member

I tried to follow Jim's code for regen lost salts. The canonical way to do it would be to synthesize all salts at load time, resulting in a perfectly normal database, identical to what we'd get if we had simply generated an input file with all salts for each hash instead of relying on this feature. For this test case, it would say "20 password hashes with 10 different salts (2.0x same-salt boost)". From that point, nothing much could go wrong at all (the only magic would be the pot file matching code).

$ for i in c4da4238a0b923820dcc509a6f75849b d3d9446802a44259755d38e6d163e820; do for j in `seq 0 9`; do echo ${i}\$${j} ; done ; done
c4da4238a0b923820dcc509a6f75849b$0
c4da4238a0b923820dcc509a6f75849b$1
c4da4238a0b923820dcc509a6f75849b$2
c4da4238a0b923820dcc509a6f75849b$3
c4da4238a0b923820dcc509a6f75849b$4
c4da4238a0b923820dcc509a6f75849b$5
c4da4238a0b923820dcc509a6f75849b$6
c4da4238a0b923820dcc509a6f75849b$7
c4da4238a0b923820dcc509a6f75849b$8
c4da4238a0b923820dcc509a6f75849b$9
d3d9446802a44259755d38e6d163e820$0
d3d9446802a44259755d38e6d163e820$1
d3d9446802a44259755d38e6d163e820$2
d3d9446802a44259755d38e6d163e820$3
d3d9446802a44259755d38e6d163e820$4
d3d9446802a44259755d38e6d163e820$5
d3d9446802a44259755d38e6d163e820$6
d3d9446802a44259755d38e6d163e820$7
d3d9446802a44259755d38e6d163e820$8
d3d9446802a44259755d38e6d163e820$9

Alas, this doesn't quite seem to be the case with the current code: For this test case, john reports "2 password hashes with no different salts". Yet there are 10 salts in the database, and salt->count is 2 for each, which makes some sense. But db->salt_count is only 1, db->password_count is only 2, all salt->salt_md5 are uninitialized and salt->sequential_count is 1 for all salts. Jim's code runs after ldr_fix_database(), which sounds like a surefire Foot Gun to me.

I tried adding corrections for db->salt_count, db->password_count and salt->sequential_id. Neither helped in this case but other parts of john relies on them so we should commit that anyway. For now I didn't care about salt->salt_md5 because it's "optional", for quicker resume with slower formats.

Maybe the problem is the current code re-uses the password list for all salts (copying salt->list and salt->hash pointers instead of data). I suppose this might lead to strange things when something gets cracked and entries are removed from the lists since things like crk_remove_hash() wasn't written with this copying in mind.

Oh and BTW if you try --regen-lost-salts with invalid parameters, it bails out refering to docs/REGEN-LOST-SALTS while it should say doc/Regen-Lost-Salts.txt.

@magnumripper
Copy link
Member

magnumripper commented Aug 31, 2021

Maybe the problem is the current code re-uses the password list for all salts (copying salt->list and salt->hash pointers instead of data). I suppose this might lead to strange things when something gets cracked and entries are removed from the lists since things like crk_remove_hash() wasn't written with this copying in mind.

This copying does make sense in that if a hash gets cracked, it's removed from all salts. So if we loaded two hashes in this case it'd start saying "Loaded 20 password hashes with 10 different salts" but after just one of them is cracked there will be "Remaining 10 password hashes with 10 different salts".

On a side note we could change those messages when this feature is active, so they'd say something like "Loaded 2 password hashes with 10 possible salts each" and "Remaining 1 password hash with 10 possible salts".

@magnumripper magnumripper self-assigned this Aug 31, 2021
magnumripper added a commit to magnumripper/john that referenced this issue Aug 31, 2021
Since every salt copied the same salt->list pointer, a special fixup is
needed after removing *the first* binary in the list in crk_process_guess().
The generated salts written to the salt database lacked some info and the
total number of salts wasn't updated.
Error messages pointed to a non-existing file in a non-existing directory.
Change the "Remaining xx hashes with yy different salts" output to be more
accurate when this feature is used.
magnumripper added a commit to magnumripper/john that referenced this issue Aug 31, 2021
Since every salt copied the same salt->list pointer, a special fixup is
needed after removing *the first* binary in the list in crk_process_guess().
The generated salts written to the salt database lacked some info and the
total number of salts wasn't updated.
Error messages pointed to a non-existing file in a non-existing directory.
Change the "Remaining xx hashes with yy different salts" output to be more
accurate when this feature is used.
@magnumripper
Copy link
Member

I think I nailed it. PR in #4795. That pointer-copying was actually a good idea, but a fixup was needed for the case where the first binary in the list was removed by a successful guess. This bug must have been present since day 1 of the feature.

@magnumripper
Copy link
Member

Here's the new Loaded/Remaining output (running with ShowSaltProgress = Y and ShowRemainOnStatus = Y):

$ ../run/john test.in --regen-lost-salts='@dynamic=md5($s.$p)@:32:?d' --mask='?d' --format='dynamic=md5($s.$p)'
Loaded 2 password hashes with 10 possible salts (2.0x same-salt boost) (dynamic=md5($s.$p) [256/256 AVX2 8x3])
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 10 candidates left, minimum 48 needed for performance.
0                (?)     
1g 0:00:00:00  100.0g/s 1000p/s 10000c/s 20000C/s 1..7
Remaining 1 password hash with 10 possible salts
Use the "--show --format=dynamic=md5($s.$p)" options to display all of the cracked passwords reliably
Session completed. 

A correct salt-boost figure is shown, and the wording (IMHO) is better for this special feature: We only have 2 hashes, not 20, but each of them have 10 possible salts.

magnumripper added a commit to magnumripper/john that referenced this issue Aug 31, 2021
Since every salt copied the same salt->list pointer, a special fixup is
needed after removing *the first* binary in the list in crk_process_guess().
The generated salts written to the salt database lacked some info and the
total number of salts wasn't updated.
Error messages pointed to a non-existing file in a non-existing directory.
Change the "Remaining xx hashes with yy different salts" output to be more
accurate when this feature is used.
magnumripper added a commit to magnumripper/john that referenced this issue Sep 6, 2021
Since every salt has a copy of the initial salt->list pointer, a special
fixup is needed after removing the first binary in the list in
crk_process_guess().  This was the actual openwall#4517 issue.

Other fixes:
The generated salts written to the salt database lacked some info and the
total number of salts wasn't updated.  From now we copy the whole initial
database struct, avoiding several current and at least some possible future
problems.
Improved the "Remaining xx hashes with yy different salts" output to be
more accurate/informative when this feature is used.
Error messages referred to a non-existing file in a non-existing directory.
Several comments were bogus, eg. referring to code that was long gone.
General code-style fixes (including a couple of barely related, made while
trying to understand the code paths involved).
Add bodges for --show to work with hashes cracked using this feature. For
this to work you need to supply the --regen-lost-salts option with --show
too.
Since we unfortunately give the exact format as one of the parameters to
--regen-lost-salts (a fairly stupid decision made 8 years ago), add code to
automatically pick that format wheneven a --format parameter isn't given,
or complain if it is and they don't match.
Minor updates to doc/Regen-Lost-Salts, eg. dropping references to things
that were deprecated eight years ago.
@magnumripper
Copy link
Member

$ cat test.in
c4ca4238a0b923820dcc509a6f75849b
d3d9446802a44259755d38e6d163e820

$ ../run/john test.in --regen-lost-salts='@dynamic=md5($s.$p)@:32:?d' -inc
Using default input encoding: UTF-8
Loaded 2 password hashes with 10 possible salts (5.0x salt BF penalty) (dynamic=md5($s.$p) [256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=16
Press 'q' or Ctrl-C to abort, almost any other key for status
                 (?)     
0                (?)     
2g 0:00:00:02 DONE (2021-09-07 01:58) 0.7299g/s 415708p/s 4147Kc/s 7888KC/s bilbark..107969
No remaining hashes
Use the "--show --format=dynamic=md5($s.$p)" options to display all of the cracked passwords reliably
Session completed. 

magnumripper added a commit to magnumripper/john that referenced this issue Sep 7, 2021
Since every salt has a copy of the initial salt->list pointer, a special
fixup is needed after removing the first binary in the list in
crk_process_guess().  This was the actual openwall#4517 issue.

Other fixes:
The generated salts written to the salt database lacked some info and the
total number of salts wasn't updated.  From now we copy the whole initial
database struct, avoiding several current and at least some possible future
problems.
Improved the "Remaining xx hashes with yy different salts" output to be
more accurate/informative when this feature is used.
Error messages referred to a non-existing file in a non-existing directory.
Several comments were bogus, eg. referring to code that was long gone.
General code-style fixes (including a couple of barely related, made while
trying to understand the code paths involved).
Add bodges for --show to work with hashes cracked using this feature. For
this to work you need to supply the --regen-lost-salts option with --show
too.
Since we unfortunately give the exact format as one of the parameters to
--regen-lost-salts (a fairly stupid decision made 8 years ago), add code to
automatically pick that format wheneven a --format parameter isn't given,
or complain if it is and they don't match.
Minor updates to doc/Regen-Lost-Salts, eg. dropping references to things
that were deprecated eight years ago.
magnumripper added a commit to magnumripper/john that referenced this issue Sep 8, 2021
Since every salt has a copy of the initial salt->list pointer, a special
fixup is needed after removing the first binary in the list in
crk_process_guess().  This was the actual openwall#4517 issue.

Other fixes:
The generated salts written to the salt database lacked some info and the
total number of salts wasn't updated.  From now we copy the whole initial
database struct, avoiding several current and at least some possible future
problems.
Improved the "Remaining xx hashes with yy different salts" output to be
more accurate/informative when this feature is used - correctly showing
same-salt boost or salt BF penalty.
Error messages referred to a non-existing file in a non-existing directory.
Several comments were bogus, eg. referring to code that was long gone.
General code-style fixes (including a couple of barely related, made while
trying to understand the code paths involved).
Add bodges for --show to work with hashes cracked using this feature. For
this to work you need to supply the --regen-lost-salts option with --show
too.
Since we unfortunately give the exact format as one of the parameters to
--regen-lost-salts (a fairly stupid decision made 8 years ago), add code to
automatically infer that format whenever a --format parameter isn't given,
or complain if it is and they don't match.
Minor updates to doc/Regen-Lost-Salts, eg. dropping references to things
that were deprecated eight years ago.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants