mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-15 11:08:21 +00:00
172 lines
5.5 KiB
Python
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()
|