mirror of
https://github.com/Pennyw0rth/NetExec
synced 2026-06-06 16:34:30 +00:00
Merge pull request #695 from Cyb3rC3lt/main
Updated whoami and find-computer modules
This commit is contained in:
@@ -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}")
|
||||
|
||||
+90
-26
@@ -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']}")
|
||||
|
||||
Reference in New Issue
Block a user