2016-06-10 18:53:03 UTC
Our dmg2john.c and dmg2john.py assume that the lengths of some dmg file
header fields are fixed, even though the actual lengths are encoded in
the header and are propagated into the output "hash". I got a couple of
dmg header v2 files where:
kdf_salt_len = 20
blob_enc_iv_size = 8
encrypted_keyblob_size = 64
However, dmg2john.py blindly assumes blob_enc_iv_size = 32 and
encrypted_keyblob_size = 48. dmg2john.c appears to similarly assume the
former, but not the latter (so it encodes 32 and 64 instead of 8 and 64).
kdf_salt_len appears to be handled correctly by both.
I have no idea whether any such assumptions are also present in the
actual dmg crackers. Either way, we clearly have this bug in dmg2john*,
where they blindly output erroneous "hashes" instead of processing the
input files correctly or reporting an error.
For dmg2john.py, fixing this problem correctly would require changing
the approach it uses. Right now, it parses the entire header with:
v1_header_fmt = '> 48s I I 48s 32s I 296s I 300s I 48s 484s'
v1_header_size = struct.calcsize(v1_header_fmt)
v2_header_fmt = '> 8s I I I I I I I 16s I Q Q 24s I I I I 32s I 32s I I I I I 48s'
v2_header_size = struct.calcsize(v2_header_fmt)
It will need to separately parse the length fields and the actual data.
In my case, the "48s" in v2_header_fmt should become "64s", but it would
probably be wrong to patch it in the v2_header_fmt line, because some
other file could in fact need "48s" or something else.
Dhiru, will you fix this properly, please? Thanks!