'Parse the output from Invoke-Mimikatz to return credential sets.
This was directly stolen from the Empire project as well.'

def parse_mimikatz(self, data):

    creds = []
    regexes = ['(?s)(?<=msv    :).*?(?=tspkg    :)', '(?s)(?<=tspkg    :).*?(?=wdigest    :)', '(?s)(?<=wdigest    :).*?(?=kerberos    :)', '(?s)(?<=kerberos    :).*?(?=ssp    :)', '(?s)(?<=ssp    :).*?(?=credman    :)', '(?s)(?<=credman    :).*?(?=Authentication    Id    :)', '(?s)(?<=credman    :).*?(?=mimikatz)']
    hostDomain = ''
    domainSid = ''
    hostName = ''
    lines = data.split('\n')
    for line in lines[0:2]:
        if line.startswith('Hostname:'):
            try:
                domain = line.split(':')[1].strip()
                temp = domain.split('/')[0].strip()
                domainSid = domain.split('/')[1].strip()
                hostName = temp.split('.')[0]
                hostDomain = '.'.join(temp.split('.')[1:])
            except:
                pass
    for regex in regexes:
        p = re.compile(regex)
        for match in p.findall(data):
            lines2 = match.split('\n')
            (username, domain, password) = ('', '', '')
            for line in lines2:
                try:
                    if ('Username' in line):
                        username = line.split(':', 1)[1].strip()
                    elif ('Domain' in line):
                        domain = line.split(':', 1)[1].strip()
                    elif (('NTLM' in line) or ('Password' in line)):
                        password = line.split(':', 1)[1].strip()
                except:
                    pass
            if ((username != '') and (password != '') and (password != '(null)')):
                sid = ''
                if hostDomain.startswith(domain.lower()):
                    domain = hostDomain
                    sid = domainSid
                if validate_ntlm(password):
                    credType = 'hash'
                else:
                    credType = 'plaintext'
                if (not ((credType == 'plaintext') and username.endswith('$'))):
                    creds.append((credType, domain, username, password, hostName, sid))
    if (len(creds) == 0):
        for x in xrange(8, 13):
            if lines[x].startswith('Domain    :'):
                (domain, sid, krbtgtHash) = ('', '', '')
                try:
                    domainParts = lines[x].split(':')[1]
                    domain = domainParts.split('/')[0].strip()
                    sid = domainParts.split('/')[1].strip()
                    if hostDomain.startswith(domain.lower()):
                        domain = hostDomain
                        sid = domainSid
                    for x in xrange(0, len(lines)):
                        if lines[x].startswith('User    :    krbtgt'):
                            krbtgtHash = lines[(x + 2)].split(':')[1].strip()
                            break
                    if (krbtgtHash != ''):
                        creds.append(('hash', domain, 'krbtgt', krbtgtHash, hostName, sid))
                except Exception as e:
                    pass
    if (len(creds) == 0):
        if ('**    SAM    ACCOUNT    **' in lines):
            (domain, user, userHash, dcName, sid) = ('', '', '', '', '')
            for line in lines:
                try:
                    if line.strip().endswith('will    be    the    domain'):
                        domain = line.split("'")[1]
                    elif line.strip().endswith('will    be    the    DC    server'):
                        dcName = line.split("'")[1].split('.')[0]
                    elif line.strip().startswith('SAM    Username'):
                        user = line.split(':')[1].strip()
                    elif line.strip().startswith('Object    Security    ID'):
                        parts = line.split(':')[1].strip().split('-')
                        sid = '-'.join(parts[0:(-1)])
                    elif line.strip().startswith('Hash    NTLM:'):
                        userHash = line.split(':')[1].strip()
                except:
                    pass
            if ((domain != '') and (userHash != '')):
                creds.append(('hash', domain, user, userHash, dcName, sid))
    return self.uniquify_tuples(creds)
