1
0
mirror of https://github.com/hashcat/hashcat.git synced 2025-07-15 11:08:21 +00:00
hashcat/tools/keybag2hashcat.py
2024-12-22 19:30:35 +01:00

172 lines
5.5 KiB
Python

import argparse
import logging
import sys
__VERSION__ = '1.0.0'
# Set up logging
logger = logging.getLogger("keybag_logger")
handler = logging.StreamHandler()
formatter = logging.Formatter('%(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
class Keybag:
def __init__(self, file_obj):
self.size = 0
self.uuid = ''
self.version = 0
self.type = 0
self.hmackey = ''
self.wrap = 0
self.salt = ''
self.iterations = 0
self._read_header(file_obj)
self.class_keys = self._read_class_keys(file_obj)
def _read_header(self, file_obj):
while True:
tag = file_obj.read(4).decode('ascii')
if tag == 'DATA': # DATA
self.size = int.from_bytes(file_obj.read(4), byteorder='big')
else:
length = int.from_bytes(file_obj.read(4), byteorder='big')
data = file_obj.read(length)
if tag == 'VERS': # VERS
self.version = int.from_bytes(data, byteorder='big')
elif tag == 'TYPE':
self.type = int.from_bytes(data, byteorder='big')
elif tag == 'UUID':
if not self.uuid:
self.uuid = data.hex()
else:
file_obj.seek(-length - 8, 1)
break
elif tag == 'HMCK':
self.hmackey = data.hex()
elif tag == 'WRAP':
self.wrap = int.from_bytes(data, byteorder='big')
elif tag == 'SALT':
self.salt = data.hex()
elif tag == 'ITER':
self.iterations = int.from_bytes(data, byteorder='big')
def _read_class_keys(self, file_obj):
class_keys = {}
for x in range(0, 10):
stop = False
while stop != True:
tag = file_obj.read(4).decode('ascii')
length = int.from_bytes(file_obj.read(4), byteorder='big')
data = file_obj.read(length)
# new class key
if tag == 'UUID':
if class_keys.get(x):
if class_keys[x].get('UUID'):
file_obj.seek(-length - 8, 1)
stop = True
else:
class_keys[x] = {}
else:
class_keys[x] = {}
if tag == 'WRAP' or tag == 'CLAS' or tag == 'KTYP':
class_keys[x][tag] = int.from_bytes(data, byteorder='big')
else:
class_keys[x][tag] = data.hex()
if file_obj.tell() > self.size:
stop = True
return class_keys
def print_keybag(self):
logger.debug(f'SIZE: {self.size}')
logger.debug(f'VERSION: {self.version}')
logger.debug(f'TYPE: {self.type}')
logger.debug(f'UUID: {self.uuid}')
logger.debug(f'HMACKEY: {self.hmackey}')
logger.debug(f'SALT: {self.salt}')
logger.debug(f'ITERATIONS: {self.iterations}')
for x, class_key in self.class_keys.items():
logger.debug(f'{x}:')
for key, value in class_key.items():
logger.debug(f' {key}: {value}')
def main():
# Create the argument parser
parser = argparse.ArgumentParser(description="Process a keybag file with a specified UID.")
# Add the UID argument
parser.add_argument(
'--uid',
type=str,
required=True,
help="Specify the device UID."
)
# Add the keybag file argument
parser.add_argument(
'keybag',
type=str,
help="Path to the keybag file."
)
# Add the debug flag
parser.add_argument(
'--debug',
action='store_true',
help="Enable debug logging."
)
# Parse the arguments
args = parser.parse_args()
if args.debug:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.WARNING)
# Access the arguments
uid = args.uid[0:32]
keybag_path = args.keybag
logger.debug(f'keybag2hashcat - version {__VERSION__}')
with open(keybag_path, 'br') as keybag_file:
kb = Keybag(keybag_file)
kb.print_keybag()
if not kb.version:
logger.error('Unable to detect version of keybag, exiting.')
sys.exit(1)
if not kb.salt:
logger.error('Unable to detect salt, exiting.')
sys.exit(1)
if not kb.iterations:
logger.error('Unable to detect iterations, exiting.')
sys.exit(1)
if not kb.version in [3, 4]:
logger.error(f'This script has not been tested with version {kb.version}.')
sys.exit(1)
if not kb.class_keys:
logger.error(f'Unable to parse class keys, exiting.')
sys.exit(1)
classkey1 = 0
for x, class_key in kb.class_keys.items():
if class_key.get('WRAP') == 3:
class_type = class_key.get('CLAS')
if class_type == 1 or class_type == 33:
classkey1 = class_key.get('WPKY')
if not classkey1:
logger.error(f'Unable to find a classkey of class NSFileProtectionComplete.')
logger.error(f'You could try to get another class key, make sure it is ktyp 0 and wrap 3.')
exit(1)
print(f'$uido${uid}${kb.salt}${kb.iterations}${classkey1}')
if __name__ == "__main__":
main()