Merge pull request #1346 from azoxlpf/fix/module-options-validation

Allow modules to abort the run by returning False from options()
This commit is contained in:
Alex authored and GitHub committed 2026-08-23 11:42:17 +02:00
commit 7751cb8f1f
4 files changed
+19 -5

No files matched your search

+6 -2
View File
@@ -14,7 +14,7 @@ from socket import AF_UNSPEC, SOCK_DGRAM, IPPROTO_IP, AI_CANONNAME, getaddrinfo
from nxc.config import pwned_label
from nxc.helpers.logger import highlight
from nxc.loaders.moduleloader import ModuleLoader
from nxc.loaders.moduleloader import ModuleLoader, ModuleOptionsError
from nxc.logger import nxc_logger, NXCAdapter
from nxc.context import Context
from nxc.paths import NXC_PATH
@@ -604,5 +604,9 @@ class connection:
self.modules = []
for module_path in self.module_paths:
module = loader.init_module(module_path)
try:
module = loader.init_module(module_path)
except ModuleOptionsError as e:
self.logger.debug(f"Skipping module: {e}")
continue
self.modules.append(module)
+6 -1
View File
@@ -13,6 +13,10 @@ from nxc.logger import NXCAdapter
from nxc.paths import NXC_PATH
class ModuleOptionsError(Exception):
"""Raised when a module aborts the run from options() (returned False)."""
class ModuleLoader:
def __init__(self, args, db, logger):
self.args = args
@@ -100,7 +104,8 @@ class ModuleLoader:
key, value = option.split("=", 1)
module_options[str(key).upper()] = value
module.options(context, module_options)
if module.options(context, module_options) is False:
raise ModuleOptionsError(f"Module {module.name} aborted the run from options()")
return module
else:
self.logger.fail(f"Module {module.name.upper()} is not supported for protocol {self.args.protocol}")
+1
View File
@@ -22,6 +22,7 @@ class NXCModule:
Module options get parsed here. Additionally, put the modules usage here as well
"""
# Put "No options available" in the docstring if there are no options for the module
# Return False to abort the run if options are invalid (log with context.log.fail first).
def on_login(self, context, connection):
"""Concurrent.
+6 -2
View File
@@ -8,7 +8,7 @@ from nxc.parsers.nmap import parse_nmap_xml
from nxc.parsers.nessus import parse_nessus_file
from nxc.cli import gen_cli_args
from nxc.loaders.protocolloader import ProtocolLoader
from nxc.loaders.moduleloader import ModuleLoader
from nxc.loaders.moduleloader import ModuleLoader, ModuleOptionsError
from nxc.first_run import first_run_setup
from nxc.paths import NXC_PATH, WORKSPACE_DIR
from nxc.console import nxc_console
@@ -207,7 +207,11 @@ def main():
exit(1)
nxc_logger.debug(f"Loading module for sanity check {m} at path {modules[m]['path']}")
module = loader.init_module(modules[m]["path"])
try:
loader.init_module(modules[m]["path"])
except ModuleOptionsError as e:
nxc_logger.debug(f"Aborting run: {e}")
exit(1)
# Add modules paths to the protocol object so it can load them itself
proto_module_paths.append(modules[m]["path"])