mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-23 06:58:31 +00:00
Merge pull request #4139 from zyronix/feature/keybag2hashcat
Adding keybag2hashcat.py script
This commit is contained in:
commit
4cdda7c208
171
tools/keybag2hashcat.py
Normal file
171
tools/keybag2hashcat.py
Normal file
@ -0,0 +1,171 @@
|
||||
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()
|
Loading…
Reference in New Issue
Block a user