Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added user-status functionality to the SAMHashes Class of the secrestdump.py #1847

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions examples/secretsdump.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# Impacket - Collection of Python classes for working with network protocols.
#
# Copyright Fortra, LLC and its affiliated companies
# Copyright Fortra, LLC and its affiliated companies
#
# All rights reserved.
#
Expand Down Expand Up @@ -72,6 +72,7 @@
except NameError:
pass


class DumpSecrets:
def __init__(self, remoteName, username='', password='', domain='', options=None):
self.__useVSSMethod = options.use_vss
Expand Down Expand Up @@ -111,7 +112,7 @@ def __init__(self, remoteName, username='', password='', domain='', options=None
self.__ldapFilter = options.ldapfilter
self.__skipUser = options.skip_user
self.__pwdLastSet = options.pwd_last_set
self.__printUserStatus= options.user_status
self.__printUserStatus = options.user_status
self.__resumeFileName = options.resumefile
self.__canProcessSAMLSA = True
self.__kdcHost = options.dc_ip
Expand Down Expand Up @@ -215,7 +216,7 @@ def dump(self):
localOperations = LocalOperations(self.__systemHive)
bootKey = localOperations.getBootKey()
if self.__ntdsFile is not None:
# Let's grab target's configuration about LM Hashes storage
# Let's grab target's configuration about LM Hashes storage
self.__noLMHash = localOperations.checkNoLMHashPolicy()
else:
import binascii
Expand Down Expand Up @@ -243,7 +244,7 @@ def dump(self):
else:
raise

self.__remoteOps = RemoteOperations(self.__smbConnection, self.__doKerberos, self.__kdcHost, self.__ldapConnection)
self.__remoteOps = RemoteOperations(self.__smbConnection, self.__doKerberos, self.__kdcHost, self.__ldapConnection)
self.__remoteOps.setExecMethod(self.__options.exec_method)
if self.__justDC is False and self.__justDCNTLM is False and self.__useKeyListMethod is False or self.__useVSSMethod is True:
self.__remoteOps.enableRegistry()
Expand All @@ -253,7 +254,7 @@ def dump(self):
except Exception as e:
self.__canProcessSAMLSA = False
if str(e).find('STATUS_USER_SESSION_DELETED') and os.getenv('KRB5CCNAME') is not None \
and self.__doKerberos is True:
and self.__doKerberos is True:
# Giving some hints here when SPN target name validation is set to something different to Off
# This will prevent establishing SMB connections using TGS for SPNs different to cifs/
logging.error('Policy SPN target name validation might be restricting full DRSUAPI dump. Try -just-dc-user')
Expand All @@ -276,8 +277,7 @@ def dump(self):
SAMFileName = self.__remoteOps.saveSAM()
else:
SAMFileName = self.__samHive

self.__SAMHashes = SAMHashes(SAMFileName, bootKey, isRemote = self.__isRemote)
self.__SAMHashes = SAMHashes(SAMFileName, bootKey, isRemote=self.__isRemote, printUserStatus=self.__printUserStatus)
self.__SAMHashes.dump()
if self.__outputFileName is not None:
self.__SAMHashes.export(self.__outputFileName)
Expand All @@ -292,7 +292,7 @@ def dump(self):
SECURITYFileName = self.__securityHive

self.__LSASecrets = LSASecrets(SECURITYFileName, bootKey, self.__remoteOps,
isRemote=self.__isRemote, history=self.__history)
isRemote=self.__isRemote, history=self.__history)
self.__LSASecrets.dumpCachedHashes()
if self.__outputFileName is not None:
self.__LSASecrets.exportCached(self.__outputFileName)
Expand All @@ -318,7 +318,7 @@ def dump(self):
noLMHash=self.__noLMHash, remoteOps=self.__remoteOps,
useVSSMethod=self.__useVSSMethod, justNTLM=self.__justDCNTLM,
pwdLastSet=self.__pwdLastSet, resumeSession=self.__resumeFileName,
outputFileName=self.__outputFileName, justUser=self.__justUser,
outputFileName=self.__outputFileName, justUser=self.__justUser,
skipUser=self.__skipUser, ldapFilter=self.__ldapFilter,
printUserStatus=self.__printUserStatus)
try:
Expand Down Expand Up @@ -349,7 +349,7 @@ def dump(self):
if self.__NTDSHashes is not None:
if isinstance(e, KeyboardInterrupt):
while True:
answer = input("Delete resume session file? [y/N] ")
answer = input("Delete resume session file? [y/N] ")
if answer.upper() == '':
answer = 'N'
break
Expand Down Expand Up @@ -391,8 +391,8 @@ def cleanup(self):

print(version.BANNER)

parser = argparse.ArgumentParser(add_help = True, description = "Performs various techniques to dump secrets from "
"the remote machine without executing any agent there.")
parser = argparse.ArgumentParser(add_help=True, description="Performs various techniques to dump secrets from "
"the remote machine without executing any agent there.")

parser.add_argument('target', action='store', help='[[domain/]username[:password]@]<targetName or address> or LOCAL'
' (if you want to parse local files)')
Expand All @@ -404,8 +404,8 @@ def cleanup(self):
parser.add_argument('-sam', action='store', help='SAM hive to parse')
parser.add_argument('-ntds', action='store', help='NTDS.DIT file to parse')
parser.add_argument('-resumefile', action='store', help='resume file name to resume NTDS.DIT session dump (only '
'available to DRSUAPI approach). This file will also be used to keep updating the session\'s '
'state')
'available to DRSUAPI approach). This file will also be used to keep updating the session\'s '
'state')
parser.add_argument('-skip-sam', action='store_true', help='Do NOT parse the SAM hive on remote system')
parser.add_argument('-skip-security', action='store_true', help='Do NOT parse the SECURITY hive on remote system')
parser.add_argument('-outputfile', action='store',
Expand Down Expand Up @@ -433,35 +433,35 @@ def cleanup(self):
help='Extract only NTDS.DIT data for specific users based on an LDAP filter. '
'Only available for DRSUAPI approach. Implies also -just-dc switch')
group.add_argument('-just-dc', action='store_true', default=False,
help='Extract only NTDS.DIT data (NTLM hashes and Kerberos keys)')
help='Extract only NTDS.DIT data (NTLM hashes and Kerberos keys)')
group.add_argument('-just-dc-ntlm', action='store_true', default=False,
help='Extract only NTDS.DIT data (NTLM hashes only)')
group.add_argument('-skip-user', action='store', help='Do NOT extract NTDS.DIT data for the user specified. '
'Can provide comma-separated list of users to skip, or text file with one user per line')
'Can provide comma-separated list of users to skip, or text file with one user per line')
group.add_argument('-pwd-last-set', action='store_true', default=False,
help='Shows pwdLastSet attribute for each NTDS.DIT account. Doesn\'t apply to -outputfile data')
group.add_argument('-user-status', action='store_true', default=False,
help='Display whether or not the user is disabled')
help='Display whether or not the user is disabled')
group.add_argument('-history', action='store_true', help='Dump password history, and LSA secrets OldVal')

group = parser.add_argument_group('authentication')
group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH')
group.add_argument('-hashes', action="store", metavar="LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH')
group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)')
group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file '
'(KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use'
' the ones specified in the command line')
group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication'
' (128 or 256 bits)')
'(KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use'
' the ones specified in the command line')
group.add_argument('-aesKey', action="store", metavar="hex key", help='AES key to use for Kerberos Authentication'
' (128 or 256 bits)')
group.add_argument('-keytab', action="store", help='Read keys for SPN from keytab file')

group = parser.add_argument_group('connection')
group.add_argument('-dc-ip', action='store',metavar = "ip address", help='IP Address of the domain controller. If '
'ommited it use the domain part (FQDN) specified in the target parameter')
group.add_argument('-dc-ip', action='store', metavar="ip address", help='IP Address of the domain controller. If '
'ommited it use the domain part (FQDN) specified in the target parameter')
group.add_argument('-target-ip', action='store', metavar="ip address",
help='IP Address of the target machine. If omitted it will use whatever was specified as target. '
'This is useful when target is the NetBIOS name and you cannot resolve it')

if len(sys.argv)==1:
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)

Expand Down
Loading