Skip to content

Commit 1f4acea

Browse files
authored
Merge pull request Pennyw0rth#1177 from ledrypotato/pre2k-module-adjustment
Adjust the pre2k module
2 parents 3e4a7bc + 121d6c4 commit 1f4acea

2 files changed

Lines changed: 49 additions & 18 deletions

File tree

nxc/modules/pre2k.py

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,28 @@ class NXCModule:
1919
category = CATEGORY.PRIVILEGE_ESCALATION
2020

2121
def options(self, context, module_options):
22-
"""No options available"""
22+
"""
23+
ALL Attempt to authenticate for every computer object in the domain (default: False)
24+
25+
Examples:
26+
nxc ldap $IP -u $USER -p $PASSWORD -M pre2k
27+
nxc ldap $IP -u $USER -p $PASSWORD -M pre2k -o ALL=True
28+
"""
29+
self.all_option = module_options.get("ALL", "").lower() in ["true", "1", "yes"]
2330

2431
def on_login(self, context, connection):
25-
# Define the search filter for pre-created computer accounts
26-
search_filter = "(&(objectClass=computer)(userAccountControl=4128))"
32+
# Define the search filter
33+
if self.all_option:
34+
search_filter = "(&(objectClass=computer))"
35+
else:
36+
search_filter = "(&(objectClass=computer)(userAccountControl=4128))" # 4128 = 4096 (WORKSTATION_TRUST_ACCOUNT) | 32 (WORKSTATION_TRUST_ACCOUNT)
37+
2738
attributes = ["sAMAccountName", "userAccountControl", "dNSHostName"]
2839

2940
context.log.info(f"Using search filter: {search_filter}")
3041
context.log.info(f"Attributes to retrieve: {attributes}")
3142

32-
computers = []
43+
computers = {}
3344

3445
try:
3546
# Use paged search to retrieve all computer accounts with specific flags
@@ -39,27 +50,39 @@ def on_login(self, context, connection):
3950

4051
for computer in results:
4152
context.log.debug(f"Processing computer: {computer['sAMAccountName']}, UAC: {computer['userAccountControl']}")
42-
# Check if the account is a pre-created computer account
43-
if int(computer["userAccountControl"]) == 4128: # 4096 | 32
44-
computers.append(computer["sAMAccountName"])
45-
context.log.debug(f"Added computer: {computer['sAMAccountName']}")
53+
computers[computer["sAMAccountName"]] = computer["userAccountControl"]
54+
context.log.debug(f"Added computer: {computer['sAMAccountName']}")
4655

4756
# Save computers to file
4857
domain_dir = os.path.join(f"{NXC_PATH}/modules/pre2k", connection.domain)
49-
output_file = os.path.join(domain_dir, "precreated_computers.txt")
58+
output_file_pre2k = os.path.join(domain_dir, "precreated_computers.txt")
59+
output_file_non_pre2k = os.path.join(domain_dir, "non_precreated_computers.txt")
5060

5161
# Create directories if they do not exist
5262
os.makedirs(domain_dir, exist_ok=True)
5363

54-
with open(output_file, "w") as file:
55-
for computer in computers:
56-
file.write(f"{computer}\n")
64+
with open(output_file_pre2k, "w") as pre2k_file, open(output_file_non_pre2k, "w") as non_pre2k_file:
65+
for computer, uac in computers.items():
66+
if int(uac) == 4128:
67+
pre2k_file.write(f"{computer}\n")
68+
else:
69+
non_pre2k_file.write(f"{computer}\n")
5770

58-
# Print discovered pre-created computer accounts
71+
# Print discovered (pre-created) computer accounts
5972
if computers:
60-
for computer in computers:
61-
context.log.highlight(f"Pre-created computer account: {computer}")
62-
context.log.success(f"Found {len(computers)} pre-created computer accounts. Saved to {output_file}")
73+
for computer, uac in computers.items():
74+
if int(uac) == 4128:
75+
context.log.highlight(f"Pre-created computer account: {computer}")
76+
else:
77+
context.log.debug(f"Computer account: {computer}")
78+
79+
counter_pre2k = len([v for v in computers.values() if int(v) == 4128])
80+
counter_non_pre2k = len([v for v in computers.values() if int(v) != 4128])
81+
82+
if counter_pre2k != 0:
83+
context.log.success(f"Found {counter_pre2k} pre-created computer accounts. Saved to {output_file_pre2k}")
84+
if counter_non_pre2k != 0:
85+
context.log.success(f"Found {counter_non_pre2k} normal computer accounts. Saved to {output_file_non_pre2k}")
6386
else:
6487
context.log.info("No pre-created computer accounts found.")
6588

@@ -76,7 +99,7 @@ def on_login(self, context, connection):
7699

77100
# Summary of TGT results
78101
if successful_tgts > 0:
79-
context.log.success(f"Successfully obtained TGT for {successful_tgts} pre-created computer accounts. Saved to {ccache_base_dir}")
102+
context.log.success(f"Successfully obtained TGT for {successful_tgts} (pre-created) computer accounts. Saved to {ccache_base_dir}")
80103
except Exception as e:
81104
context.log.fail(f"Error occurred during search: {e}")
82105

@@ -101,7 +124,13 @@ def get_tgt(self, context, username, domain, kdcHost, ccache_base_dir):
101124
context.log.success(f"Successfully obtained TGT for {username}@{domain}")
102125
return True
103126
except Exception as e:
104-
context.log.fail(f"Failed to get TGT for {username}@{domain}: {e}")
127+
if "KDC_ERR_PREAUTH_FAILED" in str(e):
128+
if self.all_option:
129+
context.log.debug(f"Failed to get TGT for {username}@{domain}: KDC_ERR_PREAUTH_FAILED")
130+
else:
131+
context.log.fail(f"Failed to get TGT for {username}@{domain}: KDC_ERR_PREAUTH_FAILED")
132+
else:
133+
context.log.fail(f"Error obtaining TGT for {username}@{domain}: {e}")
105134
return False
106135

107136
def save_ticket(self, context, username, ticket, sessionKey, ccache_base_dir):

tests/e2e_commands.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M get-net
229229
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M groupmembership -o USER=LOGIN_USERNAME
230230
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M laps
231231
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M maq
232+
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pre2k
233+
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pre2k -o ALL=true
232234
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M subnets
233235
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M user-desc
234236
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M whoami

0 commit comments

Comments
 (0)