1010import sys
1111from sectools .network .domains import is_fqdn
1212from sectools .network .ip import is_ipv4_cidr , is_ipv4_addr , is_ipv6_addr , expand_cidr , expand_port_range
13- from coercer .core .Reporter import Reporter
14- from coercer .structures .Credentials import Credentials
15- from coercer .core .modes .scan import action_scan
16- from coercer .core .modes .coerce import action_coerce
17- from coercer .core .modes .fuzz import action_fuzz
18- from coercer .core .loader import find_and_load_coerce_methods
19- from coercer .network .smb import try_login
20- from coercer .network .utils import can_listen_on_port
21-
13+ from coercer .core .Reporter import create_reporter
2214
2315VERSION = "2.4.3"
2416
@@ -35,10 +27,13 @@ def parseArgs():
3527 parser = argparse .ArgumentParser (add_help = True , description = "Automatic windows authentication coercer using various methods." )
3628 parser .add_argument ("-v" , "--verbose" , default = False , action = "store_true" , help = "Verbose mode (default: False)" )
3729 parser .add_argument ("--debug" , default = False , action = "store_true" , help = "Debug mode (default: False)" )
30+ parser .add_argument ("--disable-escape-codes" , default = False , action = "store_true" , help = "Disable ANSI escape codes" )
3831
3932 # Creating the "scan" subparser ==============================================================================================================
4033 mode_scan = argparse .ArgumentParser (add_help = False )
4134 mode_scan .add_argument ("-v" , "--verbose" , default = False , action = "store_true" , help = "Verbose mode (default: False)" )
35+ mode_scan .add_argument ("--debug" , default = False , action = "store_true" , help = "Debug mode (default: False)" )
36+ mode_scan .add_argument ("--disable-escape-codes" , default = False , action = "store_true" , help = "Disable ANSI escape codes" )
4237 # Advanced configuration
4338 mode_scan_advanced_config = mode_scan .add_argument_group ("Advanced options" )
4439 mode_scan_advanced_config .add_argument ("--export-json" , default = None , type = str , help = "Export results to specified JSON file." )
@@ -76,10 +71,16 @@ def parseArgs():
7671 mode_scan_targets_listener .add_argument ("-i" , "--interface" , default = None , help = "Interface to listen on incoming authentications." )
7772 mode_scan_targets_listener .add_argument ("-I" , "--ip-address" , default = None , help = "IP address to listen on incoming authentications." )
7873 mode_scan_targets_listener .add_argument ("--path-ip" , default = None , help = "IP address to use when generating exploit paths." )
74+ # Logging
75+ mode_scan_logging = mode_scan .add_argument_group ("Logging" )
76+ mode_scan_logging .add_argument ("--minimum-log-level" , default = 0 , help = "Minimum logging level (integer)." )
77+ mode_scan_logging .add_argument ("--log-file" , default = None , help = "Path for the file to log to (enables logging)." )
7978
8079 # Creating the "fuzz" subparser ==============================================================================================================
8180 mode_fuzz = argparse .ArgumentParser (add_help = False )
8281 mode_fuzz .add_argument ("-v" , "--verbose" , default = False , action = "store_true" , help = "Verbose mode (default: False)" )
82+ mode_fuzz .add_argument ("--debug" , default = False , action = "store_true" , help = "Debug mode (default: False)" )
83+ mode_fuzz .add_argument ("--disable-escape-codes" , default = False , action = "store_true" , help = "Disable ANSI escape codes" )
8384 # Advanced configuration
8485 mode_fuzz_advanced_config = mode_fuzz .add_argument_group ("Advanced configuration" )
8586 mode_fuzz_advanced_config .add_argument ("--export-json" , default = None , type = str , help = "Export results to specified JSON file." )
@@ -116,10 +117,16 @@ def parseArgs():
116117 mode_fuzz_targets_listener .add_argument ("-i" , "--interface" , default = None , help = "Interface to listen on incoming authentications." )
117118 mode_fuzz_targets_listener .add_argument ("-I" , "--ip-address" , default = None , help = "IP address to listen on incoming authentications." )
118119 mode_fuzz_targets_listener .add_argument ("--path-ip" , default = None , help = "IP address to use when generating exploit paths." )
120+ # Logging
121+ mode_fuzz_logging = mode_fuzz .add_argument_group ("Logging" )
122+ mode_fuzz_logging .add_argument ("--minimum-log-level" , default = 0 , help = "Minimum logging level (integer)." )
123+ mode_fuzz_logging .add_argument ("--log-file" , default = None , help = "Path for the file to log to (enables logging)." )
119124
120125 # Creating the "coerce" subparser ==============================================================================================================
121126 mode_coerce = argparse .ArgumentParser (add_help = False )
122127 mode_coerce .add_argument ("-v" , "--verbose" , default = False , action = "store_true" , help = "Verbose mode (default: False)" )
128+ mode_coerce .add_argument ("--debug" , default = False , action = "store_true" , help = "Debug mode (default: False)" )
129+ mode_coerce .add_argument ("--disable-escape-codes" , default = False , action = "store_true" , help = "Disable ANSI escape codes" )
123130 # Advanced configuration
124131 mode_coerce_advanced_config = mode_coerce .add_argument_group ("Advanced configuration" )
125132 mode_coerce_advanced_config .add_argument ("--delay" , default = None , type = int , help = "Delay between attempts (in seconds)" )
@@ -150,7 +157,11 @@ def parseArgs():
150157 # Listener
151158 listener_group = mode_coerce .add_argument_group ("Listener" )
152159 listener_group .add_argument ("-l" , "--listener-ip" , required = True , type = str , help = "IP address or hostname of the listener machine" )
153-
160+ # Logging
161+ mode_coerce_logging = mode_coerce .add_argument_group ("Logging" )
162+ mode_coerce_logging .add_argument ("--minimum-log-level" , default = 0 , help = "Minimum logging level (integer)." )
163+ mode_coerce_logging .add_argument ("--log-file" , default = None , help = "Path for the file to log to (enables logging)." )
164+
154165 # Adding the subparsers to the base parser
155166 subparsers = parser .add_subparsers (help = "Mode" , dest = "mode" , required = True )
156167 mode_scan_parser = subparsers .add_parser ("scan" , parents = [mode_scan ], help = "Tests known methods with known working paths on all methods, and report when an authentication is received." )
@@ -171,12 +182,20 @@ def parseArgs():
171182
172183
173184def main ():
174- available_methods = find_and_load_coerce_methods ()
175-
176185 lmhash , nthash , options = parseArgs ()
186+ create_reporter (options , options .verbose )
177187
178- reporter = Reporter (verbose = options .verbose , options = options )
188+ from coercer .core .Reporter import reporter
189+ from coercer .structures .Credentials import Credentials
190+ from coercer .core .modes .scan import action_scan
191+ from coercer .core .modes .coerce import action_coerce
192+ from coercer .core .modes .fuzz import action_fuzz
193+ from coercer .network .smb import try_login
194+ from coercer .network .utils import can_listen_on_port
195+ from coercer .core .loader import find_and_load_coerce_methods
179196
197+ available_methods = find_and_load_coerce_methods ()
198+
180199 # Parsing targets
181200 targets = []
182201 if options .target_ip is not None :
@@ -186,9 +205,9 @@ def main():
186205 f = open (options .targets_file , 'r' )
187206 targets = sorted (list (set ([line .strip () for line in f .readlines ()])))
188207 f .close ()
189- reporter .print_verbose ("Loaded %d targets." % len (targets ))
208+ reporter .print_info ("Loaded %d targets." % len (targets ))
190209 else :
191- print ( "[!] Could not open targets file '%s'." % options .targets_file )
210+ reporter . print_error ( " Could not open targets file '%s'." % options .targets_file )
192211 sys .exit (0 )
193212
194213 # Sort uniq on targets list
@@ -211,8 +230,7 @@ def main():
211230 target = urllib .parse .urlparse (target ).netloc
212231 final_targets .append (target )
213232 else :
214- if options .debug :
215- print ("[debug] Target '%s' was not added." % target )
233+ reporter .print_warn ("Target '%s' was not added." % target , debug = True )
216234
217235 # Sort
218236 targets = sorted (list (set (final_targets )))
@@ -233,26 +251,26 @@ def main():
233251 for target in targets :
234252 reporter .print_info ("Scanning target %s" % target )
235253 # Checking credentials if any
236- if not "msrpc" in options .filter_transport_name or try_login (credentials , target , verbose = options . verbose ):
254+ if not "msrpc" in options .filter_transport_name or try_login (credentials , target ):
237255 try :
238256 # Starting action
239- action_coerce (target , available_methods , options , credentials , reporter )
257+ action_coerce (target , available_methods , options , credentials )
240258 except Exception as e :
241259 reporter .print_warn ("An unexpected error occurred: %s" % e )
242260 elif options .mode == "scan" :
243261 reporter .print_info ("Starting scan mode" )
244262 if credentials .is_anonymous ():
245263 reporter .print_info ("No credentials provided, trying to connect with a NULL session." )
246264 if not can_listen_on_port ("0.0.0.0" , 445 ):
247- reporter .print_warn ("Cannot listen on port tcp/%d. Are you root or are other servers running?" % 445 )
265+ reporter .print_error ("Cannot listen on port tcp/%d. Are you root or are other servers running?" % 445 )
248266 else :
249267 for target in targets :
250268 reporter .print_info ("Scanning target %s" % target )
251269 # Checking credentials if any
252- if not "msrpc" in options .filter_transport_name or try_login (credentials , target , verbose = options . verbose ):
270+ if not "msrpc" in options .filter_transport_name or try_login (credentials , target ):
253271 try :
254272 # Starting action
255- action_scan (target , available_methods , options , credentials , reporter )
273+ action_scan (target , available_methods , options , credentials )
256274 except Exception as e :
257275 reporter .print_warn ("An unexpected error occurred: %s" % e )
258276 # Reporting results
@@ -268,15 +286,15 @@ def main():
268286 if credentials .is_anonymous ():
269287 reporter .print_info ("No credentials provided, trying to connect with a NULL session." )
270288 if not can_listen_on_port ("0.0.0.0" , 445 ):
271- reporter .print_warn ("Cannot listen on port tcp/%d. Are you root or are other servers running?" % 445 )
289+ reporter .print_error ("Cannot listen on port tcp/%d. Are you root or are other servers running?" % 445 )
272290 else :
273291 for target in targets :
274292 reporter .print_info ("Fuzzing target %s" % target )
275293 # Checking credentials if any
276- if not "msrpc" in options .filter_transport_name or try_login (credentials , target , verbose = options . verbose ):
294+ if not "msrpc" in options .filter_transport_name or try_login (credentials , target ):
277295 try :
278296 # Starting action
279- action_fuzz (target , available_methods , options , credentials , reporter )
297+ action_fuzz (target , available_methods , options , credentials )
280298 except Exception as e :
281299 reporter .print_warn ("An unexpected error occurred: %s" % e )
282300 # Reporting results
@@ -287,7 +305,7 @@ def main():
287305 if options .export_sqlite is not None :
288306 reporter .exportSQLITE (options .export_sqlite )
289307
290- print ( "[+] All done! Bye Bye!" )
308+ reporter . print_ok ( " All done! Bye Bye!" )
291309
292310if __name__ == '__main__' :
293311 main ()
0 commit comments