示例#1
0
static void hash_plugin_parse_hash(char *filename)
{
	int fd;
	char buf8[8];
	int64_t cno = 0;
	int64_t data_size = 0;
	int64_t count = 0;
	unsigned char *chunk1 = NULL;
	unsigned char chunk2[4096];
	char path[LARGE_ENOUGH];
	char *name = NULL;

	headerver = 0;
	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Can't open file: %s\n", filename);
		return;
	}
	if (read(fd, buf8, 8) <= 0) {
		fprintf(stderr, "%s is not a DMG file!\n", filename);
		close(fd);
		return;
	}
	if (strncmp(buf8, "encrcdsa", 8) == 0) {
		headerver = 2;
	}

	else {
		if (lseek(fd, -8, SEEK_END) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			close(fd);
			return;
		}
		if (read(fd, buf8, 8) <= 0) {
			fprintf(stderr, "%s is not a DMG file!\n", filename);
			close(fd);
			return;
		}
		if (strncmp(buf8, "cdsaencr", 8) == 0) {
			headerver = 1;
		}
	}
	if (headerver == 0) {
		fprintf(stderr, "%s is not an encrypted DMG file!\n", filename);
		return;
	}
	// fprintf(stderr, "Header version %d detected\n", headerver);
	if (headerver == 1) {
		strnzcpyn(path, filename, LARGE_ENOUGH);

		if (lseek(fd, -sizeof(cencrypted_v1_header), SEEK_END) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			return;
		}
		if (read(fd, &header, sizeof(cencrypted_v1_header)) < 1) {
			fprintf(stderr, "%s is not a DMG file!\n", filename);
			return;
		}
		header_byteorder_fix(&header);

		if (!(name = basename(path)))
		    name = path;

		fprintf(stderr, "%s (DMG v%d) successfully parsed, iterations "
		        "count %u\n", name, headerver,
		        header.kdf_iteration_count);

		printf("%s:$dmg$%d*%d*", name, 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("*%u::::%s\n", header.kdf_iteration_count, filename);
	}
	else {
		strnzcpyn(path, filename, LARGE_ENOUGH);

		if (lseek(fd, 0, SEEK_SET) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			return;
		}
		if (read(fd, &header2, sizeof(cencrypted_v2_pwheader)) < 1) {
			fprintf(stderr, "%s is not a DMG file!\n", filename);
			return;
		}
		header2_byteorder_fix(&header2);

		chunk_size = header2.blocksize;
		if (lseek(fd, header2.dataoffset, SEEK_SET) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			return;
		}
		cno = ((header2.datasize + 4095ULL) / 4096) - 2;
		data_size = header2.datasize - cno * 4096ULL;
		if (data_size < 0) {
			fprintf(stderr, "%s is not a valid DMG file!\n", filename);
			return;
		}
		if (header2.kdf_salt_len > 32) {
			fprintf(stderr, "%s is not a valid DMG file, salt length is too long!\n", filename);
			return;
		}
		if (!(name = basename(path)))
		    name = path;

		fprintf(stderr, "%s (DMG v%d) successfully parsed, iterations "
		        "count %u\n", name, headerver,
		        header2.kdf_iteration_count);

		/* read starting chunk(s) */
		chunk1 = (unsigned char *) malloc(data_size);
		if (lseek(fd, header2.dataoffset + cno * 4096LL, SEEK_SET) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			free(chunk1);
			return;
		}
		count = read(fd, chunk1, data_size);
		if (count < 1 || count != data_size) {
			fprintf(stderr, "Unable to read required data from %s\n", filename);
			free(chunk1);
			return;
		}
		/* read last chunk */
		if (lseek(fd, header2.dataoffset, SEEK_SET) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			free(chunk1);
			return;
		}
		count = read(fd, chunk2, 4096);
		if (count < 1 || count != 4096) {
			fprintf(stderr, "Unable to read required data from %s\n", filename);
			free(chunk1);
			return;
		}

		/* output hash */
		printf("%s:$dmg$%d*%d*", name, 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*", (int)cno, (int)data_size);
		print_hex(chunk1, data_size);
		printf("*1*");
		print_hex(chunk2, 4096);
		printf("*%u::::%s\n", header2.kdf_iteration_count, filename);
		free(chunk1);
	}
	close(fd);
}
示例#2
0
static void hash_plugin_parse_hash(char *in_filepath)
{
	int fd;
	char buf8[8];
	uint32_t i = 0;
	int64_t cno = 0;
	int64_t data_size = 0;
	int64_t count = 0;
	unsigned char *chunk1 = NULL;
	unsigned char chunk2[4096];
	char filepath[LARGE_ENOUGH];
	char name[LARGE_ENOUGH];
	char *filename;
	int is_sparsebundle = 0;

	int filepath_length = strnzcpyn(filepath, in_filepath, LARGE_ENOUGH);

	strnzcpyn(name, in_filepath, LARGE_ENOUGH);
	if (!(filename = basename(name))) {
	    filename = filepath;
	}

	if(strstr(filepath, ".sparsebundle")) {
		// The filepath given indicates this is a sparsebundle
		// A sparsebundle is simply a directory with contents.
		// Let's check to see if that is the case.
		struct stat file_stat;
		char *token_path;
		if (stat(filepath, &file_stat) != 0) {
			fprintf(stderr, "Can't stat file: %s\n", filename);
			return;
		}

		// Determine if the filepath given is a directory.
		if (!(file_stat.st_mode & S_IFDIR)) {
			fprintf(stderr, "%s claims to be a sparsebundle but isn't a directory\n", filename);
			return;
		}

		// Let's look to see if the token file exists.
		fprintf(stderr, "filepath = %s path_length = %d\n", filepath, filepath_length);
		if (filepath_length + 6 + 1 >= LARGE_ENOUGH) {
			fprintf(stderr, "Can't create token path. Path too long.\n");
			return;
		}

		is_sparsebundle = 1;

		token_path = strnzcat(filepath, "/token", LARGE_ENOUGH);
		strnzcpyn(filepath, token_path, LARGE_ENOUGH);
		strnzcpyn(name, filepath, LARGE_ENOUGH);
		if (!(filename = basename(name))) {
		    filename = filepath;
		}

	}

	headerver = 0;
	fd = open(filepath, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Can't open file: %s\n", filename);
		return;
	}

	if (read(fd, buf8, 8) <= 0) {
		fprintf(stderr, "%s is not a DMG file!\n", filename);
		close(fd);
		return;
	}

	if (strncmp(buf8, "encrcdsa", 8) == 0) {
		headerver = 2;
	} else {
		if (lseek(fd, -8, SEEK_END) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			close(fd);
			return;
		}
		if (read(fd, buf8, 8) <= 0) {
			fprintf(stderr, "%s is not a DMG file!\n", filename);
			close(fd);
			return;
		}
		if (strncmp(buf8, "cdsaencr", 8) == 0) {
			headerver = 1;
		}
	}

	if (headerver == 0) {
		fprintf(stderr, "%s is not an encrypted DMG file!\n", filename);
		return;
	}

	// fprintf(stderr, "Header version %d detected\n", headerver);
	if (headerver == 1) {
		if (lseek(fd, -sizeof(cencrypted_v1_header), SEEK_END) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			return;
		}
		if (read(fd, &header, sizeof(cencrypted_v1_header)) < 1) {
			fprintf(stderr, "%s is not a DMG file!\n", filename);
			return;
		}
		header_byteorder_fix(&header);

		fprintf(stderr, "%s (DMG v%d) successfully parsed, iterations "
		        "count %u\n", name, headerver,
		        header.kdf_iteration_count);

		printf("%s:$dmg$%d*%d*", name, 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("*%u::::%s\n", header.kdf_iteration_count, filename);
	} else {
		cencrypted_v2_key_header_pointer header_pointer;
		int password_header_found = 0;

		if (lseek(fd, 0, SEEK_SET) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			return;
		}
		if (read(fd, &header2, sizeof(cencrypted_v2_header)) < 1) {
			fprintf(stderr, "%s is not a DMG file!\n", filename);
			return;
		}

		header2_byteorder_fix(&header2);

		chunk_size = header2.blocksize;
		// If this is a sparsebundle then there is no data to seek
		// to in this file so we skip over this particular check.
		if (!is_sparsebundle) {
			if (lseek(fd, header2.dataoffset, SEEK_SET) < 0) {
				fprintf(stderr, "Unable to seek in %s\n", filename);
				return;
			}
		}

		if(strstr(name, ".sparseimage") || is_sparsebundle) {
			// If this file is a sparseimage then we want one of the first chunks as the other chunks could be empty.
			cno = 1;
			data_size = 8192;
		} else {
			cno = ((header2.datasize + 4095ULL) / 4096) - 2;
			data_size = header2.datasize - cno * 4096ULL;
		}

		if (data_size < 0) {
			fprintf(stderr, "%s is not a valid DMG file!\n", filename);
			return;
		}

		for (i = 0; i < header2.keycount; i++) {

			// Seek to the start of the key header pointers offset by the current key which start immediately after the v2 header.
			if (lseek(fd, (sizeof(cencrypted_v2_header) + (sizeof(cencrypted_v2_key_header_pointer)*i)), SEEK_SET) < 0) {
				fprintf(stderr, "Unable to seek to header pointers in %s\n", filename);
				return;
			}

			// Read in the key header pointer
			count = read(fd, &header_pointer, sizeof(cencrypted_v2_key_header_pointer));
			if (count < 1 || count != sizeof(cencrypted_v2_key_header_pointer)) {
				fprintf(stderr, "Unable to read required data from %s\n", filename);
				return;
			}

			v2_key_header_pointer_byteorder_fix(&header_pointer);

			// We, currently, only care about the password key header. If it's not the password header type skip over it.
			if (header_pointer.header_type != 1) {
				continue;
			}

			// Seek to where the password key header is in the file.
			if (lseek(fd, header_pointer.header_offset, SEEK_SET) < 0) {
				fprintf(stderr, "Unable to seek to password header in %s\n", filename);
				return;
			}

			// Read in the password key header but avoid reading anything into the keyblob.
			count = read(fd, &v2_password_header, sizeof(cencrypted_v2_password_header) - sizeof(unsigned char *));
			if (count < 1 || count != (sizeof(cencrypted_v2_password_header) - sizeof(unsigned char *))) {
				fprintf(stderr, "Unable to read required data from %s\n", filename);
				return;
			}

			v2_password_header_byteorder_fix(&v2_password_header);

			// Allocate the keyblob memory
			v2_password_header.keyblob = mem_alloc(v2_password_header.keyblobsize);

			// Seek to the keyblob in the header
			if (lseek(fd, header_pointer.header_offset + sizeof(cencrypted_v2_password_header) - sizeof(unsigned char *), SEEK_SET) < 0) {
				fprintf(stderr, "Unable to seek to password header in %s\n", filename);
				free(v2_password_header.keyblob);
				return;
			}

			// Read in the keyblob
			count = read(fd, v2_password_header.keyblob, v2_password_header.keyblobsize);
			if (count < 1 || count != (v2_password_header.keyblobsize)) {
				fprintf(stderr, "Unable to read required data from %s\n", filename);
				free(v2_password_header.keyblob);
				return;
			}

			password_header_found = 1;

			// We only need one password header. Don't search any longer.
			break;
		}

		if (!password_header_found) {
			fprintf(stderr, "Password header not found in %s\n", filename);
			free(v2_password_header.keyblob);
			return;
		}

		if (v2_password_header.salt_size > 32) {
			fprintf(stderr, "%s is not a valid DMG file, salt length is too long!\n", filename);
			free(v2_password_header.keyblob);
			return;
		}

		fprintf(stderr, "%s (DMG v%d) successfully parsed, iterations "
		        "count %u\n", name, headerver,
		        v2_password_header.itercount);

		if (is_sparsebundle) {
			// If this is a sparsebundle then we need to get the chunks
			// of data out of 0 from the bands directory. Close the
			// previous file and open bands/0
			char *bands_path;
			if (close(fd) != 0) {
				fprintf(stderr, "Failed closing file %s\n", filename);
				free(v2_password_header.keyblob);
				return;
			}

			filepath_length = strnzcpyn(filepath, in_filepath, LARGE_ENOUGH);

			strnzcpyn(name, in_filepath, LARGE_ENOUGH);

			// See if we have enough room to append 'bands/0' to the path.
			if (filepath_length + 8 + 1 >= LARGE_ENOUGH) {
				fprintf(stderr, "Can't create bands path. Path too long.\n");
				free(v2_password_header.keyblob);
				return;
			}

			bands_path = strnzcat(filepath, "/bands/0", LARGE_ENOUGH);
			strnzcpyn(filepath, bands_path, LARGE_ENOUGH);
			strnzcpyn(name, filepath, LARGE_ENOUGH);
			if (!(filename = basename(name))) {
			    filename = filepath;
			}

			// Open the file for reading.
			fd = open(filepath, O_RDONLY);
			if (fd < 0) {
				fprintf(stderr, "Can't open file: %s\n", filename);
				return;
			}

			// Since we are in a different file the we can ignore the dataoffset
			header2.dataoffset = 0;
		}

		/* read starting chunk(s) */
		chunk1 = (unsigned char *) mem_alloc(data_size);
		if (lseek(fd, header2.dataoffset + cno * 4096LL, SEEK_SET) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			free(chunk1);
			free(v2_password_header.keyblob);
			return;
		}
		count = read(fd, chunk1, data_size);
		if (count < 1 || count != data_size) {
			fprintf(stderr, "Unable to read required data from %s\n", filename);
			free(chunk1);
			free(v2_password_header.keyblob);
			return;
		}
		/* read last chunk */
		if (lseek(fd, header2.dataoffset, SEEK_SET) < 0) {
			fprintf(stderr, "Unable to seek in %s\n", filename);
			free(chunk1);
			free(v2_password_header.keyblob);
			return;
		}
		count = read(fd, chunk2, 4096);
		if (count < 1 || count != 4096) {
			fprintf(stderr, "Unable to read required data from %s\n", filename);
			free(chunk1);
			free(v2_password_header.keyblob);
			return;
		}

		/* output hash */
		printf("%s:$dmg$%d*%d*", name, headerver, v2_password_header.salt_size);
		print_hex(v2_password_header.salt, v2_password_header.salt_size);
		printf("*32*");
		print_hex(v2_password_header.iv, 32);
		printf("*%d*", v2_password_header.keyblobsize);
		print_hex(v2_password_header.keyblob, v2_password_header.keyblobsize);
		printf("*%d*%d*", (int)cno, (int)data_size);
		print_hex(chunk1, data_size);
		printf("*1*");
		print_hex(chunk2, 4096);
		printf("*%u::::%s\n", v2_password_header.itercount, filename);

		free(chunk1);
		free(v2_password_header.keyblob);
	}
	close(fd);
}
示例#3
0
int do_regex_crack_as_rules(const char *regex, const char *base_word, int regex_case, const char *regex_alpha) {
	c_simplestring_ptr buffer = c_simplestring_new();
	c_iterator_ptr iter = NULL;
	charset encoding = CHARSET_UTF8;
	char word[WORDSIZE];
	static int bFirst=1;
	static int bALPHA=0;

	if (bFirst) {
		bFirst = 0;
		rexgen_setlocale();
		if (regex_alpha && !strncmp(regex_alpha, "alpha", 5)) {
			bALPHA = 1;
			SetupAlpha(regex_alpha);
		}
	}

	if (bALPHA) {
		// Ok, we do our own elete of the word,
		static char Buf[4096];
		char *cp = Buf;
		const char *cpi = base_word;
		while (*cpi) {
			cp += strnzcpyn (cp, rexgen_alphabets[(unsigned char)(*cpi)], 100);
			++cpi;
			if (cp - Buf > sizeof(Buf)-101)
				break;
		}
		*cp = 0;
		printf ("buf=%s\n", Buf);
		if (*regex == 0)
			regex = Buf;
		else {
			static char final_Buf[16384];
			int len = strlen(Buf)+1;
			cpi = regex;
			cp = final_Buf;
			while (*cpi) {
				if (*cpi == '\\' && cpi[1] == '0') {
					cp += strnzcpyn (cp, Buf, len);
					cpi += 2;
				} else
					*cp++ = *cpi++;

			}
			regex = final_Buf;
		}
	}

	strcpy(BaseWord, base_word);
	if (!regex[0]) {
		if (ext_filter("")) {
			if (crk_process_key(""))
				return 1;
		}
		return 0;
	}
	iter = c_regex_iterator_cb(regex, regex_case, encoding, callback);
	if (!iter) {
		fprintf(stderr, "Error, invalid regex expression.  John exiting now  base_word=%s  Regex= %s\n", base_word, regex);
		exit(1);
	}
	while (c_iterator_next(iter)) {
		c_iterator_value(iter, buffer);
		c_simplestring_to_binary_string(buffer, &word[0], sizeof(word));
		c_simplestring_clear(buffer);
		if (ext_filter((char*)word)) {
			if (crk_process_key((char*)word)) {
				c_simplestring_delete(buffer);
				c_iterator_delete(iter);
				return 1;
			}
		}
	}
	c_simplestring_delete(buffer);
	c_iterator_delete(iter);
	return 0;
}