Repository navigation
dmg2john extracts uncrackable hashes from current DMG files #6028
Description
Activity
If I remember correctly from the post-contest Google meeting, d3fc0n is the password for start_with_this_one.dmg.
It seems like dmgwiz doesn't support the files either.
for f in *.dmg; do target/release/dmgwiz info -p "d3fc0n" $f; done
error: unsupported encryption parameters: unsupported blob encryption parameters algorithm=2147483649 mode=6 padding=7
error: unsupported encryption parameters: unsupported blob encryption parameters algorithm=2147483649 mode=6 padding=7
error: unsupported encryption parameters: unsupported blob encryption parameters algorithm=2147483649 mode=6 padding=7
error: unsupported encryption parameters: unsupported blob encryption parameters algorithm=2147483649 mode=6 padding=7Quick patch to reject the currently unsupported DMG files:
diff --git a/run/dmg2john.py b/run/dmg2john.py index f3a61a0ad..c338bc84c 100755 --- a/run/dmg2john.py +++ b/run/dmg2john.py @@ -111,6 +111,15 @@ def process_file(filename): "is too long!\n" % filename) return + # The $dmg$ format decrypts the key blob as 3DES-CBC with PKCS#7. + if (blob_enc_algorithm != 17 or blob_enc_mode != 6 or + blob_enc_padding != 7): + sys.stderr.write("%s uses unsupported blob encryption parameters " \ + "algorithm=%d mode=%d padding=%d\n" % + (filename, blob_enc_algorithm, blob_enc_mode, + blob_enc_padding)) + return + # read starting chunk(s) fd.seek(dataoffset + int(cno * 4096), 0) chunk1 = fd.read(data_size) diff --git a/src/dmg2john.c b/src/dmg2john.c index 3ec16b755..bdb7a43ce 100644 --- a/src/dmg2john.c +++ b/src/dmg2john.c @@ -342,6 +342,18 @@ static void hash_plugin_parse_hash(char *in_filepath) v2_password_header_byteorder_fix(&v2_password_header); + /* The $dmg$ format decrypts the key blob as 3DES-CBC with PKCS#7. */ + if (v2_password_header.blob_enc_algo != 17 || + v2_password_header.blob_enc_mode != 6 || + v2_password_header.blob_enc_padding != 7) { + fprintf(stderr, "%s uses unsupported blob encryption parameters " + "algorithm=%u mode=%u padding=%u\n", filename, + v2_password_header.blob_enc_algo, + v2_password_header.blob_enc_mode, + v2_password_header.blob_enc_padding); + goto bailout; + } + // Allocate the keyblob memory if (v2_password_header.keyblobsize > 1024) { fprintf(stderr, "Unusual keyblobsize found in %s\n", filename);
I have added support for such DMG files in #6029.
During the 2026 Crack Me If You Can contest, challenge 4 contained four password-protected DMG files. dmg2john extracts hashes from all four without reporting an error, but the resulting hashes cannot be cracked even when the correct password is included in the wordlist.
Tested with bleeding-jumbo at commit 9a336d8 (latest as of this writing).
Challenge files can be downloaded from: https://contest-2026.korelogic.com/downloads/
Extract challenge 4
This produces:
Extract the hashes and create wordlist
run/dmg2john *.dmg > dmg.johnThe password d3fc0n is known to be correct for at least one of these DMGs. Create a small wordlist containing it and variants:
printf 'defcon\nd3fc0n\n' > defcon.lst
run/john --stdout -w:defcon.lst -rule:single | run/unique defcon-expanded.lst
Verify d3fc0n is in the expanded list
grep -x d3fc0n defcon-expanded.lst
Run john
Hans Leininger (hlein) wrote in the post contest discord:
Same results with dmg2john.py
Either these DMG formats should be supported correctly, or dmg2john should detect unsupported/incompatible DMG formats and report an error instead of silently producing uncrackable hashes.