Skip to content

Commit e721917

Browse files
authored
Merge pull request Pennyw0rth#695 from Cyb3rC3lt/main
Updated whoami and find-computer modules
2 parents 844af80 + e9d1700 commit e721917

2 files changed

Lines changed: 91 additions & 27 deletions

File tree

nxc/modules/find-computer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def options(self, context, module_options):
3535
sys.exit(1)
3636

3737
def on_login(self, context, connection):
38-
search_filter = f"(&(objectCategory=computer)(&(|(operatingSystem=*{self.TEXT}*))(name=*{self.TEXT}*)))"
38+
search_filter = f"(&(objectCategory=computer)(|(operatingSystem=*{self.TEXT}*)(name=*{self.TEXT}*)))"
3939

4040
try:
4141
context.log.debug(f"Search Filter={search_filter}")

nxc/modules/whoami.py

Lines changed: 90 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import datetime
2+
from nxc.parsers.ldap_results import parse_result_attributes
3+
4+
15
class NXCModule:
26
"""
37
Basic enumeration of provided user information and privileges
@@ -28,43 +32,103 @@ def on_login(self, context, connection):
2832
searchFilter=searchFilter,
2933
attributes=[
3034
"name",
31-
"sAmAccountName",
35+
"sAMAccountName",
3236
"description",
3337
"distinguishedName",
3438
"pwdLastSet",
3539
"logonCount",
3640
"lastLogon",
3741
"userAccountControl",
3842
"servicePrincipalName",
43+
"userPrincipalName",
44+
"objectSid",
45+
"mail",
46+
"badPwdCount",
3947
"memberOf",
4048
],
4149
sizeLimit=999,
4250
)
43-
for response in r[0]["attributes"]:
44-
if "userAccountControl" in str(response["type"]):
45-
if str(response["vals"][0]) == "512":
46-
context.log.highlight("Enabled: Yes")
47-
context.log.highlight("Password Never Expires: No")
48-
elif str(response["vals"][0]) == "514":
49-
context.log.highlight("Enabled: No")
50-
context.log.highlight("Password Never Expires: No")
51-
elif str(response["vals"][0]) == "66048":
52-
context.log.highlight("Enabled: Yes")
53-
context.log.highlight("Password Never Expires: Yes")
54-
elif str(response["vals"][0]) == "66050":
55-
context.log.highlight("Enabled: No")
56-
context.log.highlight("Password Never Expires: Yes")
57-
elif "lastLogon" in str(response["type"]):
58-
if str(response["vals"][0]) == "1601":
51+
resp_parsed = parse_result_attributes(r)
52+
53+
for response in resp_parsed:
54+
55+
# Process name
56+
if "name" in response:
57+
context.log.highlight(f"Name: {response['name']}")
58+
59+
# Process Description
60+
if "description" in response:
61+
context.log.highlight(f"Description: {response['description']}")
62+
63+
# Process sAMAccountName
64+
if "sAMAccountName" in response:
65+
context.log.highlight(f"sAMAccountName: {response['sAMAccountName']}")
66+
67+
# Process userAccountControl
68+
if "userAccountControl" in response:
69+
uac = int(response["userAccountControl"])
70+
ACCOUNTDISABLE = 0x0002
71+
DONT_EXPIRE_PASSWORD = 0x10000
72+
is_disabled = (uac & ACCOUNTDISABLE) != 0
73+
password_never_expires = (uac & DONT_EXPIRE_PASSWORD) != 0
74+
context.log.highlight(f"Enabled: {'No' if is_disabled else 'Yes'}")
75+
context.log.highlight(f"Password Never Expires: {'Yes' if password_never_expires else 'No'}")
76+
77+
# Process User PrincipalName
78+
if "userPrincipalName" in response:
79+
context.log.highlight(f"User Principal Name: {response['userPrincipalName']}")
80+
81+
# Process mail
82+
if "mail" in response:
83+
context.log.highlight(f"Email: {response['mail']}")
84+
85+
# Process lastLogon
86+
if "lastLogon" in response:
87+
filetime_str = response["lastLogon"]
88+
filetime_int = int(filetime_str)
89+
if filetime_int == 0:
5990
context.log.highlight("Last logon: Never")
6091
else:
61-
context.log.highlight(f"Last logon: {response['vals'][0]}")
62-
elif "memberOf" in str(response["type"]):
63-
for group in response["vals"]:
64-
context.log.highlight(f"Member of: {group}")
65-
elif "servicePrincipalName" in str(response["type"]):
92+
dt = datetime.datetime(1601, 1, 1) + datetime.timedelta(microseconds=filetime_int / 10)
93+
context.log.highlight(f"Last logon: {dt.strftime('%Y-%m-%d %H:%M:%S')} UTC")
94+
95+
# Process pwdLastSet
96+
if "pwdLastSet" in response:
97+
filetime_str = response["pwdLastSet"]
98+
filetime_int = int(filetime_str)
99+
if filetime_int == 0:
100+
context.log.highlight("Password Last Set: Never")
101+
else:
102+
dt = datetime.datetime(1601, 1, 1) + datetime.timedelta(microseconds=filetime_int / 10)
103+
context.log.highlight(f"Password Last Set: {dt.strftime('%Y-%m-%d %H:%M:%S')} UTC")
104+
105+
# Process Bad Password Count
106+
if "badPwdCount" in response:
107+
context.log.highlight(f"Bad Passwod Count: {response['badPwdCount']}")
108+
109+
# Process servicePrincipalName
110+
if "servicePrincipalName" in response:
66111
context.log.highlight("Service Account Name(s) found - Potentially Kerberoastable user!")
67-
for spn in response["vals"]:
68-
context.log.highlight(f"Service Account Name: {spn}")
69-
else:
70-
context.log.highlight(response["type"] + ": " + response["vals"][0])
112+
spns = response["servicePrincipalName"]
113+
if isinstance(spns, list):
114+
for spn in spns:
115+
context.log.highlight(f"Service Account Name: {spn}")
116+
else:
117+
context.log.highlight(f"Service Account Name: {spns}")
118+
119+
# Process DistinguishedName
120+
if "distinguishedName" in response:
121+
context.log.highlight(f"Distinguished Name: {response['distinguishedName']}")
122+
123+
# Process memberOf
124+
if "memberOf" in response:
125+
groups = response["memberOf"]
126+
if isinstance(groups, list):
127+
for group in groups:
128+
context.log.highlight(f"Member of: {group}")
129+
else:
130+
context.log.highlight(f"Member of: {groups}")
131+
132+
# Process User Sid
133+
if "objectSid" in response:
134+
context.log.highlight(f"User SID: {response['objectSid']}")

0 commit comments

Comments
 (0)