From 0eee328ea044cd6b1456b92a2e97bd1b418e53bd Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Wed, 20 Mar 2024 21:59:38 -0400 Subject: [PATCH 1/9] feat(ldap): allow for specifying specific users to dump for ldap and print last password set date --- nxc/parsers/ldap_results.py | 13 ++++++ nxc/protocols/ldap.py | 78 +++++++++++++++++++------------- nxc/protocols/ldap/proto_args.py | 3 +- 3 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 nxc/parsers/ldap_results.py diff --git a/nxc/parsers/ldap_results.py b/nxc/parsers/ldap_results.py new file mode 100644 index 000000000..206fad8ba --- /dev/null +++ b/nxc/parsers/ldap_results.py @@ -0,0 +1,13 @@ +from impacket.ldap import ldapasn1 as ldapasn1_impacket + +def parse_result_attributes(ldap_response): + parsed_response = [] + for entry in ldap_response: + # SearchResultReferences may be returned + if not isinstance(entry, ldapasn1_impacket.SearchResultEntry): + continue + attribute_map = {} + for attribute in entry["attributes"]: + attribute_map[str(attribute["type"])] = str(attribute["vals"][0]) + parsed_response.append(attribute_map) + return parsed_response \ No newline at end of file diff --git a/nxc/protocols/ldap.py b/nxc/protocols/ldap.py index a21fe324f..2d90d8225 100644 --- a/nxc/protocols/ldap.py +++ b/nxc/protocols/ldap.py @@ -5,7 +5,7 @@ import os import socket from binascii import hexlify -from datetime import datetime +from datetime import datetime, timedelta from re import sub, I from zipfile import ZipFile from termcolor import colored @@ -38,6 +38,7 @@ from nxc.protocols.ldap.bloodhound import BloodHound from nxc.protocols.ldap.gmsa import MSDS_MANAGEDPASSWORD_BLOB from nxc.protocols.ldap.kerberos import KerberosAttacks +from nxc.parsers.ldap_results import parse_result_attributes ldap_error_status = { "1": "STATUS_NOT_SUPPORTED", @@ -753,37 +754,51 @@ def search(self, searchFilter, attributes, sizeLimit=0): return False def users(self): - # Building the search filter - search_filter = "(sAMAccountType=805306368)" if self.username != "" else "(objectclass=*)" - attributes = [ - "sAMAccountName", - "description", - "badPasswordTime", - "badPwdCount", - "pwdLastSet", - ] - - resp = self.search(search_filter, attributes, sizeLimit=0) + """ + Retrieves user information from the LDAP server. + + Args: + input_attributes (list): Optional. List of attributes to retrieve for each user. + TODO: allow users to pass this in + + Returns: + None + """ + if len(self.args.users) > 1: + self.logger.display(f"Trying to dumping users: {', '.join(self.args.users)}") + search_filter = f"(|{''.join(f'(sAMAccountName={user})' for user in self.args.users)})" + else: + self.logger.info("Trying to dump all users") + search_filter = "(sAMAccountType=805306368)" if self.username != "" else "(objectclass=*)" + + # default to these attributes to mirror the SMB --users functionality + request_attributes = self.args.ldap_attributes + self.logger.debug(f"{request_attributes=}") + + resp = self.search(search_filter, request_attributes, sizeLimit=0) if resp: - self.logger.display(f"Total of records returned {len(resp):d}") - for item in resp: - if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True: - continue - sAMAccountName = "" - description = "" - try: - if self.username == "": - self.logger.highlight(f"{item['objectName']}") - else: - for attribute in item["attributes"]: - if str(attribute["type"]) == "sAMAccountName": - sAMAccountName = str(attribute["vals"][0]) - elif str(attribute["type"]) == "description": - description = str(attribute["vals"][0]) - self.logger.highlight(f"{sAMAccountName:<30} {description}") - except Exception as e: - self.logger.debug(f"Skipping item, cannot process due to error {e}") - return + # I think this was here for anonymous ldap bindings, so I kept it, but we might just want to remove it + if self.username == "": + self.logger.display(f"Total records returned: {len(resp):d}") + for item in resp: + if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True: + continue + self.logger.highlight(f"{item['objectName']}") + return + + users = parse_result_attributes(resp) + # we print the total records after we parse the results since often SearchResultReferences are returned + self.logger.display(f"Total records returned: {len(users):d}") + self.logger.highlight(f"{'Username':<30} {'Last PW Set':<20}\t{'Description'}") # header + for user in users: + self.logger.debug(f"{user=}") + # we default attributes to blank strings if they don't exist in the dict + timestamp_seconds = int(user.get('pwdLastSet', '')) / 10**7 + start_date = datetime(1601, 1, 1) + parsed_pw_last_set = (start_date + timedelta(seconds=timestamp_seconds)).replace(microsecond=0).strftime("%Y-%m-%d %H:%M:%S") + if parsed_pw_last_set == "1601-01-01 00:00:00": + parsed_pw_last_set = "" + self.logger.highlight(f"{user.get('sAMAccountName', ''):<30} {parsed_pw_last_set:<20}\t{user.get('description', '')}") def groups(self): # Building the search filter @@ -1390,3 +1405,4 @@ def bloodhound(self): if each_file.startswith(self.output_filename.split("/")[-1]) and each_file.endswith("json"): z.write(each_file) os.remove(each_file) + diff --git a/nxc/protocols/ldap/proto_args.py b/nxc/protocols/ldap/proto_args.py index ff5866e00..5c46a2b3b 100644 --- a/nxc/protocols/ldap/proto_args.py +++ b/nxc/protocols/ldap/proto_args.py @@ -20,11 +20,12 @@ def proto_args(parser, std_parser, module_parser): vgroup.add_argument("--trusted-for-delegation", action="store_true", help="Get the list of users and computers with flag TRUSTED_FOR_DELEGATION") vgroup.add_argument("--password-not-required", action="store_true", help="Get the list of users with flag PASSWD_NOTREQD") vgroup.add_argument("--admin-count", action="store_true", help="Get objets that had the value adminCount=1") - vgroup.add_argument("--users", action="store_true", help="Enumerate enabled domain users") + vgroup.add_argument("--users", nargs="*", help="Enumerate enabled domain users") vgroup.add_argument("--groups", action="store_true", help="Enumerate domain groups") vgroup.add_argument("--dc-list", action="store_true", help="Enumerate Domain Controllers") vgroup.add_argument("--get-sid", action="store_true", help="Get domain sid") vgroup.add_argument("--active-users", action="store_true", help="Get Active Domain Users Accounts") + vgroup.add_argument("--ldap-attributes", nargs="+", default=["sAMAccountName", "description", "pwdLastSet"], help="Attributes to search for") ggroup = ldap_parser.add_argument_group("Retrevie gmsa on the remote DC", "Options to play with gmsa") ggroup.add_argument("--gmsa", action="store_true", help="Enumerate GMSA passwords") From 762a9ac102f93aa9945f317f8fca40d7313b86af Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Wed, 20 Mar 2024 22:23:26 -0400 Subject: [PATCH 2/9] feat(ldap): allow for adding additional attributes when querying for users --- nxc/protocols/ldap.py | 9 ++++----- nxc/protocols/ldap/proto_args.py | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/nxc/protocols/ldap.py b/nxc/protocols/ldap.py index 2d90d8225..57fca3acb 100644 --- a/nxc/protocols/ldap.py +++ b/nxc/protocols/ldap.py @@ -759,7 +759,6 @@ def users(self): Args: input_attributes (list): Optional. List of attributes to retrieve for each user. - TODO: allow users to pass this in Returns: None @@ -772,7 +771,8 @@ def users(self): search_filter = "(sAMAccountType=805306368)" if self.username != "" else "(objectclass=*)" # default to these attributes to mirror the SMB --users functionality - request_attributes = self.args.ldap_attributes + default_attributes = ["sAMAccountName", "description", "pwdLastSet"] + request_attributes = default_attributes + self.args.ldap_attributes if self.args.ldap_attributes else default_attributes self.logger.debug(f"{request_attributes=}") resp = self.search(search_filter, request_attributes, sizeLimit=0) @@ -789,7 +789,7 @@ def users(self): users = parse_result_attributes(resp) # we print the total records after we parse the results since often SearchResultReferences are returned self.logger.display(f"Total records returned: {len(users):d}") - self.logger.highlight(f"{'Username':<30} {'Last PW Set':<20}\t{'Description'}") # header + self.logger.highlight(f"{'Username':<30} {'Last PW Set':<20}\t{'Description':<60} " + ' '.join(f"{a}" for a in self.args.ldap_attributes) if self.args.ldap_attributes else '') for user in users: self.logger.debug(f"{user=}") # we default attributes to blank strings if they don't exist in the dict @@ -798,8 +798,7 @@ def users(self): parsed_pw_last_set = (start_date + timedelta(seconds=timestamp_seconds)).replace(microsecond=0).strftime("%Y-%m-%d %H:%M:%S") if parsed_pw_last_set == "1601-01-01 00:00:00": parsed_pw_last_set = "" - self.logger.highlight(f"{user.get('sAMAccountName', ''):<30} {parsed_pw_last_set:<20}\t{user.get('description', '')}") - + self.logger.highlight(f"{user.get('sAMAccountName', ''):<30} {parsed_pw_last_set:<20}\t{user.get('description', ''):<60} " + ' '.join(f"{user.get(a, '')}" for a in self.args.ldap_attributes) if self.args.ldap_attributes else '') def groups(self): # Building the search filter search_filter = "(objectCategory=group)" diff --git a/nxc/protocols/ldap/proto_args.py b/nxc/protocols/ldap/proto_args.py index 5c46a2b3b..2b70c39b4 100644 --- a/nxc/protocols/ldap/proto_args.py +++ b/nxc/protocols/ldap/proto_args.py @@ -1,4 +1,4 @@ -from argparse import _StoreTrueAction +from argparse import _StoreTrueAction, Action def proto_args(parser, std_parser, module_parser): @@ -25,8 +25,8 @@ def proto_args(parser, std_parser, module_parser): vgroup.add_argument("--dc-list", action="store_true", help="Enumerate Domain Controllers") vgroup.add_argument("--get-sid", action="store_true", help="Get domain sid") vgroup.add_argument("--active-users", action="store_true", help="Get Active Domain Users Accounts") - vgroup.add_argument("--ldap-attributes", nargs="+", default=["sAMAccountName", "description", "pwdLastSet"], help="Attributes to search for") - + vgroup.add_argument("--ldap-attributes", nargs="+", help="Additional attributes to search for (appends to default list)") + ggroup = ldap_parser.add_argument_group("Retrevie gmsa on the remote DC", "Options to play with gmsa") ggroup.add_argument("--gmsa", action="store_true", help="Enumerate GMSA passwords") ggroup.add_argument("--gmsa-convert-id", help="Get the secret name of specific gmsa or all gmsa if no gmsa provided") @@ -52,4 +52,4 @@ def __call__(self, parser, namespace, values, option_string=None): x.required = True super().__call__(parser, namespace, values, option_string) - return ConditionalAction + return ConditionalAction \ No newline at end of file From 3a1e93a3865a94dc3db703e59c6e27644ad4e1e6 Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Thu, 21 Mar 2024 11:01:46 -0400 Subject: [PATCH 3/9] ruff: apply ruff --- nxc/protocols/ldap.py | 8 +++++--- nxc/protocols/ldap/proto_args.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/nxc/protocols/ldap.py b/nxc/protocols/ldap.py index 57fca3acb..2f62ede8b 100644 --- a/nxc/protocols/ldap.py +++ b/nxc/protocols/ldap.py @@ -758,9 +758,11 @@ def users(self): Retrieves user information from the LDAP server. Args: + ---- input_attributes (list): Optional. List of attributes to retrieve for each user. Returns: + ------- None """ if len(self.args.users) > 1: @@ -789,16 +791,16 @@ def users(self): users = parse_result_attributes(resp) # we print the total records after we parse the results since often SearchResultReferences are returned self.logger.display(f"Total records returned: {len(users):d}") - self.logger.highlight(f"{'Username':<30} {'Last PW Set':<20}\t{'Description':<60} " + ' '.join(f"{a}" for a in self.args.ldap_attributes) if self.args.ldap_attributes else '') + self.logger.highlight(f"{'Username':<30} {'Last PW Set':<20}\t{'Description':<60} " + " ".join(f"{a}" for a in self.args.ldap_attributes) if self.args.ldap_attributes else "") for user in users: self.logger.debug(f"{user=}") # we default attributes to blank strings if they don't exist in the dict - timestamp_seconds = int(user.get('pwdLastSet', '')) / 10**7 + timestamp_seconds = int(user.get("pwdLastSet", "")) / 10**7 start_date = datetime(1601, 1, 1) parsed_pw_last_set = (start_date + timedelta(seconds=timestamp_seconds)).replace(microsecond=0).strftime("%Y-%m-%d %H:%M:%S") if parsed_pw_last_set == "1601-01-01 00:00:00": parsed_pw_last_set = "" - self.logger.highlight(f"{user.get('sAMAccountName', ''):<30} {parsed_pw_last_set:<20}\t{user.get('description', ''):<60} " + ' '.join(f"{user.get(a, '')}" for a in self.args.ldap_attributes) if self.args.ldap_attributes else '') + self.logger.highlight(f"{user.get('sAMAccountName', ''):<30} {parsed_pw_last_set:<20}\t{user.get('description', ''):<60} " + " ".join(f"{user.get(a, '')}" for a in self.args.ldap_attributes) if self.args.ldap_attributes else "") def groups(self): # Building the search filter search_filter = "(objectCategory=group)" diff --git a/nxc/protocols/ldap/proto_args.py b/nxc/protocols/ldap/proto_args.py index 2b70c39b4..07af8697e 100644 --- a/nxc/protocols/ldap/proto_args.py +++ b/nxc/protocols/ldap/proto_args.py @@ -1,4 +1,4 @@ -from argparse import _StoreTrueAction, Action +from argparse import _StoreTrueAction def proto_args(parser, std_parser, module_parser): From 6a4852e0137b8adb64c5788fe94131a1c079db6f Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Thu, 21 Mar 2024 19:20:05 -0400 Subject: [PATCH 4/9] fix/feat: remove unnecessary and ugly ldap-attributes functionality; add in badPwdCount to --users --- nxc/protocols/ldap.py | 14 ++++++-------- nxc/protocols/ldap/proto_args.py | 1 - 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/nxc/protocols/ldap.py b/nxc/protocols/ldap.py index 2f62ede8b..a834a9e49 100644 --- a/nxc/protocols/ldap.py +++ b/nxc/protocols/ldap.py @@ -773,11 +773,9 @@ def users(self): search_filter = "(sAMAccountType=805306368)" if self.username != "" else "(objectclass=*)" # default to these attributes to mirror the SMB --users functionality - default_attributes = ["sAMAccountName", "description", "pwdLastSet"] - request_attributes = default_attributes + self.args.ldap_attributes if self.args.ldap_attributes else default_attributes - self.logger.debug(f"{request_attributes=}") - + request_attributes = ["sAMAccountName", "description", "badPwdCount", "pwdLastSet"] resp = self.search(search_filter, request_attributes, sizeLimit=0) + if resp: # I think this was here for anonymous ldap bindings, so I kept it, but we might just want to remove it if self.username == "": @@ -791,16 +789,16 @@ def users(self): users = parse_result_attributes(resp) # we print the total records after we parse the results since often SearchResultReferences are returned self.logger.display(f"Total records returned: {len(users):d}") - self.logger.highlight(f"{'Username':<30} {'Last PW Set':<20}\t{'Description':<60} " + " ".join(f"{a}" for a in self.args.ldap_attributes) if self.args.ldap_attributes else "") + self.logger.highlight(f"{'-Username-':<30}{'-Last PW Set-':<20}{'-BadPW-':<8}{'-Description-':<60}") for user in users: - self.logger.debug(f"{user=}") - # we default attributes to blank strings if they don't exist in the dict + # TODO: functionize this - we do this calculation in a bunch of places, different, including in the `pso` module timestamp_seconds = int(user.get("pwdLastSet", "")) / 10**7 start_date = datetime(1601, 1, 1) parsed_pw_last_set = (start_date + timedelta(seconds=timestamp_seconds)).replace(microsecond=0).strftime("%Y-%m-%d %H:%M:%S") if parsed_pw_last_set == "1601-01-01 00:00:00": parsed_pw_last_set = "" - self.logger.highlight(f"{user.get('sAMAccountName', ''):<30} {parsed_pw_last_set:<20}\t{user.get('description', ''):<60} " + " ".join(f"{user.get(a, '')}" for a in self.args.ldap_attributes) if self.args.ldap_attributes else "") + # we default attributes to blank strings if they don't exist in the dict + self.logger.highlight(f"{user.get('sAMAccountName', ''):<30}{parsed_pw_last_set:<20}{user.get('badPwdCount', ''):<8}{user.get('description', ''):<60}") def groups(self): # Building the search filter search_filter = "(objectCategory=group)" diff --git a/nxc/protocols/ldap/proto_args.py b/nxc/protocols/ldap/proto_args.py index 07af8697e..6125ebb92 100644 --- a/nxc/protocols/ldap/proto_args.py +++ b/nxc/protocols/ldap/proto_args.py @@ -25,7 +25,6 @@ def proto_args(parser, std_parser, module_parser): vgroup.add_argument("--dc-list", action="store_true", help="Enumerate Domain Controllers") vgroup.add_argument("--get-sid", action="store_true", help="Get domain sid") vgroup.add_argument("--active-users", action="store_true", help="Get Active Domain Users Accounts") - vgroup.add_argument("--ldap-attributes", nargs="+", help="Additional attributes to search for (appends to default list)") ggroup = ldap_parser.add_argument_group("Retrevie gmsa on the remote DC", "Options to play with gmsa") ggroup.add_argument("--gmsa", action="store_true", help="Enumerate GMSA passwords") From 14e70343523f35e4309e6580622f26854cb7099a Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Fri, 22 Mar 2024 00:56:51 +0100 Subject: [PATCH 5/9] Formating --- nxc/protocols/ldap.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/nxc/protocols/ldap.py b/nxc/protocols/ldap.py index a834a9e49..6e7150bb2 100644 --- a/nxc/protocols/ldap.py +++ b/nxc/protocols/ldap.py @@ -373,7 +373,6 @@ def kerberos_login( used_ccache = " from ccache" if useCache else f":{process_secret(kerb_pass)}" out = f"{domain}\\{self.username}{used_ccache} {self.mark_pwned()}" - self.logger.extra["protocol"] = "LDAP" self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389" self.logger.success(out) @@ -764,18 +763,18 @@ def users(self): Returns: ------- None - """ + """ if len(self.args.users) > 1: self.logger.display(f"Trying to dumping users: {', '.join(self.args.users)}") search_filter = f"(|{''.join(f'(sAMAccountName={user})' for user in self.args.users)})" else: - self.logger.info("Trying to dump all users") + self.logger.info("Trying to dump all users") search_filter = "(sAMAccountType=805306368)" if self.username != "" else "(objectclass=*)" - + # default to these attributes to mirror the SMB --users functionality - request_attributes = ["sAMAccountName", "description", "badPwdCount", "pwdLastSet"] + request_attributes = ["sAMAccountName", "description", "badPwdCount", "pwdLastSet"] resp = self.search(search_filter, request_attributes, sizeLimit=0) - + if resp: # I think this was here for anonymous ldap bindings, so I kept it, but we might just want to remove it if self.username == "": @@ -785,7 +784,7 @@ def users(self): continue self.logger.highlight(f"{item['objectName']}") return - + users = parse_result_attributes(resp) # we print the total records after we parse the results since often SearchResultReferences are returned self.logger.display(f"Total records returned: {len(users):d}") @@ -799,6 +798,7 @@ def users(self): parsed_pw_last_set = "" # we default attributes to blank strings if they don't exist in the dict self.logger.highlight(f"{user.get('sAMAccountName', ''):<30}{parsed_pw_last_set:<20}{user.get('badPwdCount', ''):<8}{user.get('description', ''):<60}") + def groups(self): # Building the search filter search_filter = "(objectCategory=group)" @@ -867,7 +867,7 @@ def active_users(self): elif str(attribute["type"]) == "userAccountControl": userAccountControl = int(attribute["vals"][0]) account_disabled = userAccountControl & 2 - if not account_disabled: + if not account_disabled: self.logger.highlight(f"{sAMAccountName}") except Exception as e: self.logger.debug(f"Skipping item, cannot process due to error {e}") @@ -1404,4 +1404,3 @@ def bloodhound(self): if each_file.startswith(self.output_filename.split("/")[-1]) and each_file.endswith("json"): z.write(each_file) os.remove(each_file) - From 49e909c50a56c1a2d56d169d12f968eb40c66646 Mon Sep 17 00:00:00 2001 From: Alexander Neff Date: Fri, 22 Mar 2024 01:00:04 +0100 Subject: [PATCH 6/9] Formating --- nxc/protocols/ldap/proto_args.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nxc/protocols/ldap/proto_args.py b/nxc/protocols/ldap/proto_args.py index 6125ebb92..ba1be223a 100644 --- a/nxc/protocols/ldap/proto_args.py +++ b/nxc/protocols/ldap/proto_args.py @@ -25,7 +25,7 @@ def proto_args(parser, std_parser, module_parser): vgroup.add_argument("--dc-list", action="store_true", help="Enumerate Domain Controllers") vgroup.add_argument("--get-sid", action="store_true", help="Get domain sid") vgroup.add_argument("--active-users", action="store_true", help="Get Active Domain Users Accounts") - + ggroup = ldap_parser.add_argument_group("Retrevie gmsa on the remote DC", "Options to play with gmsa") ggroup.add_argument("--gmsa", action="store_true", help="Enumerate GMSA passwords") ggroup.add_argument("--gmsa-convert-id", help="Get the secret name of specific gmsa or all gmsa if no gmsa provided") @@ -51,4 +51,4 @@ def __call__(self, parser, namespace, values, option_string=None): x.required = True super().__call__(parser, namespace, values, option_string) - return ConditionalAction \ No newline at end of file + return ConditionalAction From e5bba812e8674f014c6001ed26636ebd20e5fe97 Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Thu, 21 Mar 2024 20:12:29 -0400 Subject: [PATCH 7/9] fix(ldap): off by one :) --- nxc/protocols/ldap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nxc/protocols/ldap.py b/nxc/protocols/ldap.py index 6e7150bb2..3913eb0cf 100644 --- a/nxc/protocols/ldap.py +++ b/nxc/protocols/ldap.py @@ -764,7 +764,7 @@ def users(self): ------- None """ - if len(self.args.users) > 1: + if len(self.args.users) > 0: self.logger.display(f"Trying to dumping users: {', '.join(self.args.users)}") search_filter = f"(|{''.join(f'(sAMAccountName={user})' for user in self.args.users)})" else: From b0ec4b79510e7d128163a464c678517536d44036 Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Thu, 21 Mar 2024 20:16:43 -0400 Subject: [PATCH 8/9] fix(smb): --users display off by one :) --- nxc/protocols/smb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index cc3e5faa2..54b52a468 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -1000,7 +1000,7 @@ def groups(self): return groups def users(self): - if len(self.args.users) > 1: + if len(self.args.users) > 0: self.logger.display(f"Dumping users: {', '.join(self.args.users)}") else: self.logger.info("Trying to dump local users with SAMRPC protocol") From 40e99913e380d5c69501e3e0ddef83d3e39b6e81 Mon Sep 17 00:00:00 2001 From: Marshall Hallenbeck Date: Thu, 21 Mar 2024 20:45:39 -0400 Subject: [PATCH 9/9] change extra output to debug statement --- nxc/protocols/ldap.py | 4 ++-- nxc/protocols/smb.py | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/nxc/protocols/ldap.py b/nxc/protocols/ldap.py index 3913eb0cf..b1e03cc6e 100644 --- a/nxc/protocols/ldap.py +++ b/nxc/protocols/ldap.py @@ -765,10 +765,10 @@ def users(self): None """ if len(self.args.users) > 0: - self.logger.display(f"Trying to dumping users: {', '.join(self.args.users)}") + self.logger.debug(f"Dumping users: {', '.join(self.args.users)}") search_filter = f"(|{''.join(f'(sAMAccountName={user})' for user in self.args.users)})" else: - self.logger.info("Trying to dump all users") + self.logger.debug("Trying to dump all users") search_filter = "(sAMAccountType=805306368)" if self.username != "" else "(objectclass=*)" # default to these attributes to mirror the SMB --users functionality diff --git a/nxc/protocols/smb.py b/nxc/protocols/smb.py index 54b52a468..8b9b5a801 100755 --- a/nxc/protocols/smb.py +++ b/nxc/protocols/smb.py @@ -1001,9 +1001,7 @@ def groups(self): def users(self): if len(self.args.users) > 0: - self.logger.display(f"Dumping users: {', '.join(self.args.users)}") - else: - self.logger.info("Trying to dump local users with SAMRPC protocol") + self.logger.debug(f"Dumping users: {', '.join(self.args.users)}") return UserSamrDump(self).dump(self.args.users)