Skip to content

Commit 0641534

Browse files
committed
Fix bug where modules would be the same object across protocols
1 parent 2f62e1c commit 0641534

2 files changed

Lines changed: 25 additions & 39 deletions

File tree

nxc/connection.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from nxc.config import pwned_label
1010
from nxc.helpers.logger import highlight
11+
from nxc.loaders.moduleloader import ModuleLoader
1112
from nxc.logger import nxc_logger, NXCAdapter
1213
from nxc.context import Context
1314
from nxc.protocols.ldap.laps import laps_search
@@ -145,16 +146,7 @@ def create_conn_obj(self):
145146
def check_if_admin(self):
146147
return
147148

148-
def kerberos_login(
149-
self,
150-
domain,
151-
username,
152-
password="",
153-
ntlm_hash="",
154-
aesKey="",
155-
kdcHost="",
156-
useCache=False,
157-
):
149+
def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False):
158150
return
159151

160152
def plaintext_login(self, domain, username, password):
@@ -173,6 +165,7 @@ def proto_flow(self):
173165
self.enum_host_info()
174166
if self.print_host_info() and (self.login() or (self.username == "" and self.password == "")):
175167
if hasattr(self.args, "module") and self.args.module:
168+
self.load_modules()
176169
self.logger.debug("Calling modules")
177170
self.call_modules()
178171
else:
@@ -206,7 +199,7 @@ def call_modules(self):
206199
It iterates over the modules specified in the command line arguments.
207200
For each module, it loads the module and creates a context object, then calls functions based on the module's attributes.
208201
"""
209-
for module in self.module:
202+
for module in self.modules:
210203
self.logger.debug(f"Loading module {module.name} - {module}")
211204
module_logger = NXCAdapter(
212205
extra={
@@ -491,3 +484,12 @@ def login(self):
491484

492485
def mark_pwned(self):
493486
return highlight(f"({pwned_label})" if self.admin_privs else "")
487+
488+
def load_modules(self):
489+
self.logger.info(f"Loading modules for target: {self.host}")
490+
loader = ModuleLoader(self.args, self.db, self.logger)
491+
self.modules = []
492+
493+
for module_path in self.module_paths:
494+
module = loader.init_module(module_path)
495+
self.modules.append(module)

nxc/netexec.py

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ def main():
139139
nxc_logger.debug(f"Protocol DB Path: {protocol_db_path}")
140140

141141
protocol_object = getattr(p_loader.load_protocol(protocol_path), args.protocol)
142-
nxc_logger.debug(f"Protocol Object: {protocol_object}")
142+
nxc_logger.debug(f"Protocol Object: {protocol_object}, type: {type(protocol_object)}")
143+
nxc_logger.debug(f"Protocol Object dir: {dir(protocol_object)}")
143144
protocol_db_object = p_loader.load_protocol(protocol_db_path).database
144145
nxc_logger.debug(f"Protocol DB Object: {protocol_db_object}")
145146

@@ -172,36 +173,28 @@ def main():
172173
nxc_logger.display(f"{module} module options:\n{modules[module]['options']}")
173174
exit(0)
174175
elif args.module:
175-
nxc_logger.debug(f"Modules to be Loaded: {args.module}, {type(args.module)}")
176+
# Check the modules for sanity before loading the protocol
177+
nxc_logger.debug(f"Modules to be Loaded for sanity check: {args.module}, {type(args.module)}")
178+
proto_module_paths = []
176179
for m in args.module:
177180
if m not in modules:
178181
nxc_logger.error(f"Module not found: {m}")
179182
exit(1)
180183

181-
nxc_logger.debug(f"Loading module {m} at path {modules[m]['path']}")
184+
nxc_logger.debug(f"Loading module for sanity check {m} at path {modules[m]['path']}")
182185
module = loader.init_module(modules[m]["path"])
183186

184187
if not module.opsec_safe:
185188
if ignore_opsec:
186189
nxc_logger.debug("ignore_opsec is set in the configuration, skipping prompt")
187190
nxc_logger.display("Ignore OPSEC in configuration is set and OPSEC unsafe module loaded")
188191
else:
189-
ans = input(
190-
highlight(
191-
"[!] Module is not opsec safe, are you sure you want to run this? [Y/n] For global configuration, change ignore_opsec value to True on ~/nxc/nxc.conf",
192-
"red",
193-
)
194-
)
192+
ans = input(highlight("[!] Module is not opsec safe, are you sure you want to run this? [Y/n] For global configuration, change ignore_opsec value to True on ~/nxc/nxc.conf", "red"))
195193
if ans.lower() not in ["y", "yes", ""]:
196194
exit(1)
197195

198196
if not module.multiple_hosts and len(targets) > 1:
199-
ans = input(
200-
highlight(
201-
"[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n] ",
202-
"red",
203-
)
204-
)
197+
ans = input(highlight("[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n] ", "red"))
205198
if ans.lower() not in ["y", "yes", ""]:
206199
exit(1)
207200

@@ -212,21 +205,12 @@ def main():
212205
if not args.server_port:
213206
args.server_port = server_port_dict[args.server]
214207

215-
nxc_logger.debug(f"proto_object: {protocol_object}, type: {type(protocol_object)}")
216-
nxc_logger.debug(f"proto object dir: {dir(protocol_object)}")
217-
# get currently set modules, otherwise default to empty list
218-
current_modules = getattr(protocol_object, "module", [])
219-
current_modules.append(module)
220-
protocol_object.module = current_modules
221-
nxc_logger.debug(f"proto object module after adding: {protocol_object.module}")
208+
# Add modules paths to the protocol object so it can load them itself
209+
proto_module_paths.append(modules[m]["path"])
210+
protocol_object.module_paths = proto_module_paths
222211

223212
if hasattr(args, "ntds") and args.ntds and not args.userntds:
224-
ans = input(
225-
highlight(
226-
"[!] Dumping the ntds can crash the DC on Windows Server 2019. Use the option --user <user> to dump a specific user safely or the module -M ntdsutil [Y/n] ",
227-
"red",
228-
)
229-
)
213+
ans = input(highlight("[!] Dumping the ntds can crash the DC on Windows Server 2019. Use the option --user <user> to dump a specific user safely or the module -M ntdsutil [Y/n] ", "red"))
230214
if ans.lower() not in ["y", "yes", ""]:
231215
exit(1)
232216

0 commit comments

Comments
 (0)