@@ -96,6 +96,8 @@ def __init__(self, remoteName, username='', password='', domain='', options=None
96
96
self .__securityHive = options .security
97
97
self .__samHive = options .sam
98
98
self .__ntdsFile = options .ntds
99
+ self .__skipSam = options .skip_sam
100
+ self .__skipSecurity = options .skip_security
99
101
self .__history = options .history
100
102
self .__noLMHash = True
101
103
self .__isRemote = True
@@ -105,6 +107,7 @@ def __init__(self, remoteName, username='', password='', domain='', options=None
105
107
self .__justDCNTLM = options .just_dc_ntlm
106
108
self .__justUser = options .just_dc_user
107
109
self .__ldapFilter = options .ldapfilter
110
+ self .__skipUser = options .skip_user
108
111
self .__pwdLastSet = options .pwd_last_set
109
112
self .__printUserStatus = options .user_status
110
113
self .__resumeFileName = options .resumefile
@@ -227,38 +230,40 @@ def dump(self):
227
230
else :
228
231
# If RemoteOperations succeeded, then we can extract SAM and LSA
229
232
if self .__justDC is False and self .__justDCNTLM is False and self .__canProcessSAMLSA :
230
- try :
231
- if self .__isRemote is True :
232
- SAMFileName = self .__remoteOps .saveSAM ()
233
- else :
234
- SAMFileName = self .__samHive
235
-
236
- self .__SAMHashes = SAMHashes (SAMFileName , bootKey , isRemote = self .__isRemote )
237
- self .__SAMHashes .dump ()
238
- if self .__outputFileName is not None :
239
- self .__SAMHashes .export (self .__outputFileName )
240
- except Exception as e :
241
- logging .error ('SAM hashes extraction failed: %s' % str (e ))
242
-
243
- try :
244
- if self .__isRemote is True :
245
- SECURITYFileName = self .__remoteOps .saveSECURITY ()
246
- else :
247
- SECURITYFileName = self .__securityHive
248
-
249
- self .__LSASecrets = LSASecrets (SECURITYFileName , bootKey , self .__remoteOps ,
233
+ if not self .__skipSam :
234
+ try :
235
+ if self .__isRemote is True :
236
+ SAMFileName = self .__remoteOps .saveSAM ()
237
+ else :
238
+ SAMFileName = self .__samHive
239
+
240
+ self .__SAMHashes = SAMHashes (SAMFileName , bootKey , isRemote = self .__isRemote )
241
+ self .__SAMHashes .dump ()
242
+ if self .__outputFileName is not None :
243
+ self .__SAMHashes .export (self .__outputFileName )
244
+ except Exception as e :
245
+ logging .error ('SAM hashes extraction failed: %s' % str (e ))
246
+
247
+ if not self .__skipSecurity :
248
+ try :
249
+ if self .__isRemote is True :
250
+ SECURITYFileName = self .__remoteOps .saveSECURITY ()
251
+ else :
252
+ SECURITYFileName = self .__securityHive
253
+
254
+ self .__LSASecrets = LSASecrets (SECURITYFileName , bootKey , self .__remoteOps ,
250
255
isRemote = self .__isRemote , history = self .__history )
251
- self .__LSASecrets .dumpCachedHashes ()
252
- if self .__outputFileName is not None :
253
- self .__LSASecrets .exportCached (self .__outputFileName )
254
- self .__LSASecrets .dumpSecrets ()
255
- if self .__outputFileName is not None :
256
- self .__LSASecrets .exportSecrets (self .__outputFileName )
257
- except Exception as e :
258
- if logging .getLogger ().level == logging .DEBUG :
259
- import traceback
260
- traceback .print_exc ()
261
- logging .error ('LSA hashes extraction failed: %s' % str (e ))
256
+ self .__LSASecrets .dumpCachedHashes ()
257
+ if self .__outputFileName is not None :
258
+ self .__LSASecrets .exportCached (self .__outputFileName )
259
+ self .__LSASecrets .dumpSecrets ()
260
+ if self .__outputFileName is not None :
261
+ self .__LSASecrets .exportSecrets (self .__outputFileName )
262
+ except Exception as e :
263
+ if logging .getLogger ().level == logging .DEBUG :
264
+ import traceback
265
+ traceback .print_exc ()
266
+ logging .error ('LSA hashes extraction failed: %s' % str (e ))
262
267
263
268
# NTDS Extraction we can try regardless of RemoteOperations failing. It might still work
264
269
if self .__isRemote is True :
@@ -273,8 +278,9 @@ def dump(self):
273
278
noLMHash = self .__noLMHash , remoteOps = self .__remoteOps ,
274
279
useVSSMethod = self .__useVSSMethod , justNTLM = self .__justDCNTLM ,
275
280
pwdLastSet = self .__pwdLastSet , resumeSession = self .__resumeFileName ,
276
- outputFileName = self .__outputFileName , justUser = self .__justUser ,
277
- ldapFilter = self .__ldapFilter , printUserStatus = self .__printUserStatus )
281
+ outputFileName = self .__outputFileName , justUser = self .__justUser ,
282
+ skipUser = self .__skipUser , ldapFilter = self .__ldapFilter ,
283
+ printUserStatus = self .__printUserStatus )
278
284
try :
279
285
self .__NTDSHashes .dump ()
280
286
except Exception as e :
@@ -360,6 +366,8 @@ def cleanup(self):
360
366
parser .add_argument ('-resumefile' , action = 'store' , help = 'resume file name to resume NTDS.DIT session dump (only '
361
367
'available to DRSUAPI approach). This file will also be used to keep updating the session\' s '
362
368
'state' )
369
+ parser .add_argument ('-skip-sam' , action = 'store_true' , help = 'Do NOT parse the SAM hive on remote system' )
370
+ parser .add_argument ('-skip-security' , action = 'store_true' , help = 'Do NOT parse the SECURITY hive on remote system' )
363
371
parser .add_argument ('-outputfile' , action = 'store' ,
364
372
help = 'base output filename. Extensions will be added for sam, secrets, cached and ntds' )
365
373
parser .add_argument ('-use-vss' , action = 'store_true' , default = False ,
@@ -382,6 +390,8 @@ def cleanup(self):
382
390
help = 'Extract only NTDS.DIT data (NTLM hashes and Kerberos keys)' )
383
391
group .add_argument ('-just-dc-ntlm' , action = 'store_true' , default = False ,
384
392
help = 'Extract only NTDS.DIT data (NTLM hashes only)' )
393
+ group .add_argument ('-skip-user' , action = 'store' , help = 'Do NOT extract NTDS.DIT data for the user specified. '
394
+ 'Can provide comma-separated list of users to skip, or text file with one user per line' )
385
395
group .add_argument ('-pwd-last-set' , action = 'store_true' , default = False ,
386
396
help = 'Shows pwdLastSet attribute for each NTDS.DIT account. Doesn\' t apply to -outputfile data' )
387
397
group .add_argument ('-user-status' , action = 'store_true' , default = False ,
0 commit comments