Skip to content

dmg2john extracts uncrackable hashes from current DMG files #6028

Description

@AlbertVeli

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

gpg --batch --passphrase '@u:302wbl:50[;FRiFt2' -d cmiyc_2026_challenge_4.tar.xz.pgp > cmiyc_2026_challenge_4.tar.xz
tar xf cmiyc_2026_challenge_4.tar.xz

This produces:

its_not_that_hard.dmg
lDK9QqIzhwk.dmg
start_with_this_one.dmg
wow_its_hot.dmg

Extract the hashes and create wordlist

run/dmg2john *.dmg > dmg.john

The 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

$ run/john -pot:defcon.pot -w:defcon-expanded.lst dmg.john
Warning: detected hash type "dmg", but the string is also recognized as "dmg-opencl"
Use the "--format=dmg-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 4 password hashes with 4 different salts (dmg, Apple DMG [PBKDF2-SHA1 256/256 AVX2 8x 3DES/AES])
Loaded hashes with cost 1 (iteration count) varying from 400000 to 476190
Cost 2 (version) is 2 for all loaded hashes
Will run 12 OpenMP threads
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
0g 0:00:00:46 DONE (2026-08-13 04:03) 0g/s 43.27p/s 173.1c/s 173.1C/s Defcon1944..D3fc0n1900
Session completed

Hans Leininger (hlein) wrote in the post contest discord:

Minga probably knows more details, but IIRC it's bad in a bad way: it will extract a hash from current DMG formats w/o complaint, but what it spits out is not actually crackable. So you'll think you succeeded, but can't crack a DMG with password d3fc0n

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.

Activity

  1. AlbertVeli commented on Aug 13, 2026

    @AlbertVeli
    ContributorAuthor

    If I remember correctly from the post-contest Google meeting, d3fc0n is the password for start_with_this_one.dmg.

  2. AlbertVeli commented on Aug 13, 2026

    @AlbertVeli
    ContributorAuthor

    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=7

  3. kholia commented on Aug 13, 2026

    @kholia
    Member

    Quick 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);
  4. self-assigned this
    on Aug 13, 2026
  5. kholia commented on Aug 13, 2026

    @kholia
    Member

    I have added support for such DMG files in #6029.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions