ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python暴力破解WiFi?其实是安全自检:从攻击视角守护家庭网络

Python暴力破解WiFi?其实是安全自检:从攻击视角守护家庭网络 先泼一盆冷水这个标题一看就透着危险气息。如果你以为这篇文章会教你怎么蹭隔壁老王家的网那现在就可以关掉了。我不会教任何人去破解他人的WiFi那是违法行为轻则被拉黑断网重则惹上官司。但换个角度这个话题其实有非常正面的价值——从攻击者的视角反推防御恰恰是安全从业者最常用的思路。我写的“暴力破解”指的是在你拥有合法授权的网络环境下自己家的路由器、自己租的测试环境、公司让你做的安全巡检用Python脚本去检测WiFi密码强度发现弱口令隐患。这篇文章就是一次从“破解视角”出发的家庭WiFi安全自检。1. WiFi密码安全现状为什么“25个常见密码”就能闯进一半的家门1.1 你以为的“复杂密码”可能早就躺在字典里很多人对自己的WiFi密码有谜之自信觉得“我生日手机尾号”已经够复杂了。但现实很残酷热词里有个搜索叫“25个常见wifi密码”你去翻一下就会发现什么12345678、88888888、a123456789、wang1234基本上把中国家庭路由器80%的弱口令都涵盖了。我做了几年网络安全相关的工作接过不少家庭网络安全的咨询说实话上门帮人排查路由器时用默认密码和弱密码的比例高得吓人。很多人的路由器买回来管理员密码还是admin/adminWiFi密码就是纯数字8位甚至还有人用手机号后八位。这些密码在一本稍微像样的字典里都有收录跑起来基本是秒破。1.2 暴力破解的本质穷举但不是无脑穷举“暴力破解”听起来很唬人好像是一台超级计算机在那里天荒地老地试密码。实际上针对WiFi的破解核心思路根本不是00000000到99999999这种全量穷举——那在WPA2加密面前毫无意义因为每次尝试都要完成一次完整的握手计算速度慢到你怀疑人生。真正有效的方式是字典攻击。也就是说攻击者拿一本“常见密码列表”去一个个试。WPA2时代WiFi的密码不是“试”出来的而是通过抓取握手包、离线计算验证的。整个过程的效率取决于字典里有没有你的密码而不取决于你密码的“长度”。这也解释了为什么“25个常见wifi密码”这种词能上热搜——因为对相当大比例的家庭网络来说这些密码真的能进去。这难道不是对安全意识的一次响亮的警报吗1.3 这篇文章的定位合法授权的安全自查我再次强调全篇内容的所有操作仅限在你拥有合法授权的设备上进行。你可以拿自己家的路由器练手可以搭一个测试AP比如用手机开热点来跑实验但绝对不能扫描、尝试连接邻居甚至任何第三方的WiFi网络。这种行为不仅不道德而且已经踩了法律红线。对网络安全从业者来说“如何破解”和“如何防御”是同一枚硬币的两面。你理解了攻击者的手法才能真正把自家的防线筑牢。这篇文章要带给你的是后者——用Python作为安全测试工具站在攻击者视角审视自身然后针对性地加固。2. Python环境准备与核心库选型2.1 环境搭建别在第一步卡住既然要用Python干活环境得先准备利索。我见过太多初学者卡在环境配置上然后就开始怀疑人生。这里不搞那些花里胡哨的集成环境就用最基础的官方Python pip。Windows用户直接去Python官网下载安装包注意安装时一定要勾选“Add Python to PATH”不然你后面在命令行里敲python会提示找不到命令。macOS用户建议直接用Homebrew安装brew install python3。Linux用户更简单sudo apt install python3 python3-pipDebian/Ubuntu系或sudo dnf install python3 python3-pipFedora系。装完验证一下打开终端或命令提示符输入python --version能打印出版本号就说明成功了。我建议用Python 3.9以上版本太老的版本对很多新库的支持有问题别给自己找麻烦。2.2 WiFi操作库选型pywifi与它的局限Python操作WiFi的库主流就是pywifi。它封装了底层无线网卡的API能让我们用Python代码扫描周围WiFi、建立连接、断开连接还能提取一些基本信息。安装很简单pip install pywifi不过我先说清楚pywifi这库的历史包袱比较重作者更新不算勤快在某些新系统上可能会有兼容性问题。我自己在Windows 10上用得比较多稳定性还行但到了Windows 11之后偶尔会遇到网卡驱动不配合的情况。macOS上由于系统安全机制这库基本是残废的很多接口调不动。Linux上需要wpactrl权限非root用户经常卡在权限这里。所以如果你做实验首选Windows。如果非要用Linux一定要用sudo跑脚本并且准备好折腾的耐心。还有个环境问题pywifi对Python 3.10以上的版本有时会报错如果你装不上或运行报错很可能是版本兼容问题。此时可以试试pip install pywifi -U更新一下或者干脆装一个Python 3.8的虚拟环境来跑。2.3 网卡与驱动有一个容易被忽略的硬性要求做WiFi安全测试网卡的选择是有讲究的。普通笔记本自带的无线网卡不是不能用但功能上有限制——很多消费级网卡不支持监听模式monitor mode而监听模式是抓取握手包的关键。pywifi这种库走的是标准无线管理接口不需要监听模式就能扫描和连接这点和Kali Linux里那些工具不太一样。但如果你后面想深入做分析比如用Wireshark抓包看握手过程那就得考虑买一块支持监听模式的外置USB无线网卡了。市面上常见的芯片方案有RTL8812AU、RTL8814AU这类价格不贵几十到一百多块钱但驱动的折腾程度懂的都懂。我个人的建议是如果只是做本文这种“合法密码强度检测”笔记本自带网卡完全够用没必要额外买设备。先把软件和流程跑通再考虑要不要深入硬件方向。3. 从技术上理解WPA/WPA2加密机制与破解原理3.1 四次握手WiFi连接背后的“对暗号”脱离原理谈攻击那是玄学。想要理解为什么WiFi密码能被“离线破解”必须先弄明白WPA2加密体系里最核心的机制——四次握手4-Way Handshake。简单打个比方你的手机想连接路由器两者之间需要“对暗号”确认对方知道WiFi密码。这个对暗号的过程就是四次握手。重点是握手过程中会传递一个叫PMKPairwise Master Key的东西的派生参数而PMK的核心输入就是WiFi密码本身。路由器那边会把你输入的密码加上一个叫SSID的网络名称再经过4096次PBKDF2算法迭代生成一个256位的密钥。有趣的地方来了整个握手过程中的所有数据包都可以在无线信道里被监听到。也就是说攻击者不需要在你说“我是好人”之前拦截他只用在旁边安静地搭个接收器把你说的话全部录下来然后回到自己的电脑上慢慢验证。3.2 为什么“暴力破解”在WPA2面前变成了“字典匹配”理解了四次握手的原理你就明白了所谓的“暴力破解”实质上是这样一个过程攻击者抓到一个握手包里面有路由器生成的随机数以及对PMK的某种加密结果。攻击者在本地用一台电脑拿字典里的每一个密码计算对应的PMK。每次计算出来的PMK去和握手包里捕获的数据做比对。如果匹配说明这个密码就是正确的WiFi密码。这个过程完全在攻击者的本地设备上完成不需要和路由器再有任何实时交互。速度取决于电脑的CPU/GPU算力以及字典的大小。密码的“在线试错”被转换成了“离线验算”效率何止提升百倍。这也是为什么我前面强调“纯8位数字”很危险——因为8位纯数字只有一亿种组合00000000到99999999听起来不少但现代电脑配合GPU加速跑完这一亿种组合可能只需要几小时甚至更短。而如果密码是大小写字母数字符号的12位混合那这个解空间大到天文数字暴力破解就毫无意义了。3.3 但请注意这还不是完整的“攻击链”严谨地说抓握手包需要附近有设备正在连接路由器攻击者可以在旁边被动等待或者发送“去认证”断开设备迫使其重新连接从而趁机抓包。整个过程对普通家庭来说远比想象中更容易发生。但是这篇文章不教你如何抓包也不提供那些工具的具体用法。我讲原理是为了让你知道WiFi密码的安全本质上不是“能不能被破解”的问题而是“破解成本有多高”的问题。我们要做的就是通过设置高熵密码、启用WPA3、关闭WPS等方式把破解成本推到攻击者不愿意承担的级别。4. Python代码实战自家WiFi密码强度检测工具4.1 扫描周围可见的网络在正式进入“检测”环节之前我们先用pywifi做一件事——扫描你周围可见的无线网络。这一步的目的是熟悉库的基本用法同时让你看到自己家的路由器在“攻击者视角”下长什么样。import pywifi import time def scan_wifi(): # 初始化WiFi接口 wifi pywifi.PyWiFi() # 获取第一个无线网卡通常情况下只有一个 iface wifi.interfaces()[0] # 扫描网络 iface.scan() time.sleep(2) # 给扫描留出时间 scan_results iface.scan_results() seen set() for network in scan_results: ssid network.ssid if ssid not in seen: seen.add(ssid) print(fSSID: {ssid} | 信号强度: {network.signal} | 认证方式: {network.akm})这里有几个要注意的点。iface.scan()是非阻塞的所以要用sleep等待扫描结果返回。scan_results()返回的是上次扫描的结果列表如果你发现结果总是空的很可能是因为扫描还没完成就读取了。另外同一个SSID可能有多个信号源比如双频路由器2.4G和5G代码里用seen集合去重了。跑一下这段代码你就能看到周围有哪些WiFi、信号强度是多少、用的什么认证方式WPA2/WPA3等。这个信息本身就是安全评估的第一手材料如果周围还有大量没有任何加密的开放网络那才是更严重的风险。4.2 自己造一个“弱密码”路由器做实验我强烈建议你做实验时不要拿家里正在使用的主路由器来测万一密码被误改了全家断网你就等着被念叨吧。最稳妥的方案是用手机开一个热点把热点名称设成Test_WiFi密码故意设成一个弱密码比如12345678。如果你手头有闲置的旧路由器也可以把它当实验网来用。但手机热点是最快的五分钟就能搭好一个合法测试环境。这样做的好处太多了第一你拥有这个热点的完全控制权怎么折腾都不影响他人第二你可以反复修改密码来验证自己的脚本是否工作正常第三你在安全合规的前提下真实地跑一遍“密码恢复”的完整流程积累了实战经验。4.3 单密码连接测试与断连控制有了实验环境我们来写一个“单密码连接测试”的函数。它的逻辑很简单指定一个SSID尝试用给定的密码去连接成功返回True失败返回False。本质上这就是“自动化逐个尝试密码”的基础单元。import pywifi from pywifi import const def try_connect(ssid, password): wifi pywifi.PyWiFi() iface wifi.interfaces()[0] # 断开当前所有连接 iface.disconnect() time.sleep(1) # 创建一份连接配置文件 profile pywifi.Profile() profile.ssid ssid profile.auth const.AUTH_ALG_OPEN # 开放认证 profile.akm.append(const.AKM_TYPE_WPA2PSK) # WPA2-PSK加密 profile.cipher const.CIPHER_TYPE_CCMP # AES加密 profile.key password # 删除所有旧配置文件再添加新配置 iface.remove_all_network_profiles() tmp_profile iface.add_network_profile(profile) # 连接并等待结果 iface.connect(tmp_profile) time.sleep(3) # 给连接过程留出时间 is_connected iface.status() const.IFACE_CONNECTED iface.disconnect() return is_connected # 测试一下 print(try_connect(Test_WiFi, 12345678))这段代码里最容易被忽略的是iface.remove_all_network_profiles()。Windows系统会自动保存WiFi配置如果系统里已经有这个WiFi的旧连接记录pywifi连接时可能会优先用旧配置导致你的测试不准确。删掉所有配置相当于让系统“失忆”确保每次测试都是干净环境。另外一个坑是sleep(3)的时长。太短连接还没建立起来就判断了会出现误报太长整个测试效率会很低。3秒是我试下来比较平衡的值但如果你在配置比较老的路由器上测试可能需要适当调长到5秒。手机热点的响应速度通常比较快3秒足够。4.4 从字典到“检测”一个完整的弱口令扫描脚本现在我们把上面的函数和字典结合起来做一个完整的“密码强度检测脚本”。效果是指定一个SSID和一本密码字典以常见的弱密码为主脚本逐个去尝试连接如果成功就打印出“检测到弱密码”。import pywifi from pywifi import const import time def check_password(ssid, password): # 对单密码做连接测试 ... # 同上文 try_connect 的实现此处省略重复代码 def scan_weak_password(ssid, dictionary_file): print(f目标网络: {ssid}) print(开始弱密码检测请耐心等待...) with open(dictionary_file, r, encodingutf-8, errorsignore) as f: for line in f: pwd line.strip() if not pwd: continue print(f尝试: {pwd}) if check_password(ssid, pwd): print(f[命中]发现该网络使用弱密码: {pwd}) return True print(未发现弱密码当前密码强度较高在本次字典范围内。) return False if __name__ __main__: scan_weak_password(Test_WiFi, common_wifi_passwords.txt)字典文件common_wifi_passwords.txt就相当于你手写的“常见弱密码清单”。内容可以包含12345678、88888888、a123456789、password、admin888、1qaz2wsx这些经典货也可以加上你平时观察到的常见习惯。但请注意这只是用于检测自家网络的字典不要拿它去测别人的网络。有一点必须严肃提醒脚本跑的每个“尝试”都会产生一次真实的连接请求并且会触发周边无线环境的电磁信号。在合法测试环境下这没有任何问题但如果用在未经授权的网络上这种行为不仅会留下日志还可能被路由器管理员或安全监控设备直接发现。到时候别怪我没提醒你。5. 破解之外那些比“算法”更致命的WiFi安全漏洞5.1 WPS暴力破解的“后门”远比密码本身容易被攻破很多人只顾着把WiFi密码设得无比复杂却忽略了一个几乎等于“开后门”的功能——WPSWi-Fi Protected SetupWiFi保护设置。这个功能的初衷是方便用户免输密码连接设备只需按一下路由器上的物理按钮或者输入一个8位PIN码就能接入网络。问题就出在这个8位PIN码上。这个PIN码的校验机制有设计缺陷路由器会先校验前4位再校验后3位最后1位是校验和。也就是说攻击者只需要穷举前4位一万种可能和后3位一千种可能总共最多一万一千次尝试就能在几小时内摸出PIN码。这是一个极其经典的“算法设计缺陷带来后门”案例。所以如果你的路由器还开着WPS哪怕WiFi密码设置成40位随机乱码攻击者也有机会通过WPS的漏洞绕过。检查一下自己的路由器后台把WPS功能关掉。这比换一个复杂密码重要得多。5.2 默认管理密码从外部攻破的第二道门WiFi密码复杂了攻击者就会把目光转向路由器管理员后台。许多家庭用户买回路由器之后从来不改管理密码还是默认的admin/admin或者admin/password。一旦攻击者连上了你的WiFi哪怕是通过访客网络他就可以直接访问路由器后台改DNS、劫持流量、植入后门那场景想一想都头皮发麻。有些人会说“管理后台只有内网才能进我不怕。”——那你可太小看“内网横向渗透”了也小看了一些路由器存在的远程管理漏洞。修改默认管理员密码是路由器安全加固里最基础、也是最重要的一步。我每次给别人做安全咨询第一件事必是改管理密码。5.3 访客网络给陌生设备的“隔离缓冲区”家里来客人要个WiFi密码很正常但你不好意思把主网络密码告诉对方那就用访客网络功能。现在的路由器基本都支持双SSID一个是主人用的内网一个是为访客准备的隔离网络。访客网络可以限速、可以设置“不允许访问内网资源”就算访客设备是个病毒窝子它也只能在外网游荡进不了你家那台NAS也扫不到你的打印机。这个功能对安全意识提升来说是一个非常实用且低成本的措施。而且它会降低“密码被朋友泄露出去”的风险——毕竟知道主网络密码的人越少越好。6. 常见问题与排查心得6.1 pywifi连接测试总失败但密码明明是对的这个问题我在自己测试时踩过好几次。最常见的原因是Windows的无线网卡驱动和pywifi库不兼容尤其在Windows 11上。一个典型表现是脚本报连接失败但手动用系统设置连接同一个WiFi却能秒连。排查思路如下确保remove_all_network_profiles()被执行避免旧配置干扰。适当延长sleep(3)为sleep(5)给连接留更多时间。尝试在管理员模式下运行脚本右键“以管理员身份运行”。某些网卡接口的读写需要更高权限。如果系统里有第三方无线管理工具比如某些笔记本自带的“联想电脑管家”“华硕网络管理”先关掉它们这些工具会抢占无线网卡的控制权。6.2 用手机热点做实验时总是连不上或断连手机热点的兼容性很迷尤其一些定制安卓系统对“被连接”的设备数量、设备类型有不少限制。我拿自己的手机热点做测试时经常遇到连接不稳定脚本显示连上了但下一轮又断开。解决办法是换一台设备当热点或者用旧路由器。如果只能手机开热点建议把“最大连接数”设置大一点并关闭“智能休眠”类功能别让热点因为“长时间无设备活动”自动关闭。另外2.4G频段比5G频段穿墙好、兼容性好做测试时优先开2.4G热点。6.3 字典很大时脚本越来越慢怎么办纯粹的Python脚本在尝试几千个密码时速度慢得感人——每一次连接测试都要等3到5秒。如果字典有上万行那跑起来简直是灾难。这不是Python本身慢的问题而是WiFi连接的物理过程决定了每一步都要等。如果你想提高效率有两个方向一是减少不必要的等待时间比如连接成功后立刻记录结果并断开而不是每次都傻等3秒二是使用多线程/多进程并发尝试——但这要非常小心并发连接请求可能会把网卡搞到“拒绝服务”状态反而适得其反。我试过用concurrent.futures并发跑结果网卡直接罢工重启才恢复。所以安全起见还是老老实实串行跑吧或者用小一点的字典。6.4 结果不可复现用最朴素的方式验证搞技术的人最怕“同一份代码别人跑不出和你一样的结果”。在WiFi这个领域不确定性因素太多了环境里的干扰波、路由器的信道拥堵、网卡驱动的状态都能让测试结果出现波动。我的做法是先用手机手动连接一次目标热点确保密码正确、网络正常然后用脚本跑同一个密码看结果是否一致。这样至少能验证脚本本身没有逻辑问题。如果脚本连“正确密码”都连不上那问题出在环境或代码上跟密码强度无关。7. 安全加固实操把自家的WiFi打造成硬骨头7.1 密码策略三位一体才能算“强”一个真正难被破解的WiFi密码应满足够长长度不少于12位推荐16位以上。够乱包含大写字母、小写字母、数字、特殊符号。够随机不要用生日、手机号、连续键盘序列如qwerty、1qaz2wsx等有规律的信息。有些路由器后台自带“密码强度检测器”可以帮你判断当前密码的安全等级但不要完全信任它它的标准和攻击者的字典是两码事。最好亲手去“常用WiFi密码合集”里搜一下你的密码如果能在合集里搜到基本就等于裸奔。7.2 加密协议能选WPA3就选WPA3WPA2已经服役十几年了虽然目前仍然很主流但它的继任者WPA3已经广泛普及。WPA3有几个重要改进引入了更强大的密钥交换机制即使密码偏弱攻击者也无法通过简单的方式离线猜测还增加了对“暴力破解”的防护机制比如锁定功能。如果你的路由器支持WPA3优先选择WPA3/WPA2混合模式以兼顾兼容性如果所有设备都比较新直接WPA3-only也行。注意启用WPA3后某些老旧设备比如十年前的老手机可能会连不上那时再切换回WPA2也来得及。7.3 隐藏SSID与MAC过滤防御价值有限的热门操作网上很多人推荐“隐藏SSID”让WiFi名字不广播和“MAC地址过滤”只允许指定设备接入。这些措施在安全圈内是有争议的我个人的看法是它们的防御价值有限但也不是毫无意义。隐藏SSID确实能让普通用户看不到网络名称减少“被攻击的曝光率”。但攻击者用扫描工具依然能通过分析无线流量里的SSID字段就算隐藏了名字还是会在某些包中明文出现找到这个网络。同理MAC地址过滤也能被轻易绕过——攻击者监听一下你的设备MAC然后克隆过来就能混进去了。这两项措施的真正价值主要是提高了一点攻击门槛和误伤率但别把它们当成主要防线。真正值得做的还是前面提到的复杂密码、WPA3、关闭WPS、修改管理密码、开访客网络。7.4 定期检查已连接设备发现异常的第一道关口最后养成定期查看路由器后台“已连接设备”列表的习惯。看到陌生设备不要只当没看见。快速排查方法记下你自己的所有设备手机、电脑、平板、电视、智能音箱、扫地机器人等的MAC地址在路由器后台把不认识的设备拉黑或限速。如果你发现不认识设备一直在连接你的网络那说明密码很可能已经泄露了建议立即改密码并检查是否有路由器后门风险。我把这个习惯安利给身边所有人操作成本不到一分钟却能防住大部分蹭网和恶意接入。安全的事防患于未然永远比事后补救省心得多。8. 写在最后技术本身无善恶用者须有敬畏心回到文章开头那个话题。我见过太多人懵懵懂懂地搜索“WiFi破译”“暴力破解”以为这是一件“好玩”的事情直到被网安叫去喝茶才后悔莫及。技术本身没有善恶Python不会主动区分“破解自己家的密码”和“破解别人家的密码”区别全在使用者的一念之间。这篇文章通篇的落脚点是“安全自检”。我从威协建模的角度带你拆解了攻击者可能使用的思路又用Python写了密码强度检测脚本最后给了你一套完整的加固方案。这套思路放到企业安全测试里叫“渗透测试”放到家庭环境里叫“安全自查”——本质是同一个东西站在攻击者的角度看问题然后把自己保护的体系修补到攻击者不愿再碰的程度。我个人在实际操作中的体会是安全意识不是一次性的而是不断变化的对抗过程。你今天把密码设成天书一样的乱码明天诈骗分子可能就盯上了路由器漏洞你今天关了WPS明天又有新漏洞爆出来。所以安全不是“做了某件事就一劳永逸”的状态而是一种需要持续关注的习惯。希望你能把这篇文章里讲到的加固操作落实在自己家路由器上同时管住自己的手别去碰不属于自己的网络。多一分自律就少一分风险这不仅是保护别人也是保护你自己。
返回列表