diff --git a/nxc/modules/find-computer.py b/nxc/modules/find-computer.py index fa5dff4c..b227ec0c 100644 --- a/nxc/modules/find-computer.py +++ b/nxc/modules/find-computer.py @@ -35,7 +35,7 @@ class NXCModule: sys.exit(1) def on_login(self, context, connection): - search_filter = f"(&(objectCategory=computer)(&(|(operatingSystem=*{self.TEXT}*))(name=*{self.TEXT}*)))" + search_filter = f"(&(objectCategory=computer)(|(operatingSystem=*{self.TEXT}*)(name=*{self.TEXT}*)))" try: context.log.debug(f"Search Filter={search_filter}") diff --git a/nxc/modules/whoami.py b/nxc/modules/whoami.py index c33bf329..0855e89e 100644 --- a/nxc/modules/whoami.py +++ b/nxc/modules/whoami.py @@ -1,3 +1,7 @@ +import datetime +from nxc.parsers.ldap_results import parse_result_attributes + + class NXCModule: """ Basic enumeration of provided user information and privileges @@ -28,7 +32,7 @@ class NXCModule: searchFilter=searchFilter, attributes=[ "name", - "sAmAccountName", + "sAMAccountName", "description", "distinguishedName", "pwdLastSet", @@ -36,35 +40,95 @@ class NXCModule: "lastLogon", "userAccountControl", "servicePrincipalName", + "userPrincipalName", + "objectSid", + "mail", + "badPwdCount", "memberOf", ], sizeLimit=999, ) - for response in r[0]["attributes"]: - if "userAccountControl" in str(response["type"]): - if str(response["vals"][0]) == "512": - context.log.highlight("Enabled: Yes") - context.log.highlight("Password Never Expires: No") - elif str(response["vals"][0]) == "514": - context.log.highlight("Enabled: No") - context.log.highlight("Password Never Expires: No") - elif str(response["vals"][0]) == "66048": - context.log.highlight("Enabled: Yes") - context.log.highlight("Password Never Expires: Yes") - elif str(response["vals"][0]) == "66050": - context.log.highlight("Enabled: No") - context.log.highlight("Password Never Expires: Yes") - elif "lastLogon" in str(response["type"]): - if str(response["vals"][0]) == "1601": + resp_parsed = parse_result_attributes(r) + + for response in resp_parsed: + + # Process name + if "name" in response: + context.log.highlight(f"Name: {response['name']}") + + # Process Description + if "description" in response: + context.log.highlight(f"Description: {response['description']}") + + # Process sAMAccountName + if "sAMAccountName" in response: + context.log.highlight(f"sAMAccountName: {response['sAMAccountName']}") + + # Process userAccountControl + if "userAccountControl" in response: + uac = int(response["userAccountControl"]) + ACCOUNTDISABLE = 0x0002 + DONT_EXPIRE_PASSWORD = 0x10000 + is_disabled = (uac & ACCOUNTDISABLE) != 0 + password_never_expires = (uac & DONT_EXPIRE_PASSWORD) != 0 + context.log.highlight(f"Enabled: {'No' if is_disabled else 'Yes'}") + context.log.highlight(f"Password Never Expires: {'Yes' if password_never_expires else 'No'}") + + # Process User PrincipalName + if "userPrincipalName" in response: + context.log.highlight(f"User Principal Name: {response['userPrincipalName']}") + + # Process mail + if "mail" in response: + context.log.highlight(f"Email: {response['mail']}") + + # Process lastLogon + if "lastLogon" in response: + filetime_str = response["lastLogon"] + filetime_int = int(filetime_str) + if filetime_int == 0: context.log.highlight("Last logon: Never") else: - context.log.highlight(f"Last logon: {response['vals'][0]}") - elif "memberOf" in str(response["type"]): - for group in response["vals"]: - context.log.highlight(f"Member of: {group}") - elif "servicePrincipalName" in str(response["type"]): + dt = datetime.datetime(1601, 1, 1) + datetime.timedelta(microseconds=filetime_int / 10) + context.log.highlight(f"Last logon: {dt.strftime('%Y-%m-%d %H:%M:%S')} UTC") + + # Process pwdLastSet + if "pwdLastSet" in response: + filetime_str = response["pwdLastSet"] + filetime_int = int(filetime_str) + if filetime_int == 0: + context.log.highlight("Password Last Set: Never") + else: + dt = datetime.datetime(1601, 1, 1) + datetime.timedelta(microseconds=filetime_int / 10) + context.log.highlight(f"Password Last Set: {dt.strftime('%Y-%m-%d %H:%M:%S')} UTC") + + # Process Bad Password Count + if "badPwdCount" in response: + context.log.highlight(f"Bad Passwod Count: {response['badPwdCount']}") + + # Process servicePrincipalName + if "servicePrincipalName" in response: context.log.highlight("Service Account Name(s) found - Potentially Kerberoastable user!") - for spn in response["vals"]: - context.log.highlight(f"Service Account Name: {spn}") - else: - context.log.highlight(response["type"] + ": " + response["vals"][0]) + spns = response["servicePrincipalName"] + if isinstance(spns, list): + for spn in spns: + context.log.highlight(f"Service Account Name: {spn}") + else: + context.log.highlight(f"Service Account Name: {spns}") + + # Process DistinguishedName + if "distinguishedName" in response: + context.log.highlight(f"Distinguished Name: {response['distinguishedName']}") + + # Process memberOf + if "memberOf" in response: + groups = response["memberOf"] + if isinstance(groups, list): + for group in groups: + context.log.highlight(f"Member of: {group}") + else: + context.log.highlight(f"Member of: {groups}") + + # Process User Sid + if "objectSid" in response: + context.log.highlight(f"User SID: {response['objectSid']}")