11import argparse
2- import importlib . metadata
2+ import argcomplete
33import sys
44from argparse import RawTextHelpFormatter
55from os import listdir
66from os .path import dirname
77from os .path import join as path_join
8-
9- import argcomplete
10-
118import nxc
12- from nxc .helpers .args import DisplayDefaultsNotNone
13- from nxc .helpers .logger import highlight
9+ from nxc .paths import NXC_PATH
1410from nxc .loaders .protocolloader import ProtocolLoader
11+ from nxc .helpers .logger import highlight
12+ from nxc .helpers .args import DisplayDefaultsNotNone
1513from nxc .logger import nxc_logger , setup_debug_logging
16- from nxc . paths import NXC_PATH
14+ import importlib . metadata
1715
1816
1917def gen_cli_args ():
@@ -28,79 +26,26 @@ def gen_cli_args():
2826 DISTANCE = ""
2927 CODENAME = "SmoothOperator"
3028
31- generic_parser = argparse .ArgumentParser (
32- add_help = False , formatter_class = DisplayDefaultsNotNone
33- )
34- generic_group = generic_parser .add_argument_group (
35- "Generic" , "Generic options for nxc across protocols"
36- )
37- generic_group .add_argument (
38- "--version" , action = "store_true" , help = "Display nxc version"
39- )
40- generic_group .add_argument (
41- "-t" ,
42- "--threads" ,
43- type = int ,
44- dest = "threads" ,
45- default = 256 ,
46- help = "set how many concurrent threads to use" ,
47- )
48- generic_group .add_argument (
49- "--timeout" ,
50- default = None ,
51- type = int ,
52- help = "max timeout in seconds of each thread" ,
53- )
54- generic_group .add_argument (
55- "--jitter" ,
56- metavar = "INTERVAL" ,
57- type = str ,
58- help = "sets a random delay between each authentication" ,
59- )
60-
61- output_parser = argparse .ArgumentParser (
62- add_help = False , formatter_class = DisplayDefaultsNotNone
63- )
64- output_group = output_parser .add_argument_group (
65- "Output" , "Options to set verbosity levels and control output"
66- )
67- output_group .add_argument (
68- "--verbose" , action = "store_true" , help = "enable verbose output"
69- )
70- output_group .add_argument (
71- "--debug" , action = "store_true" , help = "enable debug level information"
72- )
73- output_group .add_argument (
74- "--no-progress" ,
75- action = "store_true" ,
76- help = "do not displaying progress bar during scan" ,
77- )
78- output_group .add_argument (
79- "--log" , metavar = "LOG" , help = "export result into a custom file"
80- )
81-
82- dns_parser = argparse .ArgumentParser (
83- add_help = False , formatter_class = DisplayDefaultsNotNone
84- )
29+ generic_parser = argparse .ArgumentParser (add_help = False , formatter_class = DisplayDefaultsNotNone )
30+ generic_group = generic_parser .add_argument_group ("Generic" , "Generic options for nxc across protocols" )
31+ generic_group .add_argument ("--version" , action = "store_true" , help = "Display nxc version" )
32+ generic_group .add_argument ("-t" , "--threads" , type = int , dest = "threads" , default = 256 , help = "set how many concurrent threads to use" )
33+ generic_group .add_argument ("--timeout" , default = None , type = int , help = "max timeout in seconds of each thread" )
34+ generic_group .add_argument ("--jitter" , metavar = "INTERVAL" , type = str , help = "sets a random delay between each authentication" )
35+
36+ output_parser = argparse .ArgumentParser (add_help = False , formatter_class = DisplayDefaultsNotNone )
37+ output_group = output_parser .add_argument_group ("Output" , "Options to set verbosity levels and control output" )
38+ output_group .add_argument ("--verbose" , action = "store_true" , help = "enable verbose output" )
39+ output_group .add_argument ("--debug" , action = "store_true" , help = "enable debug level information" )
40+ output_group .add_argument ("--no-progress" , action = "store_true" , help = "do not displaying progress bar during scan" )
41+ output_group .add_argument ("--log" , metavar = "LOG" , help = "export result into a custom file" )
42+
43+ dns_parser = argparse .ArgumentParser (add_help = False , formatter_class = DisplayDefaultsNotNone )
8544 dns_group = dns_parser .add_argument_group ("DNS" )
86- dns_group .add_argument (
87- "-6" , dest = "force_ipv6" , action = "store_true" , help = "Enable force IPv6"
88- )
89- dns_group .add_argument (
90- "--dns-server" ,
91- action = "store" ,
92- help = "Specify DNS server (default: Use hosts file & System DNS)" ,
93- )
94- dns_group .add_argument (
95- "--dns-tcp" , action = "store_true" , help = "Use TCP instead of UDP for DNS queries"
96- )
97- dns_group .add_argument (
98- "--dns-timeout" ,
99- action = "store" ,
100- type = int ,
101- default = 3 ,
102- help = "DNS query timeout in seconds" ,
103- )
45+ dns_group .add_argument ("-6" , dest = "force_ipv6" , action = "store_true" , help = "Enable force IPv6" )
46+ dns_group .add_argument ("--dns-server" , action = "store" , help = "Specify DNS server (default: Use hosts file & System DNS)" )
47+ dns_group .add_argument ("--dns-tcp" , action = "store_true" , help = "Use TCP instead of UDP for DNS queries" )
48+ dns_group .add_argument ("--dns-timeout" , action = "store" , type = int , default = 3 , help = "DNS query timeout in seconds" )
10449
10550 parser = argparse .ArgumentParser (
10651 description = rf"""
@@ -123,191 +68,54 @@ def gen_cli_args():
12368 { highlight ('Commit' , 'red' )} : { highlight (COMMIT )}
12469 """ ,
12570 formatter_class = RawTextHelpFormatter ,
126- parents = [generic_parser , output_parser , dns_parser ],
71+ parents = [generic_parser , output_parser , dns_parser ]
12772 )
12873
12974 # we do module arg parsing here so we can reference the module_list attribute below
130- module_parser = argparse .ArgumentParser (
131- add_help = False , formatter_class = DisplayDefaultsNotNone
132- )
75+ module_parser = argparse .ArgumentParser (add_help = False , formatter_class = DisplayDefaultsNotNone )
13376 mgroup = module_parser .add_argument_group ("Modules" , "Options for nxc modules" )
134- mgroup .add_argument (
135- "-M" ,
136- "--module" ,
137- choices = get_module_names (),
138- action = "append" ,
139- metavar = "MODULE" ,
140- help = "module to use" ,
141- )
142- mgroup .add_argument (
143- "-o" ,
144- metavar = "MODULE_OPTION" ,
145- nargs = "+" ,
146- default = [],
147- dest = "module_options" ,
148- help = "module options" ,
149- )
150- mgroup .add_argument (
151- "-L" ,
152- "--list-modules" ,
153- nargs = "?" ,
154- type = str ,
155- const = "" ,
156- help = "list available modules" ,
157- )
158- mgroup .add_argument (
159- "--options" ,
160- dest = "show_module_options" ,
161- action = "store_true" ,
162- help = "display module options" ,
163- )
77+ mgroup .add_argument ("-M" , "--module" , choices = get_module_names (), action = "append" , metavar = "MODULE" , help = "module to use" )
78+ mgroup .add_argument ("-o" , metavar = "MODULE_OPTION" , nargs = "+" , default = [], dest = "module_options" , help = "module options" )
79+ mgroup .add_argument ("-L" , "--list-modules" , nargs = "?" , type = str , const = "" , help = "list available modules" )
80+ mgroup .add_argument ("--options" , dest = "show_module_options" , action = "store_true" , help = "display module options" )
16481
16582 subparsers = parser .add_subparsers (title = "Available Protocols" , dest = "protocol" )
16683
167- std_parser = argparse .ArgumentParser (
168- add_help = False ,
169- parents = [generic_parser , output_parser , dns_parser ],
170- formatter_class = DisplayDefaultsNotNone ,
171- )
172- std_parser .add_argument (
173- "target" ,
174- nargs = (
175- "+"
176- if not (
177- module_parser .parse_known_args ()[0 ].list_modules is not None
178- or module_parser .parse_known_args ()[0 ].show_module_options
179- or generic_parser .parse_known_args ()[0 ].version
180- )
181- else "*"
182- ),
183- type = str ,
184- help = "the target IP(s), range(s), CIDR(s), hostname(s), FQDN(s), file(s) containing a list of targets, NMap XML or .Nessus file(s)" ,
185- )
186- credential_group = std_parser .add_argument_group (
187- "Authentication" , "Options for authenticating"
188- )
189- credential_group .add_argument (
190- "-u" ,
191- "--username" ,
192- metavar = "USERNAME" ,
193- dest = "username" ,
194- nargs = "+" ,
195- default = [],
196- help = "username(s) or file(s) containing usernames" ,
197- )
198- credential_group .add_argument (
199- "-p" ,
200- "--password" ,
201- metavar = "PASSWORD" ,
202- dest = "password" ,
203- nargs = "+" ,
204- default = [],
205- help = "password(s) or file(s) containing passwords" ,
206- )
207- credential_group .add_argument (
208- "-id" ,
209- metavar = "CRED_ID" ,
210- nargs = "+" ,
211- default = [],
212- type = str ,
213- dest = "cred_id" ,
214- help = "database credential ID(s) to use for authentication" ,
215- )
216- credential_group .add_argument (
217- "--ignore-pw-decoding" ,
218- action = "store_true" ,
219- help = "Ignore non UTF-8 characters when decoding the password file" ,
220- )
221- credential_group .add_argument (
222- "--no-bruteforce" ,
223- action = "store_true" ,
224- help = "No spray when using file for username and password (user1 => password1, user2 => password2)" ,
225- )
226- credential_group .add_argument (
227- "--continue-on-success" ,
228- action = "store_true" ,
229- help = "continues authentication attempts even after successes" ,
230- )
231- credential_group .add_argument (
232- "--gfail-limit" ,
233- metavar = "LIMIT" ,
234- type = int ,
235- help = "max number of global failed login attempts" ,
236- )
237- credential_group .add_argument (
238- "--ufail-limit" ,
239- metavar = "LIMIT" ,
240- type = int ,
241- help = "max number of failed login attempts per username" ,
242- )
243- credential_group .add_argument (
244- "--fail-limit" ,
245- metavar = "LIMIT" ,
246- type = int ,
247- help = "max number of failed login attempts per host" ,
248- )
249-
250- kerberos_group = std_parser .add_argument_group (
251- "Kerberos" , "Options for Kerberos authentication"
252- )
253- kerberos_group .add_argument (
254- "-k" , "--kerberos" , action = "store_true" , help = "Use Kerberos authentication"
255- )
256- kerberos_group .add_argument (
257- "--use-kcache" ,
258- action = "store_true" ,
259- help = "Use Kerberos authentication from ccache file (KRB5CCNAME)" ,
260- )
261- kerberos_group .add_argument (
262- "--aesKey" ,
263- metavar = "AESKEY" ,
264- nargs = "+" ,
265- help = "AES key to use for Kerberos Authentication (128 or 256 bits)" ,
266- )
267- kerberos_group .add_argument (
268- "--kdcHost" ,
269- metavar = "KDCHOST" ,
270- help = "FQDN of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameter" ,
271- )
272-
273- certificate_group = std_parser .add_argument_group (
274- "Certificate" , "Options for certificate authentication"
275- )
276- certificate_group .add_argument (
277- "--pfx-cert" ,
278- metavar = "PFXCERT" ,
279- help = "Use certificate authentication from pfx file .pfx" ,
280- )
281- certificate_group .add_argument (
282- "--pfx-base64" ,
283- metavar = "PFXB64" ,
284- help = "Use certificate authentication from pfx file encoded in base64" ,
285- )
286- certificate_group .add_argument (
287- "--pfx-pass" , metavar = "PFXPASS" , help = "Password of the pfx certificate"
288- )
289- certificate_group .add_argument (
290- "--pem-cert" ,
291- metavar = "PEMCERT" ,
292- help = "Use certificate authentication from PEM file" ,
293- )
294- certificate_group .add_argument (
295- "--pem-key" , metavar = "PEMKEY" , help = "Private key for the PEM format"
296- )
84+ std_parser = argparse .ArgumentParser (add_help = False , parents = [generic_parser , output_parser , dns_parser ], formatter_class = DisplayDefaultsNotNone )
85+ std_parser .add_argument ("target" , nargs = "+" if not (module_parser .parse_known_args ()[0 ].list_modules is not None or module_parser .parse_known_args ()[0 ].show_module_options or generic_parser .parse_known_args ()[0 ].version ) else "*" , type = str , help = "the target IP(s), range(s), CIDR(s), hostname(s), FQDN(s), file(s) containing a list of targets, NMap XML or .Nessus file(s)" )
86+ credential_group = std_parser .add_argument_group ("Authentication" , "Options for authenticating" )
87+ credential_group .add_argument ("-u" , "--username" , metavar = "USERNAME" , dest = "username" , nargs = "+" , default = [], help = "username(s) or file(s) containing usernames" )
88+ credential_group .add_argument ("-p" , "--password" , metavar = "PASSWORD" , dest = "password" , nargs = "+" , default = [], help = "password(s) or file(s) containing passwords" )
89+ credential_group .add_argument ("-id" , metavar = "CRED_ID" , nargs = "+" , default = [], type = str , dest = "cred_id" , help = "database credential ID(s) to use for authentication" )
90+ credential_group .add_argument ("--ignore-pw-decoding" , action = "store_true" , help = "Ignore non UTF-8 characters when decoding the password file" )
91+ credential_group .add_argument ("--no-bruteforce" , action = "store_true" , help = "No spray when using file for username and password (user1 => password1, user2 => password2)" )
92+ credential_group .add_argument ("--continue-on-success" , action = "store_true" , help = "continues authentication attempts even after successes" )
93+ credential_group .add_argument ("--gfail-limit" , metavar = "LIMIT" , type = int , help = "max number of global failed login attempts" )
94+ credential_group .add_argument ("--ufail-limit" , metavar = "LIMIT" , type = int , help = "max number of failed login attempts per username" )
95+ credential_group .add_argument ("--fail-limit" , metavar = "LIMIT" , type = int , help = "max number of failed login attempts per host" )
96+
97+ kerberos_group = std_parser .add_argument_group ("Kerberos" , "Options for Kerberos authentication" )
98+ kerberos_group .add_argument ("-k" , "--kerberos" , action = "store_true" , help = "Use Kerberos authentication" )
99+ kerberos_group .add_argument ("--use-kcache" , action = "store_true" , help = "Use Kerberos authentication from ccache file (KRB5CCNAME)" )
100+ kerberos_group .add_argument ("--aesKey" , metavar = "AESKEY" , nargs = "+" , help = "AES key to use for Kerberos Authentication (128 or 256 bits)" )
101+ kerberos_group .add_argument ("--kdcHost" , metavar = "KDCHOST" , help = "FQDN of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameter" )
102+
103+ certificate_group = std_parser .add_argument_group ("Certificate" , "Options for certificate authentication" )
104+ certificate_group .add_argument ("--pfx-cert" , metavar = "PFXCERT" , help = "Use certificate authentication from pfx file .pfx" )
105+ certificate_group .add_argument ("--pfx-base64" , metavar = "PFXB64" , help = "Use certificate authentication from pfx file encoded in base64" )
106+ certificate_group .add_argument ("--pfx-pass" , metavar = "PFXPASS" , help = "Password of the pfx certificate" )
107+ certificate_group .add_argument ("--pem-cert" , metavar = "PEMCERT" , help = "Use certificate authentication from PEM file" )
108+ certificate_group .add_argument ("--pem-key" , metavar = "PEMKEY" , help = "Private key for the PEM format" )
297109
298110 p_loader = ProtocolLoader ()
299111 protocols = p_loader .get_protocols ()
300112
301113 try :
302114 for protocol in protocols :
303115 protocol_object = p_loader .load_protocol (protocols [protocol ]["argspath" ])
304- subparsers = protocol_object .proto_args (
305- subparsers , [std_parser , module_parser ]
306- )
116+ subparsers = protocol_object .proto_args (subparsers , [std_parser , module_parser ])
307117 except Exception as e :
308- nxc_logger .exception (
309- f"Error loading proto_args from proto_args.py file in protocol folder: { protocol } - { e } "
310- )
118+ nxc_logger .exception (f"Error loading proto_args from proto_args.py file in protocol folder: { protocol } - { e } " )
311119
312120 argcomplete .autocomplete (parser , always_complete_options = False )
313121 args = parser .parse_args ()
@@ -336,11 +144,5 @@ def get_module_names():
336144 ]
337145
338146 for path in modules_paths :
339- modules .extend (
340- [
341- module [:- 3 ]
342- for module in listdir (path )
343- if module [- 3 :] == ".py" and module != "example_module.py"
344- ]
345- )
147+ modules .extend ([module [:- 3 ] for module in listdir (path ) if module [- 3 :] == ".py" and module != "example_module.py" ])
346148 return sorted (modules , key = str .casefold )
0 commit comments