From 17c2b01b294d91042b617cfdb4f28bd75554904f Mon Sep 17 00:00:00 2001 From: Dhiru Kholia Date: Wed, 22 Aug 2012 21:10:41 +0530 Subject: [PATCH] Add support for cracking DMG files --- src/dmg2john.c | 173 +++++++++++++++++++++++ src/dmg_fmt_plug.c | 397 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 570 insertions(+) create mode 100644 src/dmg2john.c create mode 100644 src/dmg_fmt_plug.c diff --git a/src/dmg2john.c b/src/dmg2john.c new file mode 100644 index 0000000..b095203 --- /dev/null +++ b/src/dmg2john.c @@ -0,0 +1,173 @@ +/* Modified by Dhiru Kholia for JtR in August, 2012 + * + * dmg.c + * + * hashkill - a hash cracking tool + * Copyright (C) 2010 Milen Rangelov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gladman_fileenc.h" +#include "filevault.h" + +#define ntohll(x) (((uint64_t) ntohl((x) >> 32)) | (((uint64_t) ntohl((uint32_t) ((x) & 0xFFFFFFFF))) << 32)) + +static int chunk_size; +static int headerver; +static cencrypted_v1_header header; +static cencrypted_v2_pwheader header2; + +static void header_byteorder_fix(cencrypted_v1_header * hdr) +{ + hdr->kdf_iteration_count = htonl(hdr->kdf_iteration_count); + hdr->kdf_salt_len = htonl(hdr->kdf_salt_len); + hdr->len_wrapped_aes_key = htonl(hdr->len_wrapped_aes_key); + hdr->len_hmac_sha1_key = htonl(hdr->len_hmac_sha1_key); + hdr->len_integrity_key = htonl(hdr->len_integrity_key); +} + +static void header2_byteorder_fix(cencrypted_v2_pwheader * pwhdr) +{ + pwhdr->blocksize = ntohl(pwhdr->blocksize); + pwhdr->datasize = ntohll(pwhdr->datasize); + pwhdr->dataoffset = ntohll(pwhdr->dataoffset); + pwhdr->kdf_algorithm = ntohl(pwhdr->kdf_algorithm); + pwhdr->kdf_prng_algorithm = ntohl(pwhdr->kdf_prng_algorithm); + pwhdr->kdf_iteration_count = ntohl(pwhdr->kdf_iteration_count); + pwhdr->kdf_salt_len = ntohl(pwhdr->kdf_salt_len); + pwhdr->blob_enc_iv_size = ntohl(pwhdr->blob_enc_iv_size); + pwhdr->blob_enc_key_bits = ntohl(pwhdr->blob_enc_key_bits); + pwhdr->blob_enc_algorithm = ntohl(pwhdr->blob_enc_algorithm); + pwhdr->blob_enc_padding = ntohl(pwhdr->blob_enc_padding); + pwhdr->blob_enc_mode = ntohl(pwhdr->blob_enc_mode); + pwhdr->encrypted_keyblob_size = ntohl(pwhdr->encrypted_keyblob_size); +} + +static void print_hex(unsigned char *str, int len) +{ + int i; + for (i = 0; i < len; ++i) + printf("%02x", str[i]); +} + +static void hash_plugin_parse_hash(char *filename) +{ + int fd; + char buf8[8]; + fd = open(filename, O_RDONLY); + int cno; + int data_size; + unsigned char *chunk; + if (fd < 0) { + fprintf(stderr, "Can't open file: %s\n", filename); + return; + } + if (read(fd, buf8, 8) <= 0) { + fprintf(stderr, "File %s is not a DMG file!\n", filename); + return; + } + if (strncmp(buf8, "encrcdsa", 8) == 0) { + headerver = 2; + } + + else { + lseek(fd, -8, SEEK_END); + if (read(fd, buf8, 8) <= 0) { + fprintf(stderr, "File %s is not a DMG file!\n", filename); + return; + } + if (strncmp(buf8, "cdsaencr", 8) == 0) { + headerver = 1; + } + } + if (headerver == 0) { + fprintf(stderr, "File %s is not a DMG file!\n", filename); + return; + } + // fprintf(stderr, "Header version %d detected\n", headerver); + if (headerver == 1) { + lseek(fd, -sizeof(cencrypted_v1_header), SEEK_END); + if (read(fd, &header, sizeof(cencrypted_v1_header)) < 1) { + fprintf(stderr, "File %s is not a DMG file!\n", filename); + return; + } + header_byteorder_fix(&header); + } + + else { + lseek(fd, 0, SEEK_SET); + if (read(fd, &header2, sizeof(cencrypted_v2_pwheader)) < 1) { + fprintf(stderr, "File %s is not a DMG file!\n", filename); + return; + } + header2_byteorder_fix(&header2); + + chunk_size = header2.blocksize; + lseek(fd, header2.dataoffset, SEEK_SET); + cno = ceil(header2.datasize / 4096.0) - 2; + chunk = (unsigned char*)malloc(header2.datasize); + data_size = header2.datasize - cno * 4096; + lseek(fd, header2.dataoffset, SEEK_SET); + read(fd, chunk, header2.datasize); + } + close(fd); + if (headerver == 1) { + printf("%s:$dmg$%d*%d*", filename, headerver, header.kdf_salt_len); + print_hex(header.kdf_salt, header.kdf_salt_len); + printf("*%d*", header.len_wrapped_aes_key); + print_hex(header.wrapped_aes_key, header.len_wrapped_aes_key); + printf("*%d*", header.len_hmac_sha1_key); + print_hex(header.wrapped_hmac_sha1_key, header.len_hmac_sha1_key); + printf("\n"); + } + else { + printf("%s:$dmg$%d*%d*", filename, headerver, header2.kdf_salt_len); + print_hex(header2.kdf_salt, header2.kdf_salt_len); + printf("*32*"); + print_hex(header2.blob_enc_iv, 32); + printf("*%d*", header2.encrypted_keyblob_size); + print_hex(header2.encrypted_keyblob, header2.encrypted_keyblob_size); + printf("*%d*%d*", cno, data_size); + print_hex(chunk + cno * 4096, data_size); + printf("\n"); + } +} + +int main(int argc, char **argv) +{ + int i; + + if (argc < 2) { + puts("Usage: dmg2john [DMG files]"); + return -1; + } + for (i = 1; i < argc; i++) + hash_plugin_parse_hash(argv[i]); + + return 0; +} diff --git a/src/dmg_fmt_plug.c b/src/dmg_fmt_plug.c new file mode 100644 index 0000000..4568b59 --- /dev/null +++ b/src/dmg_fmt_plug.c @@ -0,0 +1,397 @@ +/* DMG cracker patch for JtR. Hacked together during August of 2012 + * by Dhiru Kholia + * + * This software is Copyright © 2011, Dhiru Kholia + * and is based on "dmg.c" from + * + * hashkill - a hash cracking tool + * Copyright (C) 2010 Milen Rangelov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * BUGS: + * + * This patch does not work for "testimage.AES-256.64k.header_v2.dmg" + * from VileFault sample set */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "filevault.h" +#include "arch.h" +#include "misc.h" +#include "params.h" +#include "common.h" +#include "formats.h" +#include "gladman_fileenc.h" +#ifdef _OPENMP +#include +#define OMP_SCALE 64 +#endif + +#define FORMAT_LABEL "dmg" +#define FORMAT_NAME "Apple DMG PBKDF2-HMAC-SHA-1 3DES / AES" +#define ALGORITHM_NAME "32/" ARCH_BITS_STR +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 +#define PLAINTEXT_LENGTH 32 +#define BINARY_SIZE 2 +#define SALT_SIZE sizeof(struct custom_salt) +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +#if defined (_OPENMP) +static int omp_t = 1; +#endif +static char (*saved_key)[PLAINTEXT_LENGTH + 1]; +static int any_cracked, *cracked; +static size_t cracked_size; + +static struct custom_salt { + unsigned int saltlen; + unsigned char salt[20]; + unsigned int ivlen; + unsigned char iv[32]; + int headerver; + unsigned char chunk[8192]; + uint32_t encrypted_keyblob_size; + uint8_t encrypted_keyblob[0x30]; + unsigned int len_wrapped_aes_key; + unsigned char wrapped_aes_key[296]; + unsigned int len_hmac_sha1_key; + unsigned char wrapped_hmac_sha1_key[300]; + int cno; + int data_size; +} *cur_salt; + +#ifdef DEBUG +static void print_hex(unsigned char *str, int len) +{ + int i; + for (i = 0; i < len; ++i) + printf("%02x", str[i]); + printf("\n"); +} +#endif + +static struct fmt_tests dmg_tests[] = { + {"$dmg$1*20*f615ec6c463799eccc6a2dfbedf12c6bdc422a2a*56*a595f4a81a490e7aa6378034661da57a424f922c971d3db3f856f8d54b0784bcc5d7182905c4237153c5d250b8aee1d26410b1dca7b1cb73*48*74a060efbaf2c79d5523219d8162c425befbb2094fb46e7ffaedc7cd4f192e6f0c47d8aa91e0a3201346725d3ddadfff", "vilefault"}, + {"$dmg$1*20*9c82b419bdac1b3e6b71f8a6b99a7501f34b6950*40*5da479e292e0acf67a9fa3e24d0a767cae2f645ff63836665068637188f4b80295de79aabdbc2536*48*9b136165ee73418631ccf28d5e77073788ae921df596649a7a7789585db0f13f446d5927967e2ede20ce8a4f5389185d", "vilefault"}, + {"$dmg$2*20*839730be2331c69df4f729ffe8a10c26653bea94*32*1f24e25712c2d70d000000000000000000000000000000000000000000000000*48*3231e20aa642889a7e087cb87c84ba1cd52864007cfea677796a6f52e16b2609696dde9230aeb5603aeb1f70f6701be6*14*8192*75884a049d2b7a40c14002ab6e511bf3c73ca79a2bb8285a3d2ac1d5b9b0cbf92d4a483fb762bae8485dc3fc9cd7a54141da2b74a86ea833d253d56f52eecb9dd4d40b9f846690378cb8a5db74fbc6d756ef9fcdbb5d21805ed43a7fb45d6caf6b3d2564f4a7760030aad69ed9e56789e8b2699bebfaac3cd73130fae1d8ef7f003e765e86eb84e990f3c24780022fdff3ba283ece4fa8d31716e5cb1ea22e408431eeb2cda1460217efda86461e940cb10ae602a84ddd22be53064e66c0973a04405ff17afa020b24f1bb4ce42750b28cf4e98c4f542576e712f3c2fe0a0539a411290f65ca763a94d865fc24b1beeefbb6b055db453da38e62bc383e74b188b86c54b62f589334de8ce3ab2e4643f76eb4db95bfc088bea8c4e88cfccd19b89b818fb698982f73df634c8a8148e4c8d3ec2dab02aabcf48ec0a78686fe0b4f5e589a067d6c54f0732e559cf9db5b4ae1f0468f5681226d3b03002cb6ec528b96470f1d1aee5d3b51b4c5f45a2702830ea35056e02279e76fdd30b3ac174cd91b65fd6a26a192f6e632b0fae660d0861059a62bc512f610f4974c22993bbafa364fd2e8eb53d07244d165f990c876320d99070fbfa6fe7e0ca42c0ef2f17205ca7196376d4026a8a93fa83a99cd3b6cde354ed3122dfc07ffef91c24f2036b0d83467e120b85a92fa04120cc8f7af3196adb6420f519c610983d163964b0cbd048adfb89266d9ccf9845cd17ed04accff9d106b7bfffefb365e97357fdb9ab2d0956411c0c73bdf235a9ea4b50962c8f258583899ff2c0bad6602e8a3c14f3c870fa14686d15aa17f5cfd1ddeecc7b061cb5c00db7d198d083a690ecee97a1b4b0251349beab744c4bcb53a4c1702d1094f6591ee5ae15a29271ee3d3d22f0f833219c3676236c9e9620a206ab6ab08fe5fc663f4f2ccfdae6e34adc68e59fcba5363f44cbc5d8345f184ccb38d52bc2bbe6ad996c3d4316ce644698bba6044209d108c698c3d18f4b64161651224cb015052d2e9bee0079b779d77b6623e9669c4ff99988bc612c4099f6b8bc9719444cecbc5f87bf9ca6dc30f3b346c3cf20cc342cd4d156ed67c8be0f1801c3e672bfdf2fb9e6c6f1ef3570d059405a8a0c5bcfcd70f7bfc1d2417e3ca205be70a5ffc9b4d1d123ff64cf72b20df25e9861e1da57fd1311451e542c25100c19d1d70bba2c26752e4cf1c59a6373fceceebf2b4c392a45e2cc7151f4cc1c7292720b5f0716cf7ea752a8a44cfcb7f638c5387a410efbfae90598f2d99cc79baa298e30076d5ac8a2094dc14d81953c09fca8b41f88cbca2274158b93fe5a151b93bec1fdabe1a6c67807d5f9d46b2a19ba85f9540cfb54656fe473216ee1922046c5b6cd08b325e0c25a420765a61e5f7a266c9e0ea1148f0e62ec65736d4cacef77940a0eb24e93b7b656e3b591f5827e78b577b628da26c1e5bd7544dd439d15ca21a3fbe96d3833ab1bddbb03beb8f0fe39517958b7bf43afdbc68b5061b41145e151d228bb5e5220b31a86878be40060839855db438368e40dd6b8d534c5c39009455c0a783455b41b572f2864eed60e5dad80979b97efd6dd08549c154b76f748101396847efd56a97b82cf62a25e26ecaebfa35d545cdf886ecc22460cc0e2983b9da14ac41dd1e1dead58a2c29a85f6bc900268d755d1158939470c4793359b50da19addd3d8f722c0a889ebd8dc69bd955b524bbe452cc98834613ea48d7a73a9b93820c0ba718cf664d82a1745451a204a2845d4e2a846f0f18923ad0315896b1c1ac1942fbdcba119ceed9e02b0e707b28feaba44bac94888ba1a31670cdce6348d58d2072eb13ee805d569815fb28749c392d11eb06d8b1746ba8eef3313072fdb4685f1401717933fd18edbc99e3d89d08a4c7798bc1d724d6bca02a31642ca0ac6223884580c0be8f6508a6650b783a9ef24de3713f65fadcb2da6d68c4bbbdc216ff91ea7bd24bd7365b91087c14edf70dbd4eceb2676797ead7fbedae77a0add9d22a515e2a79d075958d8fb87aa62700c62df007abaa3a5e002403205fe04edaa4aac3da6d08ad9ba909974e9091148208db90f330b2c2c702521d4b1b32acc4fe6b7ffd9f96fdca05b6c404afcc789fb9ad8c52063fc0f9b9cb4116ee11f07aa17dff57b889a4f4abaedc51a07481c1e954d78ead32c6e808d3eafe7cfa9d2d4ab4886abcd2f64ba2df2d8d507cabfa8d01f785409d71896461adaeb4e34d18f9b2fa38779f0932c27ba2f3f75ece12f6eaf7a0d728dc02e97cd44ff175b592b8234c3e3b5491726c58dcf0a1b77698cd38d861fcd549aa793f8d2b58d6afd1d9b7bb96c8936c960eaa7072c00e69f68f948ee24494b8152bd8e5d6923c8eb26023dc660d202e41663888a8e8550092b5e1610452c79069b3cab41a2e7459dc0d361ded09c9f1589999623f6deacf276eb72996a355e4f7dc19a5217e9dcb2d6a3e4679bed9f980a5dc8f24a1c5f4eef00d706566e12ac8deeee964ab9501be5e57e326a6fcb794e4f4fe14922704206a343724913ca2e1d26e3d83cf994cb7aaaf9a916ea6eaa06987a9822c5a8e556b16ad72d5f5640b3490d6b0f290f9f2db7c3ead435e534406dee40366efb98f0b53930a83ff9bad177b84343d204a1083801f1d68b3aff78ec4246f670f924969e4608b419ea9f5aafec40d902492f62844d9a83d65f38af2531b875b964abc781b3537c708fe65f70a11552990447bf6db287412367ca918a39d9e2b2e228451807b01174afc33f5f67d45f9c765015da6abd318c980fc8bcba60ccd5193e7a8caa54193aa83bff7b77725be99780da88b3209a3cec620c17f979fb16e640473b0d98a2f492702ab99f2f0f83bbdcabc2a6dc4986476f420f112ffbc7bddac8cffe59e82ff558151b9160e2f99bf37a05654253321591ef31d01b32b8d69297b3bd57f127e9f574fd472b6d29b6e9a0e1fd43252bc1f1b2c8c959f3f4d80177b4fd6a77dde8fcbaf1eabcd5e7f6d38630f35defc161ba7432cc9af6bc73baabcb343c469ab18e4cf88eee21e49311b4f20077bd6e30705338f047a9c7bbdbe4dfa6d7be3a827c92823a3c8f36909f9e4df4dd91426b75ac6b5d953357929b0bcd91ebd24e651a855755edca82c4664d3c89fca6001ba88688e5ec8d5e5c3fb145b963b29424192530601d74e3b815be85ca44640ca89c57ec4ac7084639b82e23f065ac561779c040cbfe63310ec846db02873203feccc3f88a28fa78d8d567905abc9f8f561b4a29ec5c380849ada42100c15efd3d73fc203e63a315cc27b82f62c4ca0df9ea213dbf7eb39552fcc38edfba0ce7e25dd097bfad5224369f1d2a175ab88ee5a3371daece3342e99c60cde76a1ff5dc7e5ebaa7e0fb59d4d088cfbe7704126b2697d62d7b82289a35ea778ea4ca347410513513084f1fa971686724761f711a916ae1e92402ff3d52f948fdbd9c1d961c6ad6923c8ae9cf3a4eae7a9369daa5cbdadfc786e873b90ed1e8f5933ebd011081ae7ea236c11f0c53e00c1c0f9206f91e6954123b5caa08c7615a787c1661dc17f297c8ed2ff6c90dfdd9a262ab5e9a4489d6ed7ac032f72bcbbc2248e7f1675e2b2da0bf85caf89921fcd8e78403f11a28970f673ec7adbea798b3eff87fec642ef77c15b3f3d19dfeb74d1ef6a38ab938692207133aaeaf722aec4f6082a4cd742bd37fba0f1f83f01cd2fad6a169c4716940f7d74b8f29001f406de5897a5e5d813b995df132cc57a5d9bdecdad9024dff7dee8b89189d35085a70bba2e5e0a8c1c71cc593238f3acbd1337b2cc5a8647ce6bbd669eb939279d3b964d661112752bd7fb877c4c6ccb5ef72ff5446410286fc69347841c5595a3408e0c73fed8984d0c0fdd2544a168ccfe41386702f6ab7b3675a78b57f9782f23e0471e6dceb176dc9eb871ddd92dc0b86b2a11293523189c75019200a45213f0cbd86823f65f28cbe6569a58512dd469431322b7ca5b9b8ca57e56a139dc4788ffbac10fb57441f2435584651fa572450a4719c8c9b4a322f3aaedd3693a55820c725b63096d3f211d830d39aa89be83d59b13145dea9231266ef6b1eb1fdef31203922308cff81b166426d662989a350ec712dba14ced58df7dda0d0fad05ad8d9c6b247307d481f79e6a3cffdb2ab9b21a8208d6d7faa72b6f22a505d2b950884474862f6f67effc81c6292f3550c4e8852c39c52d952648b256e961d478c0c6979300c5188c490ce5c1e34ff6dcfca63c0f0571ea616651ef6f9781f2d355dbca208e56948ab9e26c5d2d3f8509952bba3e93241837b11a89caef6c956c9354ac10425a6d8d4e82bd5d7411d18655393d7c542a7c914a5ea6aba717a226e0f51200cc949f38c703f4f6ce452cc1d7d6ee8acf26d34f74981f6850b11610c11d1c5e6689c1b6fcd6b6e997ea145851c6655560c33dcf5ed7315578263c39fe6a838c5de867f1b3cd482c0206f56ebea0617ae25b3ca8d7e13849bb2b58ea4e21409762d549636bb7cf5ec32d3216d827d94cba1f36e7632e3a43b3203fc596cdbf879d1aaee90804fa0cbf46d08ff4c40aff8fb2b46f7ba8ce21d17c2d3d025b67702054e9d76716fe7b5c9d2f43036d86e6a17924d2f160f91110ed1f3364a1177aa6193baf59878ec84f450914faad409618bf25cae17ba5545abd33833ebf408990fa4236d322089aa42eebea965e59456250fa14bdb61a32be8d70372891a83e7bf298168c5431e0b326229c36c667217bedbf64e3a07019534a087e84cd1a9cf35a889d9e65a7be63e8d638373774148e127b328734963437e7f00253d2fcce7bc0d798c09326ccd4f379f8a29f2d308ab2fece6fcadd653b1a3ba53a078e51a1a87e8dc03c5c118444d82d9166c0c4c1bfbe8ee09be6f8cd497a20132d4b6e1edd13683b363dc6587de2f11cdd51674ebdaafc41654d639b6cdbcc040f5889efb1f64e1b873442493ebffd8f867f0e1ba2cc629bc5239ded578336a9e88ee8b2d1b71f6d9303cbfb8a35e4015d2f9ec25eb4618c2ac17166e8964b68a66e60cb7b464e36a2251243a218ee542dac96062ec7db751273435dca23bf3e8aaea895ef1d6f6bdc98fcb6a9e0658dbe734450682cd1a3fe16161a9fbd035270fc86684971e20f1f1869546e1b77a481774c9449ac6499f376bc3c0f0efa589abe3bf676fb385ea50618c681eff6e5359678f078292da285c4b5e66d5ddb43499abc3558490aca6481299c351c6b053739d0065c187f59767e7de24f1b7bcd2d80d0ab2e7c789a9f5172a8411a88d2c69d8f9d2744ca7e42ba8478648df29919c23c0f4cf14e2428c792f2d8abae1073b97d86c2d5cf2e5beebc7fdfc449ec3804a81199d6c4f24d9b040bd1feeaf141b7eea626c1fa812e499b74e86dded2641ce3e11a04a35c8b8831a4de563c3614b4048eaa656d8dea460d2c46f6d748be434718e9f54934804756fad07d2a8ace694bccbd7bf2e33c09199a22a98726d2e1a690b2a9c33e39c8746d8125d93f675c571247b0a060114eff4c32231898a05e3ced4721edaaee9ebab9b46692c65f086d9fcd34b86a499685010ae0f4423625263d0a2a62672624662a6613bd4235b7402573af1b0571c364f7c14e277b84e4a102b1055a1456b912431f9ce9e875056f8b48345ab09bf06b3de6126fae32e2bd61d2fdea29a2f3cb46d963fa40694c02657352b9b9918bc50fd7e26584e51ab5e4bbcdcbc18b9bc17d3efc5935ae5077a269fb8e912dfc91a2c287686590c3e2671f6d29365c044fac2c077fb5ff280b0a4d69eee3b9538b4c8a029a3360902ee8291ca9f1088074f307392b70a7a43ceaa07c47d175b286c052e2412237da3f6acb1eb6b1ec386dbcdf5b49d2391615788f401ec234b58b112d296b389ede47243c01a1a6d18ca5dd3f2646d483b97e41370faa1c023118a1d2006694debebe35046f6e5852952bb520c9991cf9dfdcf89e51fe29d3cdad6f1091fc7c450782f06b09cb8aed1e1f95221af7ad369e49ed672fbbf2d255549d0fc0398dc6b4d37d038a8dc9e8d9b4d6faacf3c5fd10663107cec0e171ea6e1c26eb8a1534646e0813ab0fb449d15b4865eb2e9914d404d06c1e284f66e39d09e99eaf7c2f36997ac6ecb9197f8ea7fbdf7da38e427dd5179ef265f1471a096fd24d8ea2a2ec3b820c54356cd912f069accfd370ca945e60c72b5d479b15d52a5c3c4423c73f4ec06d9201ddbfdaac2e304b1408674d40c203ed48fbf4b126904900349228b28fe262539c9a12270632f28241198381c6e7174d275227c99178ef4942655ec95acbc19a3b96fd1e07b5e0e91488c979e7e25be5ea733bc3171b2874801157c83a6de754ecd05cd78d6d2846e7ce19f641bdb53075dca078ad0ddfa871c16e47da96d007b5e2b2854d151dccfad21875fcd12df56dee7f4aed6a54fa248ba2721ab2f58c1157c85a3df8486f99295f2c9b8e8cd7a65145b69ca93d0ac4fe328e31c07bc1d0af2db886266def575d74be200ec9a4ccb0213743eace8d7d39f810e3877876082238d72c375a5cbdc4d7de36c2ad90904a173df80195cff86f19a0904d18a1f8a92cc4779e5997dacba58770c5091dab5b832dfaab2d0fd102b99e3b8a799ac6e7357b294a31db5f9bc3d04036a4a6e18dd47dc88b0f07e1c4271e5106f329731ce4dea9f56f6d63beddad788d7eeb955589a13990cbe3454b07f63477642613bd77f3bc5d024dbc5c55a0c7426ac7cfe63dd2da9f0d5a7e816dfe5856b646b648c302c16b50296882c62334c9b8e56ba6dab63a9c787fa153d04e5e64503c6bbb9bfc8957d2fa607ecdd3714123dd52b6f9c1a3a73f649dfe67fd7195857955cb8c5470a9f363116cbb580b793033280dfb63ae47b384e6aed677251b63a7a27447f37e9817f10f27c4a0560ef34c0255617cfb90769aea2e5971077cc89022f8a44493d5157ab2962946c7fe600a24f002cfc6108d345469a65f2f29b55e4da3f4c767324f173a11567ccc401628f2934989b29875ededce223de3134b7e99384f94436bed28329daff8da5690984b491d43f14d86d5a5e783545442f913dfa39f25f6360d2143fbe4c7e234a40f65b2c48ff5835c3fab67a92d0adbac9e63993db052a832b1c7b6045a495b82ed0d7f1068ec96fe1519493f7376a9f9f331f6ae89420fd1b523278df3e78c7b957f599767057113d5a1895801f1fff1b7021fde8360c4fc1ec8165132244b680645df7a1c0673728ca6323379739905856537091dba18f762b7be6f5f7e95212c402b005d73dce6a7775e90093f927edcf0d9ca24d04809f953ece372414d5f987ec2ae030dbb547db5ec17bef47dcb097fcd2fdd873eb93a99e2209425d4fbb589530fe41bdb5daf8ad8f83e48557a01d2ff6b658368e39bc8324cc2756160cdf56b8d7fe231aa03e82bf0b3f55eeaba71133a6bbf72342727a52ff7d158992895c61c0bab4cfe42ba5e4d5f239ef5efb6433dff84a02e2a5f12bfc35c1062e4103a3f8fdd1c5be28bc83725023c8a72d2cf5103a7c97a23b2d9903a1870726ad2bbaef7b7a6dac3e36c1b92769cb3f43eea1faf95c53db0cda2a8bea38efc1dd11695bb5de4baf583b175a32d49f98c37510e9e56f3d9e10bb4aff163abc91a36f24fb38d33d87fb4299d5ceb5144c69cb741b03d35436002d7740c38753e284a808a77cc1d4ff9e63b9ece720e778497c25b46ccf757449cb3b3fa8e5bb6d5a9f6eab58c97e9469cc6192b7b31362453faac839327067f41f25ff34c2cd40e9fee3a0b8133f266407587ac40db20e7d7d397e90558e54250111f540a44a70d427497b5a06c8ef87f6bba0082e00d42adc7eb38e890dcf5cd426c1bc2b4c781b07670382aa0d13e227e05c1987d3cd0241b5ad78387e19dfe4804189dd8a10cab05c79409b9414a6a384cfaadbefcbe8e3521fcbcaf52d92dcf1611ba3a824b576051aa24f42cadd7b7e9841375646740f2a6271d81d2d5f4819ae6a5d3f1feb6f7923f4252872c3a2709a8b8556b3977af8c4423bdbcf66ade1b3c4303539e06957e8930aea8ff70d6a202407aa44c6c8dab0232a33ff3f3ee9f61ed664bfadde8d294022da21b10e0aee583379d8dcdc078639cf3a1ee18d6ee1740bf1b917ff56070bf807b90d5a19f37a5c31214c6a19532f364d463595262ca057f5865f0d55636ce080acfd4e303f03372af014a3c32d2efec8f7f6cd6c825e5edf309ed16008e50aafa2584804c1897f6433e350cd91e155ac786dd9c3deb22a39d69e85331086842f32ba7cb6b4d4f13e08d90acaff24315020f7efb2b74214b14e840d739378afadcb06d45e7bcc17f2a03ed54d0da71d865508900334386ab96e11b88d2811c84539e4e2a93aa27d66620500789bb4d595a8b2e5972b1805d88af2b722e1e9b8aef10ca3dcf5ddbf3d20a6f101bf8f8a8cad825946dbf0c64193689f461bc0c62d138f902575ed601e26184a10ed9df17ad4be7c9672147c0158f132452ea502948a749b474cd0a63ae5cf942609e4864985b4060239d0cee6c78ce4dfdf5750b51ffbd5ee920967f5dcc52df6771e286eb83dac1c576f1a073687411cef3701ce6de66ed17bfe0fa5f03c63f96fb40ad70b478aae1e16efe22cb9e8c2aa57d5498803d35fde7f920b32ec686e6091a9ba6eb91fdd17b3302b760d084bda32244f704e14af619a5c9e72bd14c4e69f51177a26174c16d2e3eac934f184d460df5640fd84c3d3dbbc6785c249a501203374c0d58852d52c4c64a6d70ead2af1bca1d61f6f4cd00c3892565e085d3e603a0586d176f478062b092b205807fe7438a065ae7dbcb14f69c92cae4000dbd6804bf4eabf112813ff0599a29b1fd8bcf9d0ba7d9b14e40e38826b48204d8c0a50fd804167c88056cfe77e7a75ac36b5bd049571639b3f02a7e973abfaff1327080630a4bbaf6a096005ca2ccd54f076f2c3311e6e7b48bafbc9de38d01c8a01ee41d25ff0f775a2db4e34566e377683bad9a133482ab87907769bd783bd170b616d48974ad332e3defe94a2e7d6eccfb4cc43cad93b53c476e7795a087fe58cc074b591315daceee3c02af54d9beac8162b70dd9863bcd7702b7c8c72022856f78b2d249cacaea6c1dbf1317ca9e35664c518bf4155501ae77ecc3f47be6e7151c4d5fe56b893c69f1f939cdfd2b68830d9ea47a89fa7b3d4f620e0909d5a97f2637e2eaf223f25fb5ce7949e3ceb87d93db628872fc469f58a749e8b4841798ef505ef2712a3ba713386dc56b83e504c3d24d2ae8200698f9b3eca8d7971f7b82dbd5df6deb34865e2e6336fcd2fc3ff00bf9c8d04992f012dc9473e347ac05aff1040f010b1683c10dcd0bb49b7b5883ceb6c0bee4bd2ea6d275f884a37fc7151245274f208a457f4bcf180d793de68f09c7b03e7e430dd34e553362f91c4e721926eafd54d6c8464082d2d4a4c5b4b44495ddb06290f01913e68c7cd95963242df31741eae89eec41d0af689518ae335aae42c60041154356ce475ba0bc7f6c5ec798cd7c493aeac5e08d7ef554dc23832161a615a6b902e1d4f7bd076f3bf045360cdb73c3b2d7c158b74d2b718b95189225a0824a38836d1d4dbc5a2861e62f8a8c2723cbf1fe8951860f0cf7b4c6bc4c307cca509435e077f3947b8fcbb8ba1252b89d61b69b0328a2b1c31255c2c9df670bc244af42599cb5982878fa363627b321302255f2a20e04b70e8f4f63638af83a98ba40c55ecc46230798224de084d2cc203841d91c4f049c9b0a98535f3f905bb80b24679de883470c8225af80361031354483d879f98b78cdc5aeb07b371fea8355d146f9bbe16c9178f3d83ed63e2812048a386ef85d6c35ad696936a008a524f358ec8a2e40081c3c50b73fcdc6199f59e14b6ee213a8161f675d5938ce72a848ba9e7ed930198d9ae6c43dd86d94d88c5312be17b9dc590072e382607390e247869674ff446e8c37d89b7276aa61b5ebeb0ab18f500389a326341ee13283965dd4cce69b666d2c114372cb0e5b5d9921cfdb5e12aea0d95ec0a73c8d07b3b3e0dd8d159d323feb4bdaf6ea184bc2fbed75e7cc13bde26aa597ea7eaf0e37aa4be069c2c629af7debd8692befbf74d6c9939165e3238d8b2b573001ce957942b199e5c57935ecf5ae0c3b161b96f1f637605bc29bf5230fc65524041d9970e9b4bd6e7469e0c0bfb62e672b30a7094b014c27a06e3982d83a951ea4207a4d7b38eb155259b847ecba4675c3f82c48343a07e2d5fe16d3189c8dc0f4bb1fe2ca4abce4638a4462f0dd79d69c240eeac8ee4bea297bc1bd5683ca97a352712bb4461fd507f9125f895fc7ca8fc76c7f78207224d0fd142669137ccbac0f023fe1700eef77abc804e9b9da27ad5c3a767202a0d0a36f8fe86e2a8ac5f30303c39fad8b65a206239b881910f9d904f96edae31e4befce7822a7399ad06355bc3c7198eb1a4b2c7c8b4c92a604dfa4905109c35edb62dd3c817cbf5261f5069bccbcf98da9ee5ea192151237b31131953509157f833bb1b482cd011c361d768347b2d0da11b1dc43b392d609f0c4806d7325e92f9d76ecd278fcfb9d91e9993addffa55d66acf9211b7cdcf28c73bd4e7cf83a869532c90f9880bb963cec69cf40e117b3fdf9c0c5c9d6570a2458aa9d14716ecb8b6642a4cb1fe0fbcf8298ad0db3c676b9836910658f03bd47ded56ed210cb1e2f1088c87f4e225faabf29e2d450468ff6614f282e15b4a6fbcc9463a16f802d3ba071fa5b009403478f1088ca8a8d9eded648be7394aa6bb3590c0725ec87fdcc53c4d2afea49ba11f9f2b3231c912bdd9431ad941a7d89f70d8e1669e90553b047b5f4a033437fe3b84c05105227efb5390e6e99b597fa1c35a1940f513ee8aaef9485d1ffdf7ce94fd34dfccfa8f178dc113c32082e0345f6d39294ef283b6f9a566a87b1122e744118e643cd6a2ecf14e47d68254d26942666fcf957586497c72c9e5814ab3371fe4b0f9a7fa1e5d9629d0dfe9e93fb388865a599076e7ba983365fb3bf574d335787416c099c545feeea69e3069d841b62e4db9833e6865e24cda78e2bc46ee83ad5d79bee507c44007200e64b5d1329930bd658e6f051cdefdf758e5b023650c2abda7a6827ca394c086057c617dfa8c161ea1f953446d8e0d5f6d5c76bedde8d596d1641a973e2b53bddb8f7bfcfbd0fbe4883f4d6d4e6f930e51d47ccc40148e6ed1b409705e9a777f1bf86af2621cb1f04ba160a5faad78a0949032e9dd7e34bbe6b2fa1c478a990d3b7c474a2f81af7f7246bdcc669df005adf397cef71869237c53126d1301ceab14011a529d4897cb00f7d93f35031facdcfda8110b9fb5d55a057ac9087a9cc8f1034e03f79a806db8a8e726e8afbfcb2c7c39d3315ecad3a2e542d94753b88717b7791c66c47a45f499885f6c096cb1093d9dd6082ba8eb2132e4a80e22ee309b7f74af55530e190d73315023fe4b52fca855a06fd111fbe1125910f4ace6dcf228447c007cf82fc50993de0202d28aed32ae795d2d75ba8c975b78c657af", "vilefault"}, + {"$dmg$2*20*186673f316ce762e8f2b2595b3e8ea204aef584e*32*df036556654b76eb000000000000000000000000000000000000000000000000*48*71793cfc457320157f12b1351051f60e59fc80a728f82f0156cc8b3f20f75bfb4289c65e6c8c21589f3dc6187540551a*2*5953*3c25089e22f54dfa868b7460f43185a32b6988681952eca4a493ff4699e2340f8cccd06ba2df28334dd01b83f8bafa3754b7afce8f859ffaf64d33950a817d5ffa9671894f71d6ef35aefd00d237f7f8f413b8b8424db42e6fe7bf503d1d4222d77d5c3c2a16f26a1e15d7797cedd59fbeb45f70ff7731cf8be628895f13cc2937f82c92e0d5c6b6ee0214c668ad1ee4f41501dca668af0f83ef252bd6b6444f9028f12ce15134fcd8610426b5a6a75ac25fa938f93280143b5c991a683fb008a08e133a962dd4e3aa9ddb57e72955e3a840c3599b84d874d61cff4236fb487e2a344ee3311d30a531a20ec800ec591607edb97599b297ac67e173a4f7d98ce2d73b66c37659bc75becb65b799f0a1642a4282ad623ee574091821c971363128e307288b4377e1e90e831b800936f2b5eb05fd5d0e505d71e7e34311950812131c5b742ea238bcdfacaf35e23a4b5b9ee2a7c0da6aca0ff02595fd4229baaf700eab8ce7ea772e133bffd5665ea3ccde2edf61d11e64dbd1919454f977a31292416c86e3e11b762a3c6f0c27cf1a07ba3c4197f21c8959e0f04fae6a086be6e77b47495d0cbfcfce05e34ef361d45b1f8c5068f0174cbb2ec9a9f37eb6ae1fb088717630b97bf46c801ca598878e6a8a96b232266479925e8f170bf76afa4acbcc6c7daa51c2b9a1821e5b5df170a8b57aa371019c240626b2f2a9d60587c34383ea7c12b300fb478e2b62ca9bf54b00f04f4970a68d6689c4087713e9b6be1e7c92ef16a7cd527d1ef33140d8d3994c07d8ae237e047bf478f164aee1c6300545bf986e570a403ef626c5fd14044611621bc5d5f37e417175a22288c2fb45b0e11e946f755fccdd774e5ace72bd2ba44be8f673235e9b49c0fd4d6a912493fa797bd97462de0402f77da7eee2ea6c0d02fa880ba57390eb1f73927d4616b95067d18103ad4b10af7a40b35e620211acf4c9f47fd12080b2df1d350d17afb649ea5e8a038157561b107e7d1d00284a59541c0b759bb424d2795ff1d3bfd7749461a9f67502df649d2d69e72036ab4f8869c7bb35fc999a9179612524e2f9bbb00e7dd5ef8fbdbfc486447ad5ea93b7220608aff49eebb98a1de88c68ce2b9846a63ac6b8878fd645bfc0c0fea6bb746b15301f58d2b9d2ace73828a623885fb495761be85780668b436fcaa6367776dee9e3af641ed5755f1cca7a931c97162f6879c7a3bf6eb47f98590d07654be8fd8582c5774f89bebf6fb113d75d28afe74443a64af360f41b9d243d8fb865039d924fff4586e3c76d9d0d43f8487200e802adb9e01460eb6ad5538d8549999c4b38c41dcd878b8dbd049b853aaa4426e74226fa19d3d501e6a93aa99dcea681f0044e15a05c2d08ae49f625ffe88181d2c1fe55e91b6f602409fdf961af1da851fff67f1e9c9ac10dd3960f460bb8f937ec415870cb9e99e150f5b2a2308f2136960d199ccf5900f130a3f4610cda347991cf34fe46717071dd5ab2e8dc5bc20757fe6357fa56a18a606b25c51612975f51cad52e5a20a8eb2cefc79732fe19baee7b8c65167e2949a4ddc8d1e262b47c97286c2d0fb7078b3f553453445053d82a865320ead1ff4bf4fea84cfd7ce21e7aee696a15f92da1f3d73c394d47a254247492fec3b6582c94cad0df1b1b097048c9c91bae6aa269f5a074b796bf86770059cc767aa07fcf84010b1686437042d16d693775a03d9832857bdde9f7d98392bbcc579db3bddbc58d8cf08f04064e3eb92d87829e6617efab245cfbb6d564c5fa333ef560d6105c525e39177ff5530dc154b691b1dabf14d0da99229a04ca5c6e7956d474c0ee578b1b287b0a5971506687670ea848820c44875c74e69a79b36eaa3cc2a5a27fd5098f0fd3c190089736a271ecf3f14b3259cab95b941bbebfb5be132d875328a1b0ddeed958e8ea454ef80724f878a2a690bef56fe3ea62f47cfb6db303ae608957dbbd57735195d6b1b2ed73e69d1ac4b4b4fb01c20eddcb29e8b44bbd71fc25515885a56b8b7e55edd4c21d5e8cc43417e94e57cc49f279d0ed740b286d4e27c0b909729c4250ea2d1857f3f7d801a87afcee46f455f8a53e211fa0a311006cdde262ad4bc47941bc52db89c4b454b7075bf29d9cad6c98b7e84318a071789a78d1a83ece7a24cbf17691aec06c5fb7bb8a832c0aa33b27a5b3a68ef36364fd85cbd19e8f75e184c3d1cbccaf7ebc71211506021ce0d38bf8c0885a205d7f4a60f7fbc972c7e2365b07d5a52fe8ae02608c7bfb1650ebdb4f2620f2698f5fc90c7b42a34a31732d2cdd12a4bcae3ce399623211946f74c67c5e82c0f53701bb4460504e17c1d6fa14288a63d97a86068be8ec36670adc16670b5cb3c09972b596cd441e4bb9b50471708bab77691417517e91883df9f0b353c2bea3d0acffe5410097edd2b3886592cc70ccaccbbf64d168637a8a3fff0d143e497e5311a9b13b4adcbe8d2625dd1fcb5ffe9c83ddd4a1cb3046616296faed945fe7b29ab6f912be6959f8768ce28958f2441a1e161147145a1621693b9f2d24fb9c7a89535456dab48dbe15c689709e2af6a6805edf923d8504f3d2cb8220ff9966f854c84e9ff04fbf45e42a5c73df4f719b9ed287695a4a03d5c0a3a964a7b6e95bcfc36a292b23774812e8567a02cb8a5baaf89afb900b3fb7be40c9e8432656307fbf2487c0d1f3baeda11e803f9f298e7e0c478f9fac11a43ca32e2cda46ca6491cc7b31aa1725d24805587722248dc326cf81fea4fc1ba9a58bdce9e34740e3732b96889b36e917cf029c7027c5cc985f8b3f0fa4e504325d56c7e653ce903e8410a6b06a2126b3aae2030404441273c1e486bc8285dc078c1874635e75cdb753a0fa821567e8116179b78039f8cc52675d538fe38a71f46792af445b125dcee671bf7789f2e874b25f05a431ce574a2d85762ceade5e5cfebfa5ff62b1ef5ee155fe418b16638c1562b29be425e05ef0237f03bb42181f55d4370272a13d5fbb353358da434519cbd0e4fca54f9cad4a7735238098d3984b0cb9360eccfc63b3b4339e0ad2b2719552085d7445681c919f21a6b482402c271e34d7f9fbe4fbad68eaf825c57d22ec0a2c5ddec8c1273131b867a3760626abe779e37ee632f41f212e9a9aaf26fd5cb28df689d9c4875c49db62213faa1e18c35b5d2df1fec21852e7c35d20d6df85ca2a6b10898b244da31dbb6de3a3a8553601c0dabf1e5f4755fc77c1561223cf0b1ee43441c3aa9d855df0831db6a7f6949ff0ae1cdd465aee616b789c268417de07e9c0f0ddae6b07ce5186b3b83ef96fa1ba9fabda1bd79986efa852a348364e33e89458550049522e64491a9b24514665af058b4be4ba690299d3c2379b25ec97575a9312b38d3106f805e829bd77033f4d5f1b35ffc7289c118749b31f17babb56f48aec597049d635c055d056db0434493a379d15010f3325690444e1021abd622d18ea7e0b5d5b97054708ea9087b4721bf857e3504aafec84516feab2a6f6309a506cd3e931ef3ef47807feba8ff0b6dd56eb83349d99be8633675eed19be804c06d4d81b0a256ec95cfbb2b6565d7906537c5adc404713baa8fc2e0f425c577660df47198e91d2eb3ee7a9a5025641aaa759e7e1f3dfd85c83a17a6a59df4af62bc669f28d12544254f4e0527a6b10958664af9378e41aa9f88ef3041ee6880f23a858254b5d0fa7899655e9d06f12fa863b63c2c950a0c3eae774149502f0fa3c3a44d24add7f9426ceaa21dcdc5408f0b96d63dcfd97dc4a3ce03ccd56c8d48ccb253e82d50123e8a5176ae5d1b9cf6b6c11d2decea9f91e9ddfea605eec75391ffc4e01f4988c0ee78ccb3adb8a5e16644eb30e7e76ff251192fb3a8c48a68224a2cfee4aefa616ccbb68abea13d335a4b212b0b9841a42b418cf413fc868a842a26950e11061608a623a5dbd520aaebddfd1a559705e8cadf6abfa272925651f84130223b0056be28b618bfdfb164d2c5db86d82ac0eb2c457198a6cf8b0c2f2560eeac4441df45a9192cdef63a00adee0aafed7e0ab0bbb0c0b9a066f9f45f5e0c6a9376a069a45512081ee3edd2e9679d6c46d71e3740c5ada7457fc5d21610edccc2bef851d18f89e8307105855da15dfa749c44370b8149de48309f99fb5040d05d0739a64cf253855c185550339af73be6d5cc2de3186ff4b004ac816c1f4afcc83ec3ad66740c57b9cf660de7ab97b0771189fae5957751eec58a3aa6d3ec6121bf767d13533ff413c84c1ef47142f51ebf515c3d60a3c5cc3b9eaf9d43d2a84b94ce02db3f254862cf3c6330574fde5f8257c215c416ac3c9833839d5b33436fc12c21046025a4b0be90f18dbf002e001b8541b888835ad138def9910c4546fa0cf496bb4415463cb10004959dc6b0e379c18090bbd1aba6e9588fc21a89778ed1a1c0533049867569691aef6bc310fe4853e9e9bdd94a58943017a197526c70d2d278c66e94aa97abe5af8d9faceb0fd4e102bb69c824a1e4709be2125de420aebb11506bd62ae6b32eb1bb2cbcbc35dda3c992193086b11203775b33dcf4206a976b31222fcfd8b0e6beab7eed02f9f6d0dc2959929e1d30c856a672379ea1a20bdea6e023fb7ada31f6f9e02f354f464b2261879372c0c92ea462ad11a83d54bacfce3febcafe14753d697e905a7c77031beb83076444aebdb99cd1aa470d5774ed91cded7eeccf7fb18860fc39577a054b17aacae86d02c2dabbd3ab068c982cb095d135c11daedd863bf9abafe991656d1f7773cbc05aa66c4c800b5763fe845d06c3b19f4f73dedbcd50ea363aa11e8274d541ab754209fe7fc159e7bbe317f8d9ba602bde8fe02171f8daf608bcd4663eb401c7a3f2cc814bd8fc195cc192d4d6fefbb15b9d9738f5e6ade7826d65b9d8477ef500afe2e40077b6ecd7d3ed78233fe980332a313fb2fe854d6becf9ab4c1008cb1b16a513d3fbed8036ddaaf372e8891c59c6e9bcdaf2d88e22d528b975d1a36af2fa792028a3e1161a74545eab1cd6284079c2353ef1c49e3e1242ea52d22d8c7d64f553e4c396e7d62c4a6619ec698b56cf25cecb6673d8a3a703f65e480f1b8b91e4427e9f1e9dfa1939134d03cb3115167567835d449f50cc9bae06adc68e3211d8e0cc1faa34f7bda6e1cfb088fe980397f4643e89052d2bfeb233ad81c3cd466bca1b1007e2e6459e3aa1e51f1a326a2f5d89407c05946b0dc7741f458464b5e4ceea5e367a2e4f0d007e9e31b24f5b7bf69aecdef4ef57de58719cf9fb5e8f5366452013a5bb69c3f1807d83e26bb63493dc141ab1ae8eeea11c495650b346919de060c4af1a80823fb10b4cbc333b9d6d05c6a4c293a7fd524c5259a841500617ee442222ef2cfc71a0e4bffa87903ff531898a44452ca2b132c4a633c91c7a24bbc885a01001988ab845e53a350c3b283dda71360c7a9b47ae40f72737ab6be068ed8ecbde1d0bcaecb729c5bea691ba0de6867e6e6879fdd99efec2b6de4c2691ec9031189491a01329fafb2f0d0cc28e26a22bf55be6ca866dd4a473153901f244c63967e829d9ae2ed83451a365558b697055a3b9a6bcb1bb40ae56f13d4b60defeb1a06cc6831e175ccbdb92a34462e786ea28e2ff25b813b63b30ea3b8d9a0921a5a5bf45576b39fbab6071fb1412670c936b5fc31d668026d297c5b84739021c4e763686e4011a2bb7e109db8e1d6bc853235a44ddd93f1012f7168ba3091a2a92a3e05bbc761fd97ebfa22265e6c1c2bccaa9d327d4ad61de87d3b5f0c5b29e604f79827064e05eede8b574c8982bcc0439db27b15bd7ea9a38923a1982fa7063f9f1572963c75168d53756803f6f60604ab33388ccc1294fb0ea143fa5e128a060da40f4dfa0382906b878a602c568f3c99809cf1d5912f224b2adfdcdda84df149217bf8edae18fb4bd825900ddc57ecca2eb7d209ac44e06e674c2b7c126756bdbad066dcf187344824050b16ff9414fe957c37a048c3a260a8dea72f7a12bf5b35e1c2205866bdf85367d94af939bf52a3027e2c560ca096a449b7297687bee98e4cc56e1449448461d028e435fef26f060097cd96bd605d5a1cf6b1cc95c49037401878b85d437ee43bcfbd7b2b8c145c05a33fe01226a637dd677bfd28c8acebc4a30494917c253957462cdd5a3d200e350f5d92c5c57bbbc7b2392e4569610f35e3707aae8a481b8500dc8dcfac689a018671a0f3634d18fc7bf4f7c58933da452308e348a446ade0bdd6f02d29cd8d273544ba46f1767873717fea45f0e0980339fc187acb7045612e95db5dd9c89169daccfef2e3a01c4d19984f8b1cc960d054285119f23e746d743a0db459bdd5803fcdbfe92137e80d47c84c547848ae563695cbf113253b8a96e368bdacf59ff73c023d043348c1dfaf143ed13424662c2da644c25b9d22598813e1973f30ab103c0ada9ed247ca038a056d18f2e7c8443fd2c95366b387e9ab972170cd2b4438455dc73619ab3444da0d64b0b2d3a9d640ea917b1c09d17c37fd587eedab367235e1748dad753e4cbc74dd53017ba65571a5a65269666df0a24bc694a2d24e862830e7808ea8ffc1fd6cf4b29564c8d77d9692d7fd55e496c69f5f17fe145abc0dd1818f2cf6eb979c33eaf41050901dbbe5a49c8bf9983b1284fce92703b45c4131b3204fb9edd58b6cda3918cc490051bf9d6751b7702e577b700230f1820238b959e46f7dc3a3abad842814c69a76be5376c1e7b35e3ad7318b3439008e4c3801bd6754fe67cc7aed658d89550a30cbb1193eb5d2144eb7f84c5c6ee9e13947daa3534ad4902ceb9cedcae471547bf95e2337760322b55af97457d23d174b1c6f3e1d3585feb000953e298e35aeb467e90342bc61bd05af59c72921b2fd4795c19bba268bc6bf4f18349ca91b89cbd6814a62dffd4684ab78e998f7e3833b51ffc495ca3e789e685417a0d972bf4192b0c50016a64ba839da14c3c5bdd58a74e96e56c66d73e2869323093892c5272aba5e6edff5a8976c5e04976c8bc1b8cefa630cd924b5bc7d28dbc67b8aac4d7571623c4d412acbfdf61603d2cdf1bed6fdcf8d88519a3ce3c4803317587c4a7dd33147f66aad06554d69138959fc3172298be9f5f83748b83c6618758bb45058fab1bbc1434b993890288a42910b91bd52ac1abe775acb09cf7173ff9fdf0e644ee94b000c8ac5cbce24d424800a9df431e03c650b3f4196115f100b49b7a41f68ce27e5dab5865b40a0977cc1be995d3504dd3bfcdc8db2a57765b1a80f6cdac0db795336bc9ffa4cc163df1d9d6e034d5b246cf59ffb2f81ec02ad4c48eb652be03c97a11427ab519d8fc8d704fea98d597e44cfeb168f3fc1385f1a1dc5926dfda78be4c3a3e1d024e4492e952cc8471ae1f26150cc065bef433c0431128c7df6c57bd79dbd409fb0684137465ec0687ec2ec45c6fb76eb88bb7bfb4df3fe69421dc7e0809e2474f987a59980fdd92b2a66ee31fb9560b4657a112ae523caec636642e44b507ed5a900fd65e29d35c89d252708b7f2c2daa29062b94577b0406ab9cda76c921694998192078e2ba7a90386e1544444c228db678f9c7da51a06b9c0a22ea26ebd3dbd8880a6e981decba2f659ddfcd15af8d06031e2d8ddc587417ab536fd4cef49372e0510c58060f2900e030fc894f1edb6aea502b0e2642a8cb1e0d22cc11a43cfe8eda906711e059d6e4a55959cc337dd54428eec2c123f5cfe185a78f442266f54213537af2f4b42176951bd9b0d1b70c61ef5e728acd1a5b0c8f0360fc3d4106d1f1a6a100326500e25cf6ce2c7f230e5e54526c3affad6bba78eb0a275ef942e441919384b0420571655eff68e32cd97a322e22765fe736eaf329f41b2ea005ad56acb4c092b7bcdbf2bf3e54b058827259bac8bd94ea73e1d61cba79deb078857c63e255da3b8ed4bf5d4f603d8e3e19813fbe997afbd272102aef06950ab6daab60139fae51f0fa8b48f3e056a360f074692f982aac57ac3472539e7484862997ed283dda8be4b22b83235299d1b20df4ccbf0fa24faf392a8433535d3f3cc3ad7453b9b150dae24b8c78f149b53f5394af065082540b46f6ec3e70e2428b873fa564b548cc1e39fb406ff897662ac7e901384b3094c328bd484980c120518a8504511644b0616215df50ce1ab6106762d52ef24d40b9851168c69b3068682525f1050fa3ae139c9500f89d1b5a96c35f71e25f8ac229518a79fbdbfafcd67d7356bfc3e9699f0e5a8c9fceb068f810cf2c8e3042b5fef34778a3edcda569dde4fbc240996038e50e233652eb5f303fca7f8f29c633684566f6548bbc311bd24d7e0ba95da8f02917048d9777e5f142f83cce4187ec1af72b6b6c3825e38646f9f29697f6fe3b3cd76", "password#"}, + /* test vectors from CMIYC 2012 */ + {"$dmg$2*20*dc39029a22b86bb4f930499578d0dc9eee69398e*32*bb47bff69b10ae67000000000000000000000000000000000000000000000000*48*c4559cada09552ab075e73dbefa4aea1aa21209011946e423ca707753a91c87f6c4cbed3beae20a244d33568f852068a*6*4315*504c0c37c600618fd54da114fc0eb24d6f24585568543126ac56c034cd8d7b3dd991f1418d0c95791e091921c02bf695b7835f7b0da2c1b96524e72b4bd3f671c592aa176b6a58de77a35a26bd1d0c313b2ca23581027fc52c7c63f37439404218d720171d3b178125e6ce0646bd6fa1033f2ab7b6849b3a35a430cbd1401f73b5deb478d6d0f58364579c208c613cb2349fb19adaf98be2d4a74a6030215793fe4f1129189626bb87c23d26dc2af51a98e1fabf2f58e106271c7759d104b9e5171d8f952ceeb14317614b7a14a5313029aa4068b898f7e0f5b68683feff0d375f2ada37f20135df443bae913c7e96a29c6c3388b4b51432add89ee22826ad0b1b0a4ca9233e691f71a5ae2c76b5e5a135dc793e081dc53781faa4f844928db94084b53b39f1820c8342b563e3f46b002bc52ced63e4588388e69c9e85e2002438a1a703de411717d24ea88adef3051b27def61e4b9a31548d3714c3bee39fed866254033a123429043d0c08a052d2999a171b010ffd119f90bf9222462508ac914e0a68daf93f63caaa0c4302c9b1f6447ac3856b09eb45096b3a294731f110b90826b0d611e6e045397b07e5aa64afd271f1c92664e648af648642f786c0c8aae6218f4282d8efa713dce232fb24df4073a0e04edc86d940e8ad22db8ca751143743f9f12585bd788551cc7b70821b5c42b133cb7781f60d1b9c345e9adb122ae444be456b8e49f9bab0e2033019b52f2ede4e7f56cc1d1dc3a48bf0666cc7a4dc6b4ffd5077673f2f6761688e4452a4c11b82598cc0ef57213f6c7c12ecc67164ae501b3e87e25a361d0615e48cde249f0193f2aa69a1eccf029340531becdee8eefbddca18905451b48c1085d4cb965786d3892d7144841300b8d2722e92af50fb828cdd8e825dbfb16328f7cf792f311f84078d45306fa570661e1ef2b34d5d36de2fc4b295f5e84fae8d55ca22bc15764932d0c5dd3cfd914b2b8f67477b2b5139c822ee2c511a03f7e9c717a5e8eca6c4b54f9c3b7d85765a78f03b29fb979811ff0c655522b341bb54ae3bc412eb760eb689c6b4c3bfb85a8ce794946214c574105e577acc01d3f8885e72db52075d05a75260a6e4a54872d087040ff38f8942cf150c3615088588cc53fed11040bed573c0e9ab14b987f9223ad089bb73284443f61ffdd61616b8a783e85618217e8bb491a31b7050421f4b0a0bfa5003775933db00e47e4452adc1433da2603f6dc5b9dfe58efe458da25699e512660ac6f1129dd9d7b176a24109c6e6e0c201d784addc9c7f8d4f309ef6fcfb02493abb7c836ba3a371e64fea941031a59adbcd4ef59f0dbf31f361f4282a0e60ced4d9d17675b0422faa1c2f932cb525ee07df7eb2643a67963aa99daf5b119884557ef1585d81eac5c8acf32438636a10d043bf47093fb53a5b3ad544a38fbc3588bea3ed616167a79b2133efd8c509f53626b9cd7b71828fbd5d61b1df6ef3713b5347f65e7c0770715ac1fae561cc548864f9cfe281c6e5770f053f68ace64702c81c97976f471ad11c7551789ca21a4d5480c5d3528503f2f7fcb268c34498888d5fd3edf1c71d12581c393db2ff863e22c1f6c037106e5928aac9118702b45bd36782b2295782f93458dc120e79cb3d1632c2c5e527e56060b79a751cb7653b8c0ed2acc32168b56fe5b50ff9e49a71dc9b82f812b53e095660cd7d59c04f31ee47773a04eabccd7a4a6455ebc7d719c9eaedc4e6c935fc99642acd3e60e0f564efae90d7d1308d6ddfe7eb89520c234cafca6bc7e8ac96ed401bf96e3c9de704ad124b0f9381f22d9ce846fad0b14eeb5f93eb0e0fd0657c480fd2a1109d735f3825db598e2aa7e624f282673947c38aee8832ec8d4dc5d6a7306e3477ab4e37588788109a3ed76741f8f2a796d0f5bef8247eb298fb973c4e5d13666d87b0bf5a7a553f208050dd7140f64fcc27793ea82cf58fd86ddf805a700065888bbf6b5037815afe8c03eaea355c90bbbb448de13773e977fa4c6f06e7695e80882cdac40301b537fe254eb1ee437a6ccf3efa68899a7188e6829b58977917a9d6124cd2af7cfa567fb85aac9c6b971423681a0b6658575ea0dd32054800e08be5683faf46165c56647e1c346961608bdd8e6f999eb033caf73f000a71961cf2fa8c319f4084c0ab499caab87d13aca3f057d17748522f08b36c56c1746e49d731f9355100879d7d114000293520c9ce71098d26b2114030615aeedabd5a6f7fb9a91f98b7ff00ec72c82136a00e5a19384084e0aebc78bb3cf05c3c1e3872f56e254c68694d930eeb46ca8e99329eb923ee0f1b5af0b7276e8600e25f18642247111eca41da427e5b9034a6a22627734ee024c2e2c4277edcb3a0309c3007c19416fa131086eccc6f73784e1a008dba5166e7c8aa4cf8efc3a4e14f59d665800982e46341b9b098508510c7dadde295a784f7a7085f5ddab5b6881b305f99d87ce3883e557280bf2a1f3adc69b7cc9d4f339623d21d569230e57a2bce611de7495d403adf451725d7ef11df4bde5a31a95bdda0d0c2a7869ddeedf2ca7e1986ef430ed44bff6ae6e44f740b2c65364477ade4dff6f4eacbffc67a2e0494c81e0424bc9220bf20aa795e2b20db6076667088b6863243ccd2bf897d4b6e1e58e2662cac593fb9a86220d65964e7f6e0f1987d07a4a8242c41c001ec38ed2442011d8a56919800b4d590338eb8db02833031ed0422bc08b11dd59b59f1d301e82154803076053464120217ca64bacc02465cdf629732cf709777452e177f4a4d1015fec4c36337ebdb8daf57f19bfeb247a27131ec5280038f3d1a766e071470ffb685cf4d9763b7e1b5776589874f3cbd4761d5fd35638918ad144a4a1bcedab9d652477951a716e4073cb36640fc257031f06e4d6f586a9a0b6172727933179e4cd433ba940571f3eb908535a12e9cc3ec1e8f8aa9975bc17241779d972a8fd8581dd3850905cec48061dd5fff1b295757e38ed8568c3a2967ba271e00fb507b10bdd5ac5b90426e48e596ed430b5a3c554ca1cd0d18a90809d8db18853e2580cf2b2ca52ff686b7cf360799bf69c008f87191ee372b44f96696a12632af003eba51adf1e6101628168b92c718c6f7aecb765125880f180047ec3b89fa23bf57e4fabbce38ef0fcba829123f0a3ff527dad6d6b5b0c4b0c4c4cd13787e98c829bec08728acc5e90ddc6bcfe2254eb29ae8450ae87841a39958ab80a38c8a742de64a44e25df0360a9e8672148347d7812bdfcd9037723edbc5fb4a8bba689dfe3baf113778a498e2689e8cf1ad194df422838a618b0cb222aaf020705fcfe1475a8c205690379cbe2d0b5f9a0de41a4d2e6ff85f1f19a97712bdbf49bb90051ab934407bdda9bdbc1a57b0e874f3b2a09df45b7d01bda15330ccc57a752deb2751e495e394471f09f33d98d8face401d418affeeab86be36cd8cfb0f435d9939822041f256ad860733ccf137e582e1cfb5a8b96ffe646d1928657c05c67b8589a90fb32e078697fdf8a3ec58dc6d350a7f50c83d09e5884317829d8e850b7fe17bd2ba4d7fd94b86d060a3a97880fb350b95cde4542cb7d1a2f44f8ea065ae30fd4d4b5fb24f787b8462115b3a918155bae098f0fd7ae2d4646d3731d228909f690cf0116e1ac15899513957834e0a74d8c07f0c696cd3268d631ce1292f66b2633a3287a7e058781aef9d3d566e4e41395fa7e1793aa9f669aff116b99660a5a29fe127a0459eacc3fefa4be95a13499dc844d9faf72dca38d8032932084faca23e4022869f2034ace2de0b286e71f2b569951214fd2eaa3d32da48a234265acec4967c74976b5b5d635eb12cff038a4a23d6c8e86a11a408aee5eedfa7209a8ce8d6bc10271e4b5627e16c5f8ce8000882c461de0113efd8ae9cec6ac4819ab2d6f8a9f189fa2929807fb20a895204edad9821d180c54e865548f9b3eafd8073a734e61d574923f0d1f69d266d970102434b0bab705465833ec9926b03798fa8a95ab98d35863b7490db07fa1abd600abcc3718d105f26f96d20e593ce0c82efc68ae65d03e4e2ed3faed27bc5799e359588fa884ac79c1ad4f5f8bcbc9a2a5605f97551710e2e416aacf149941265406490d32cc6bdde994943fac2102e57785dca3c20358cd431cee285768d9eed6ed32a9919e13f1a38304db6a57f637b6a5c8adf4e829baa82ce674ec7444fd9f7f1807b8f65d4b68ef7b6c3fe5bf653e81525f7900916f5d5809a52c070256e6b4cb332fced5e460c9a2f62bd73392bdf4522be7c211577559f59f62869e0a71f832ff493fab76bbe70f3c0b902fdf45cf49793afdb87558f1a6ec289018035d861990eca1dbfc412492cf86503af00c7db7a0a2c6374eed42b440293938a36f61e1c4c187cd50d974f2a0989b05b8ee207398560b516aea520044e37229fe0efa8b7038441fd584d79c010c0f31030d60eaa4dc1fbdb5a254c089198bb5eba6fe20655808c1d22b9604af1247e2b820823b3c622be2b01ca5f16f86af880908ace8765520c813afefef18e2c112a72fcd4760da91f7d1066cb5c8c902745b83be8defa193bc8b6b93a82efdf1713a223660c6ff4dbbbaccb1a4e5482cc238388448e8b9c24c9aa3acac9467e1f6d96d6deb1cbc9fbbf77b7e756068e22bc3b9e6c275987c5eb99da6a5e2d90a1e0558c4f9fc392371c07a7844cb947b19dd1a6d9c1ebb6496f36bdce2967bea2971cc1c6330b1c31054c07f8d853858a46ae9370ff1d6ab755beb120a61b4774fba521baec6fe8a079862a0471cdc5080c0f073f7e3d33f0f25978d098f61bcb4905c776ce6c0562dfe08d8b9f17de4bc2048d962ad7f4baf132cd0152a904fea9530e7c1f52a85c0188d6ca38ff9b692b2a68204a6dfbfbec06f2d800b4444503bf2dde736be4108845c5a28909cdb42391b5a0207c157003b8dbd4e43996ab5017c5f21cf0d4d9b3145c0cb70fefa767b4689cb750fa7657c4a788b7759f86496998fd4b99b2ad1b2918bf330c1a81e8986eab031e9f86cd93b7d623c72e1a394f0862a193f21eeb858524477c3192fdf5b61ce9dd5b0bf3b3d7adbfa828f1a9ecd4dabf5e318fc40262f0dd204f28b934d1af7b0d7cbcc20be21f1c7e04fdf76104767892404b14965bf8d53003ca9ff0a8f15f5d9b2e152a662ddd8eaf7902854d8561ff088fe2e880a18a036d06c29997dddbfaba32ae4ed70b47413c2a037122d830d55bfde89ba645562cfa1d29f428da108d93562bd291748a728d1b3090b8a7f56293a3135f05d6876021e92aeede437dc7ab610e1e5af0a00c880887754d76b42b059f32f9159d25ffc56a993661d06a7973d190fd10c4ac998c8627b494444389c529e41982726f47135212b678b69ff36ad29e225856ad2081bd393249f469648e6ea4445e0011adfe320b4eb5cff1d9332c1779edae5d5d66931015e793f730be8482b5f488ca6372edfc71abc4b8aeaecf8051bbcc848d736eb0aa0d7ee4cdb9eaddfdcd4200c3e2f58a97a162565409abc44b8e982fb883b619fa80c7c4f2318954767ea1c63c70124f4342118f2c798adaa7ab5f6ebed1b0a15e12f40978ca8e5f0972a47cf397746f9f482902abdda10ee7f4c610935070f888b5ef8eeb07933e1d6ecaba243fb475b4c788cf8b453638ac43b9f6eb74654835678b47d9437a14300a12553fdb10daff3690e0802dab80fbffc401422a465e10e6414975358249d68e4ad5a1f1c93e295bc10b8c5c11ed98c7ca5773014a2739c0592dfa30d8756be1f66e4fcc01beb2dd58d87800e71d136c12b8f73298cd37b1bb5758376b2111921fa9f7040e69d3620415ace96ebf29fc1a87e392a9e701f4075208a1a8fda7a59b28997c017da70c18d2bbb5c91db86d701cae85a5742842fafec723be9d93b4225619c7188f5bd23c900ef3863068785363ab861b58aab8e91b562b26f72a812e7892ca0bb6ed91086a2935ba82938b367b34f70cbe40c02a8cea92a78588f90cddcabd2738c9a18450f6d3a87c7f827a1773c2c7629452f64e1528258a8ba75bc53245c705246963369f1179a765bed41d", "654321"}, + {NULL} +}; + +static void init(struct fmt_main *self) +{ + +#if defined (_OPENMP) + omp_t = omp_get_max_threads(); + self->params.min_keys_per_crypt *= omp_t; + omp_t *= OMP_SCALE; + self->params.max_keys_per_crypt *= omp_t; +#endif + saved_key = mem_calloc_tiny(sizeof(*saved_key) * + self->params.max_keys_per_crypt, MEM_ALIGN_NONE); + any_cracked = 0; + cracked_size = sizeof(*cracked) * self->params.max_keys_per_crypt; + cracked = mem_calloc_tiny(cracked_size, MEM_ALIGN_WORD); +} + +struct fmt_main dmg_fmt; + +static int valid(char *ciphertext, struct fmt_main *self) +{ + return !strncmp(ciphertext, "$dmg$", 5); +} + +static void *get_salt(char *ciphertext) +{ + char *ctcopy = strdup(ciphertext); + char *keeptr = ctcopy; + int i; + char *p; + static struct custom_salt cs; + ctcopy += 5; + p = strtok(ctcopy, "*"); + cs.headerver = atoi(p); + if(cs.headerver == 2) { + p = strtok(NULL, "*"); + cs.saltlen = atoi(p); + p = strtok(NULL, "*"); + for (i = 0; i < cs.saltlen; i++) + cs.salt[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + + atoi16[ARCH_INDEX(p[i * 2 + 1])]; + p = strtok(NULL, "*"); + cs.ivlen = atoi(p); + p = strtok(NULL, "*"); + for (i = 0; i < cs.ivlen; i++) + cs.iv[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + + atoi16[ARCH_INDEX(p[i * 2 + 1])]; + p = strtok(NULL, "*"); + cs.encrypted_keyblob_size = atoi(p); + p = strtok(NULL, "*"); + for (i = 0; i < cs.encrypted_keyblob_size; i++) + cs.encrypted_keyblob[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + + atoi16[ARCH_INDEX(p[i * 2 + 1])]; + p = strtok(NULL, "*"); + cs.cno = atoi(p); + p = strtok(NULL, "*"); + cs.data_size = atoi(p); + p = strtok(NULL, "*"); + for (i = 0; i < cs.data_size; i++) + cs.chunk[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + + atoi16[ARCH_INDEX(p[i * 2 + 1])]; + } + else { + p = strtok(NULL, "*"); + cs.saltlen = atoi(p); + p = strtok(NULL, "*"); + for (i = 0; i < cs.saltlen; i++) + cs.salt[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + + atoi16[ARCH_INDEX(p[i * 2 + 1])]; + p = strtok(NULL, "*"); + cs.len_wrapped_aes_key = atoi(p); + p = strtok(NULL, "*"); + for (i = 0; i < cs.len_wrapped_aes_key; i++) + cs.wrapped_aes_key[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + + atoi16[ARCH_INDEX(p[i * 2 + 1])]; + p = strtok(NULL, "*"); + cs.len_hmac_sha1_key = atoi(p); + p = strtok(NULL, "*"); + for (i = 0; i < cs.len_hmac_sha1_key; i++) + cs.wrapped_hmac_sha1_key[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 + + atoi16[ARCH_INDEX(p[i * 2 + 1])]; + } + MEM_FREE(keeptr); + return (void *)&cs; +} + +static int apple_des3_ede_unwrap_key1(unsigned char *wrapped_key, int wrapped_key_len, unsigned char *decryptKey) +{ + EVP_CIPHER_CTX ctx; + unsigned char *TEMP1, *TEMP2, *CEKICV; + unsigned char IV[8] = { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 }; + int outlen, tmplen, i; + TEMP1 = alloca(wrapped_key_len); + TEMP2 = alloca(wrapped_key_len); + CEKICV = alloca(wrapped_key_len); + EVP_CIPHER_CTX_init(&ctx); + EVP_DecryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, decryptKey, IV); + if (!EVP_DecryptUpdate(&ctx, TEMP1, &outlen, wrapped_key, wrapped_key_len)) { + return (-1); + } + if (!EVP_DecryptFinal_ex(&ctx, TEMP1 + outlen, &tmplen)) { + if (cur_salt->len_wrapped_aes_key == 48) + return (-1); + } + outlen += tmplen; + EVP_CIPHER_CTX_cleanup(&ctx); + for (i = 0; i < outlen; i++) { + TEMP2[i] = TEMP1[outlen - i - 1]; + } + EVP_CIPHER_CTX_init(&ctx); + EVP_DecryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, decryptKey, TEMP2); + if (!EVP_DecryptUpdate(&ctx, CEKICV, &outlen, TEMP2 + 8, outlen - 8)) { + return (-1); + } + if (!EVP_DecryptFinal_ex(&ctx, CEKICV + outlen, &tmplen)) { + return (-1); + } + outlen += tmplen; + EVP_CIPHER_CTX_cleanup(&ctx); + return 0; +} + +static int hash_plugin_check_hash(const char *password) +{ + unsigned char derived_key[24]; + unsigned char hmacsha1_key_[20]; + unsigned char aes_key_[32]; + if (cur_salt->headerver == 1) { + derive_key((const unsigned char*)password, strlen(password), (unsigned char *)cur_salt->salt, 20, 1000, derived_key, 24); + if ((apple_des3_ede_unwrap_key1(cur_salt->wrapped_aes_key, 40, derived_key) == 0) && (apple_des3_ede_unwrap_key1(cur_salt->wrapped_hmac_sha1_key, 48, derived_key) == 0)) { + return 1; + } + } + + else { + EVP_CIPHER_CTX ctx; + unsigned char *TEMP1; + int outlen, tmplen; + AES_KEY aes_decrypt_key; + unsigned char outbuf[8192]; + unsigned char iv[16]; + HMAC_CTX hmacsha1_ctx; + int mdlen; + + derive_key((const unsigned char*)password, strlen(password), cur_salt->salt, 20, 1000, derived_key, 24); + EVP_CIPHER_CTX_init(&ctx); + TEMP1 = alloca(cur_salt->encrypted_keyblob_size); + + EVP_DecryptInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, derived_key, cur_salt->iv); + if(!EVP_DecryptUpdate(&ctx, TEMP1, &outlen, + cur_salt->encrypted_keyblob, cur_salt->encrypted_keyblob_size)) { + return 0; + } + if(!EVP_DecryptFinal_ex(&ctx, TEMP1 + outlen, &tmplen)) { + return 0; + } + EVP_CIPHER_CTX_cleanup(&ctx); + outlen += tmplen; + memcpy(aes_key_, TEMP1, 32); + memcpy(hmacsha1_key_, TEMP1, 20); + HMAC_CTX_init(&hmacsha1_ctx); + HMAC_Init_ex(&hmacsha1_ctx, hmacsha1_key_, 20, EVP_sha1(), NULL); + HMAC_Update(&hmacsha1_ctx, (void *) &cur_salt->cno, 4); + HMAC_Final(&hmacsha1_ctx, iv, (unsigned int *) &mdlen); + HMAC_CTX_cleanup(&hmacsha1_ctx); + if (cur_salt->encrypted_keyblob_size == 48) { + AES_set_decrypt_key(aes_key_, 128, &aes_decrypt_key); + AES_cbc_encrypt(cur_salt->chunk, outbuf, cur_salt->data_size, &aes_decrypt_key, iv, AES_DECRYPT); + if(memmem(outbuf, cur_salt->data_size, (void*)"koly", 4)) { + /* handle compressed DMG files, CMIYC 2012 and self-made samples */ + // fprintf(stderr, "koly found!\n"); + return 1; + } + if(memmem(outbuf, cur_salt->data_size, (void*)"EFI PART", 8)) { + /* handle VileFault sample images */ + // fprintf(stderr, "EFI PART found!\n"); + return 1; + } + } + + else { + AES_set_decrypt_key(aes_key_, 128 * 2, &aes_decrypt_key); + AES_cbc_encrypt(cur_salt->chunk, outbuf, cur_salt->data_size, &aes_decrypt_key, iv, AES_DECRYPT); + if(memmem(outbuf, cur_salt->data_size, (void*)"koly", 4)) { + /* handle compressed DMG files, CMIYC 2012 and self-made samples */ + // fprintf(stderr, "AES-256 koly found!\n"); + return 1; + } + if(memmem(outbuf, cur_salt->data_size, (void*)"EFI PART", 8)) { + /* handle VileFault sample images */ + // fprintf(stderr, "AES-256 EFI PART found!\n"); + return 1; + } + } + } + return 0; +} + +static void set_salt(void *salt) +{ + cur_salt = (struct custom_salt *)salt; + if (any_cracked) { + memset(cracked, 0, cracked_size); + any_cracked = 0; + } +} + +static void dmg_set_key(char *key, int index) +{ + int saved_key_length = strlen(key); + if (saved_key_length > PLAINTEXT_LENGTH) + saved_key_length = PLAINTEXT_LENGTH; + memcpy(saved_key[index], key, saved_key_length); + saved_key[index][saved_key_length] = 0; +} + +static char *get_key(int index) +{ + return saved_key[index]; +} + +static void crypt_all(int count) +{ + int index; + for (index = 0; index < count; index++) { + if(hash_plugin_check_hash(saved_key[index]) == 1) + any_cracked = cracked[index] = 1; + } +} + +static int cmp_all(void *binary, int count) +{ + return any_cracked; +} + +static int cmp_one(void *binary, int index) +{ + return cracked[index]; +} + +static int cmp_exact(char *source, int index) +{ + return cracked[index]; +} + +struct fmt_main dmg_fmt = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, +#if FMT_MAIN_VERSION > 9 + DEFAULT_ALIGN, +#endif + SALT_SIZE, +#if FMT_MAIN_VERSION > 9 + DEFAULT_ALIGN, +#endif + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT | FMT_OMP, + dmg_tests + }, { + init, + fmt_default_prepare, + valid, + fmt_default_split, + fmt_default_binary, + get_salt, +#if FMT_MAIN_VERSION > 9 + fmt_default_source, +#endif + { + fmt_default_binary_hash + }, + fmt_default_salt_hash, + set_salt, + dmg_set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + fmt_default_get_hash + }, + cmp_all, + cmp_one, + cmp_exact + } +}; -- 1.7.11.5