1
0
mirror of https://github.com/hashcat/hashcat.git synced 2025-08-04 12:56:00 +00:00

Fixed keys extraction in luks2hashcat (now extracts all LUKS2 keyslots), fixed file permissions for module 34200, 34201, 34211

This commit is contained in:
Gabriele Gristina 2025-08-01 01:59:07 +02:00
parent 81892335b8
commit 68c536aca8
No known key found for this signature in database
GPG Key ID: 9F68B59298F311F0
5 changed files with 44 additions and 39 deletions

View File

@ -159,6 +159,7 @@
- Fixed incompatible pointer types (salt1 and salt2 buf) in 3730 a3 kernel
- Fixed incorrect plaintext check for 25400 and 26610. Increased plaintext check to 32 bytes to prevent false positives.
- Fixed keys extraction in luks2hashcat - now extracts all active keys
- Fixed keys extraction in luks2hashcat - now extracts all LUKS2 keyslots
- Fixed maximum password length in module/test_module of hash-mode 2400
- Fixed maximum password length in module/test_module of hash-mode 2410
- Fixed memory leaks in tuning_db_init in tuningdb.c

0
src/modules/module_34200.c Executable file → Normal file
View File

0
src/modules/module_34201.c Executable file → Normal file
View File

0
src/modules/module_34211.c Executable file → Normal file
View File

View File

@ -230,7 +230,7 @@ def extract_version1(file):
# read header
header = file.read(header_struct.size)
if len(header) < header_struct.size:
raise ValueError("file contains less data than needed")
raise ValueError("file contains less data than needed (invalid header len)")
# convert bytes into temporary header
header = header_struct.unpack(header)
@ -245,7 +245,7 @@ def extract_version1(file):
file.seek(key.material_offset * SECTOR_SIZE, SEEK_SET)
af = file.read(header.key_bytes * key.stripes)
if len(af) < (header.key_bytes * key.stripes):
raise ValueError("file contains less data than needed")
raise ValueError("file contains less data than needed (invalid af len)")
key = KeyVersion1(key.active, key.iterations, key.salt, af)
keys.append(key)
@ -254,7 +254,7 @@ def extract_version1(file):
file.seek(header.payload_offset * SECTOR_SIZE, SEEK_SET)
payload = file.read(PAYLOAD_SIZE)
if len(payload) < PAYLOAD_SIZE:
raise ValueError("file contains less data than needed")
raise ValueError("file contains less data than needed (invalid payload len)")
if sum(payload) == 0:
raise ValueError("file not initialized - payload contains zeros only")
@ -315,51 +315,55 @@ def extract_version2(file):
json_header = json.loads(json_data[:json_end])
# print("\nWe got the following large json header:\n")
# print(json.dumps(json_header, indent=4))
#print(json.dumps(json_header, indent=4))
keyslot_offset = int(json_header['keyslots']['0']['area']['offset'])
keyslot_size = int(json_header['keyslots']['0']['area']['key_size'])
encryption = json_header['keyslots']['0']['area']['encryption']
keyslots_cnt = len(json_header['keyslots'])
if keyslots_cnt == 0:
raise ValueError("no keyslots founds")
(cipher_type, cipher_mode) = tuple(encryption.split("-", 1))
file.seek(keyslot_offset)
keyslot_encrypted_data = file.read(256000) #don't yet know how to calculate this length exactly
blocknumbers = int(json_header['keyslots']['0']['af']['stripes'])
hash_mode = json_header['keyslots']['0']['af']['hash']
# Include first sector of the segment for entropy check
# extract first sector of the segment for entropy check
segment_offset = int(json_header['segments']['0']['offset'])
file.seek(segment_offset)
first_sector = file.read(512)
kdf = json_header['keyslots']['0']['kdf']['type']
time = int(json_header['keyslots']['0']['kdf']['time'])
memory = int(json_header['keyslots']['0']['kdf']['memory'])
cpus = int(json_header['keyslots']['0']['kdf']['cpus'])
salt = b64decode(json_header['keyslots']['0']['kdf']['salt'])
for key in json_header['keyslots']:
print(key)
keyslot_offset = int(json_header['keyslots'][key]['area']['offset'])
encryption = json_header['keyslots'][key]['area']['encryption']
stripes = int(json_header['keyslots'][key]['af']['stripes'])
key_size = int(json_header['keyslots'][key]['key_size'])
key_size = int(json_header['keyslots']['0']['key_size']) * 8
(cipher_type, cipher_mode) = tuple(encryption.split("-", 1))
hash = SIGNATURE + "$".join(
map(
str,
[
HeaderVersion2.VERSION,
kdf,
hash_mode,
cipher_type,
cipher_mode,
key_size,
f"m={memory},t={time},p={cpus}",
salt.hex(),
keyslot_encrypted_data.hex(),
first_sector.hex(),
],
file.seek(keyslot_offset)
keyslot_encrypted_data = file.read(key_size * stripes)
hash_mode = json_header['keyslots'][key]['af']['hash']
kdf = json_header['keyslots'][key]['kdf']['type']
time = int(json_header['keyslots'][key]['kdf']['time'])
memory = int(json_header['keyslots'][key]['kdf']['memory'])
cpus = int(json_header['keyslots'][key]['kdf']['cpus'])
salt = b64decode(json_header['keyslots'][key]['kdf']['salt'])
hash = SIGNATURE + "$".join(
map(
str,
[
HeaderVersion2.VERSION,
kdf,
hash_mode,
cipher_type,
cipher_mode,
key_size * 8,
f"m={memory},t={time},p={cpus}",
salt.hex(),
keyslot_encrypted_data.hex(),
first_sector.hex(),
],
)
)
)
print(hash)
print(hash)
# main