docs: def parse_mimikatz(self, data):
          """
          Parse the output from Invoke-Mimikatz to return credential sets.
  
          This was directly stolen from the Empire project as well.
          """
  
          # cred format:
          #   credType, domain, username, password, hostname, sid
          creds = []
  
          # regexes for "sekurlsa::logonpasswords" Mimikatz output
          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 = ""
  
                      # substitute the FQDN in if it matches
                      if hostDomain.startswith(domain.lower()):
                          domain = hostDomain
                          sid = domainSid
  
                      if validate_ntlm(password):
                          credType = "hash"
  
                      else:
                          credType = "plaintext"
  
                      # ignore machine account plaintexts
                      if not (credType == "plaintext" and username.endswith("$")):
                          creds.append((credType, domain, username, password, hostName, sid))
  
          if len(creds) == 0:
              # check if we have lsadump output to check for krbtgt
              #   happens on domain controller hashdumps
              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()
  
                          # substitute the FQDN in if it matches
                          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:
              # check if we get lsadump::dcsync output
              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)