@@ -85,11 +85,13 @@ def scan_and_attack():
8585
8686 Color .pl ('' )
8787
88- # Scan
88+ # Scan (no signal handler during scanning to allow proper target selection)
8989 s = Scanner ()
9090 do_continue = s .find_targets ()
9191 targets = s .select_targets ()
9292
93+ # Attack modules handle KeyboardInterrupt properly, no global handler needed
94+
9395 if Configuration .infinite_mode :
9496 while do_continue :
9597 AttackAll .attack_multiple (targets )
@@ -105,6 +107,14 @@ def scan_and_attack():
105107 Color .pl ('{+} Finished attacking {C}%d{W} target(s), exiting' % attacked_targets )
106108
107109
110+
111+
112+ def force_exit_handler (signum , frame ):
113+ """Force exit on multiple Ctrl+C during cleanup"""
114+ import sys
115+ print ('\n [!] Force exiting...' )
116+ sys .exit (1 )
117+
108118def main ():
109119 try :
110120 wifite = Wifite ()
@@ -120,23 +130,66 @@ def main():
120130 Color .pl ('\n {!} {R}Try running with sudo{W}\n ' )
121131 except KeyboardInterrupt :
122132 Color .pl ('\n {!} {O}Interrupted, Shutting down...{W}' )
133+ # Set up force exit handler for cleanup phase
134+ import signal
135+ signal .signal (signal .SIGINT , force_exit_handler )
123136 except Exception as e :
124137 Color .pl ('\n {!} {R}Unexpected Error{W}: %s' % str (e ))
125138 Color .pexception (e )
126139 Color .pl ('\n {!} {R}Exiting{W}\n ' )
127140
128141 finally :
129- # Ensure all processes are cleaned up
130- from .util .process import ProcessManager
131- ProcessManager ().cleanup_all ()
142+ # Set up aggressive force exit handler during cleanup
143+ import signal
144+ import sys
145+
146+ def emergency_exit (signum , frame ):
147+ print ('\n [!] Emergency exit!' )
148+ # Disable atexit callbacks and suppress stderr to prevent ugly exception messages
149+ import atexit
150+ import os
151+ atexit ._clear ()
152+ # Redirect stderr to devnull to hide any remaining cleanup exceptions
153+ os .dup2 (os .open (os .devnull , os .O_WRONLY ), 2 )
154+ sys .exit (1 )
155+
156+ signal .signal (signal .SIGINT , emergency_exit )
157+
158+ # Quick cleanup with short timeouts
159+ try :
160+ from .util .process import ProcessManager
161+ import threading
162+
163+ # Run cleanup in thread with timeout
164+ cleanup_thread = threading .Thread (target = ProcessManager ().cleanup_all )
165+ cleanup_thread .daemon = True
166+ cleanup_thread .start ()
167+ cleanup_thread .join (timeout = 3 ) # 3 second timeout
168+ except :
169+ pass # Ignore cleanup errors
132170
133- # Delete Reaver .pcap
171+ # Delete Reaver .pcap quickly
134172 try :
135- subprocess .run (["rm" , "reaver_output.pcap" ], stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL )
173+ subprocess .run (["rm" , "-f" , "reaver_output.pcap" ], stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL , timeout = 2 )
174+ except :
175+ pass
176+
177+ # Try graceful exit with timeout
178+ try :
179+ import threading
180+
181+ def graceful_exit ():
182+ Configuration .exit_gracefully ()
183+
184+ exit_thread = threading .Thread (target = graceful_exit )
185+ exit_thread .daemon = True
186+ exit_thread .start ()
187+ exit_thread .join (timeout = 2 ) # 2 second timeout
136188 except :
137- pass # Ignore if file doesn't exist
189+ pass
138190
139- Configuration .exit_gracefully ()
191+ # Force exit regardless
192+ sys .exit (0 )
140193
141194
142195if __name__ == '__main__' :
0 commit comments