news 2026/10/1 2:23:58

Python+弱口令字典:从清洗到批量验证的完整工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python+弱口令字典:从清洗到批量验证的完整工程实践

简介:一线网络安全学习者常为缺少现成字典而发愁,这份Python工具包恰好提供常见弱口令字典与WiFi密码破解脚本,面向安全测试初学者,用来快速搭建无线密码检测环境。压缩包内仅两个文件,整体大小为十四KB,但结构完整:txt字典按高频弱口令和少量英文密码逐行整理,可轻松导入其他自动化工具;py脚本演示了无线网卡信息读取、字典遍历和密码比对的整个流程,逻辑清晰,适合边调试边学习。目前已有10524人浏览学习,说明该资源在安全圈子里受到了广泛关注。借助它,读者既能直接使用字典开展一次口令强度测试,也能拆解脚本理解字典攻击的常见写法,后续还可自行扩充字典、修改匹配逻辑,形成自己的工具模块。需特别说明的是,该内容仅供授权环境下的技术研究和测试,严禁用于未授权的网络攻击。

1. 从弱口令字典到“一键跑批”:这个脚本组合到底解决什么问题

如果你维护过几台路由器、几十个摄像头或者公司内网的一批测试账号,一定会遇到同一个尴尬:设备回来第一件事是登录,可出厂默认密码、前任工程师留下的弱口令、同事随手设的“123456”,能让你在命令行前耗掉一整个下午。网上流传的所谓“常见密码字典”大多是几万甚至几十万条的巨型弱口令合集,跑起来又慢又乱;而真正工作中需要的,往往只是几百条“足够常见”的弱口令,再加少量英文单词组合,就能覆盖大多数默认设备和内部系统的密码习惯。

这套“python+常见密码字典”的组合,本质上不是要你去海量撞库,而是把“常见弱口令+少量英文”整理成一份干净、可复用、可扩展的字典文本,再用几十行Python脚本把它送到目标系统里去验证。它解决的问题是:让密码验证从手工一条条试,变成脚本批量跑;让字典从“网上随便下载的一大坨”,变成你手里能看、能改、能随时加料的资产。适合的人群是运维、安全测试初学者、物联网设备管理者,以及任何想把“试密码”这件事从玄学变成工程的开发者。

2. 字典才是主角:弱口令与英文词的筛选、去重和格式清洗

2.1 先搞懂“常见密码字典”的分层:通用弱口令、设备默认口令、英文组合

网上能下载的弱口令字典动辄几百MB,但真正能派上用场的部分其实很少。我一般会把字典内容分成三层来整理。

第一层是通用弱口令,也就是所有系统里最常见的那些:admin、root、123456、password、admin123、test、guest。这一层是字典的地基,不管目标是路由器、数据库还是Web后台,都可以先拿这一层去试。第二层是设备默认口令,这部分带有明显的品牌和型号特征,比如某些摄像头厂商初始密码是admin:admin,某些光猫出厂是user:1234或admin:telecomadmin。第三层才是“少量英文”,也就是你根据目标业务场景猜出来的词:公司名、品牌名、产品名、城市名,加上年份和特殊符号后缀,比如Huawei@2024。

我的经验是,这套“少量英文”不要贪多。网上那些几十万的字典,问题在于低频词太多,跑起来费时间不说,还容易触发目标系统的锁定策略。整理字典时优先保证“精”而不是“多”,一份300到500条的常见密码字典,在大多数设备上的命中率已经相当可观。

2.2 字典来源与格式清洗:字符编码、换行符和去重的三个关键点

字典文件的来源有几个,最常见的渠道是开源社区的密码字典库、安全工具自带的字典目录,以及GitHub上别人整理好的Weakpass合集。但拿到手之后不能直接用,脏数据会浪费你大量时间。

第一件必须做的事是统一编码。Windows下保存的字典文件,很多是GBK或者带BOM的UTF-8,Python读出来第一行会带\ufeff,直接导致第一条密码匹配永远失败。用utf-8-sig编码读取可以解决BOM问题,但如果文件本身是GBK,utf-8-sig会直接抛异常。稳妥的做法是先用chardet库探测编码,再读取,这段代码在清理阶段必写:

import chardet def detect_encoding(path): with open(path, 'rb') as f: data = f.read(1024) result = chardet.detect(data) return result['encoding'] or 'utf-8' # 用法:先用探测拿到编码,再交给后续清洗流程 enc = detect_encoding('weakpass.txt') print(f"检测到的编码: {enc}")

chardet.detect读取文件头部1KB的字节,返回一个带encoding字段的字典。这个方案能覆盖绝大多数GBK和UTF-8混存的脏文件,虽然慢一点,但清洗阶段一次慢总比跑批时反复出错强。

第二件事是统一换行符并清洗空白。Linux和Windows的换行符分别是\n和\r\n,直接按行读取时,\r会残留在密码末尾,导致实际发送的密码多了一个不可见字符。用str.strip()处理每一行,同时把空行过滤掉,这是最基础但最有效的清洗。

第三件事是去重。几十万条的字典里,admin123出现几十次并不奇怪,不去重意味着同一个密码会被重复验证多次,浪费时间不说,还可能让目标系统更快触发锁定。用set去重是最直接的方案,但去重前必须处理好大小写——Admin和admin在多数Linux系统里是两个不同的密码,在Windows服务里却可能被当成同一个。我一般会保留原始大小写,同时额外生成一份小写列表用于对比统计,这样既不丢失原始候选,又能看清字典的组成结构。

2.3 用Python做一次完整的字典预处理:去重、排序、过滤短密码

把上面的思路落成一个可以反复执行的脚本片段,我会把它放在字典更新的流水线里,保证每次手动往文件里加了新密码后,跑一遍就能得到一份干净的产物:

def clean_dict(input_file, output_file, min_len=4, max_len=32): seen = set() cleaned = [] with open(input_file, 'r', encoding='utf-8', errors='ignore') as f: for line in f: pwd = line.strip() if len(pwd) < min_len or len(pwd) > max_len: continue if pwd in seen: continue seen.add(pwd) cleaned.append(pwd) # 按长度再按字母序排序,跑批时优先试短密码 cleaned.sort(key=lambda x: (len(x), x)) with open(output_file, 'w', encoding='utf-8') as f: f.write('\n'.join(cleaned)) return len(cleaned) # 参数说明:min_len=4 过滤掉 'aa' 这类无意义短串 # max_len=32 是多数设备密码字段的上限 print(f"清洗完成,剩余密码数: {clean_dict('raw_dict.txt', 'clean_dict.txt')}")

这段逻辑里值得说的是排序策略。按长度排序的意义在于,大多数设备的默认密码和弱口令都不会太长,4到12位的密码占用字典总量的大部分,先跑短的可以更快“试出”结果。errors='ignore'参数让读取过程不被个别非法字节中断,并且排序时保留原始大小写形式,不做统一小写处理。

清洗完成后,字典文件的基本格式就是每行一个密码,无空行、无重复、无首尾空格。这样的文件才能进入下一阶段的脚本验证。

3. 把字典跑起来:Python脚本的结构、并发控制与验证逻辑

3.1 字典怎么“喂”给脚本:目标类型决定验证方式

字典本身只是一份文本,真正让字典发挥作用的是“验证”这一步。不同目标有完全不同的验证方式:路由器管理页面通常是HTTP Basic认证或表单登录;SSH服务需要走paramiko库做账号密码认证;内网数据库则用对应的数据库驱动做连接测试。

我见过很多新手把验证逻辑写死在一个函数里,换一个目标类型就得重写整个脚本。更好的做法是把“字典加载”和“验证逻辑”拆成两层:字典层负责逐条吐出密码,验证层负责定义“什么算验证成功”。以最常见的HTTP表单登录为例,验证成功的标志通常是登录后跳转的URL变化、返回的响应码是302而不是200、或者响应体里出现了“欢迎”等关键字,三种标志组合使用最稳。

3.2 一个可复用的Python验证框架:requests实现表单登录批量验证

下面的代码实现了一个针对Web登录页的批量验证框架,配合前面清洗好的字典文件,可以直接跑通“读字典—逐条尝试—记录结果”的完整链路:

import requests, threading from queue import Queue results = [] def check_password(base_url, username, pwd, success_flag): session = requests.Session() try: r = session.post( base_url, data={'username': username, 'password': pwd}, timeout=5, allow_redirects=False ) # 登录成功通常伴随302跳转,但需配合响应体关键字二次确认 if r.status_code == 302 and success_flag in r.text or r.status_code == 200 and success_flag in r.text: results.append((username, pwd)) return True except requests.RequestException: pass return False def run_batch(dict_file, base_url, username, success_flag, threads=5): q = Queue() with open(dict_file, 'r', encoding='utf-8') as f: for line in f: pwd = line.strip() if pwd: q.put(pwd) def worker(): while not q.empty(): pwd = q.get() if check_password(base_url, username, pwd, success_flag): print(f"[+] 命中: {username}:{pwd}") q.task_done() thread_list = [] for _ in range(threads): t = threading.Thread(target=worker) t.start() thread_list.append(t) q.join() # 参数说明:threads控制并发数,建议从5开始调 # success_flag是登录成功后响应体里才出现的字符串 run_batch('clean_dict.txt', 'http://192.168.1.1/login', 'admin', 'dashboard')

这段代码的精髓在allow_redirects=False这一步。很多登录接口成功后返回302跳转,如果requests默认跟随重定向,你就看不到登录成功那一次的真实响应码;禁用后,302就变成了直接的“登录成功”信号。success_flag的二次校验则可以避免把“密码错误也返回302”的接口误判成命中——有的系统对错误密码也会做一次跳转刷新,两者配合能大幅降低误报。

线程数的设置值得单独说。5个线程在大多数家庭路由器上不会触发锁定,但对一些带防暴力破解的网关设备,连续快速尝试超过15次就会锁IP。更稳的做法是先跑一次“小字典”(比如只跑前50条)观察目标反应,确认没锁再放开全量跑批。

3.3 组合扩展:让“少量英文”变成有规律的候选集

字典里的“少量英文”部分,不应只是一串孤立的单词,而应该通过程序化组合扩展出更大但仍有规律的候选集。比如你有admin和test两个单词,想生成admin123、Admin@2024、test2024这类变体,靠人工手写太累了,让Python来做这件事:

import itertools base_words = ['admin', 'root', 'test', 'guest'] suffixes = ['123', '1234', '2024', '@2024'] combinations = set() for word, suffix in itertools.product(base_words, suffixes): combinations.add(f"{word}{suffix}") combinations.add(f"{word.capitalize()}{suffix}") # 生成结果是组合候选集,需合并进主字典并再次清洗去重 with open('extend_words.txt', 'w') as f: f.write("\n".join(combinations)) print(f"组合候选数: {len(combinations)}")

itertools.product做笛卡尔积,把4个基础词和4个后缀两两组合,每组又生成首字母大写版本,总共得到32条候选。这个数字不大,恰好符合“少量英文”的定位。需要注意,扩展出的候选不能直接塞进主字典,必须回到清洗流程再跑一遍,防止和已有条目重复,也防止Admin@2024和admin@2024这种大小写变体数量失控。

组合扩展的度很关键,我见过的翻车案例是有人把30个基础词、15个后缀全量组合,生成了几千条候选,把原本干净的小字典变成了一坨垃圾。组合的目的是覆盖“目标可能用了单词+年份/数字”的场景,不是追求数量上的满足感。

4. 避坑指南:字典和脚本跑批的6个高频翻车点

4.1 字典第一行是乱码或永远匹配不上:BOM头和GBK编码的坑

现象是脚本跑完几十条,没有一条命中,但手工复制字典里的密码去登录却能成功。原因几乎都是文件读取时编码不对,最常见的就是UTF-8 BOM头让第一条密码变成了\ufeffadmin,以及Python按UTF-8读取GBK编码文件时,每个汉字都变成乱码。

解决分两步:第一步用chardet探测编码,把结果用在open()的encoding参数上;第二步读取后统一做pwd = pwd.strip(),如果pwd.startswith('\ufeff')就直接丢弃。清洗流程固定住之后,这类问题基本不会再见。

4.2 频繁触发目标系统的账户锁定:并发太高、试错太快

很多路由器管理页面和Web后台有登录失败次数的限制,连续错了5到10次会锁定几分钟甚至更久。现象是脚本跑到一半,目标网站突然返回429或403,后续请求全部失败。

解决的关键是控制节奏。把线程数调低到3,每次尝试后加一个随机延迟。Python里实现随机延迟很简单,time.sleep(random.uniform(0.5, 1.5))。另外,务必在脚本里记录已经尝试过的密码清单,一旦触发锁定,下次跑批直接从断点恢复,而不是从头再来。

4.3 大量误报:把“密码错误”也当成验证成功

有些登录接口无论密码对错都返回302跳转,区别只在跳转的目标URL不同。如果脚本只检查状态码,就会出现大量假命中——账密根本不对,但脚本报成功。

解决的办法是三重确认:一查响应码,二看跳转后URL里有没有dashboard、main等关键字,三看响应体里有没有错误提示的关键词(如error、invalid)。三个信号里至少两个指向成功才记录结果。这一条是脚本准确率的核心,也是最容易被忽略的。

4.4 脚本一跑就报内存错误:字典文件太大全读进了内存

有人把网上几十万条的豪华字典直接喂给脚本,还一次性读入内存。现象是脚本启动缓慢,跑一会儿内存占用飙到几GB,最后直接卡死。

解决方法是把“读文件”改成“逐行处理”。上面的run_batch用的是for line in f方式,文件不会一次性载入内存,这是正确处理大字典的标准姿势。如果还需要更大规模,建议改用mmap按需读取,但日常场景下逐行迭代已经足够。

4.5 同一个密码重复跑了无数次:忘了去重或大小写处理不一致

字典里同时存在admin和admin123不算重复,但Admin、ADMIN、admin在目标系统里如果是大小写敏感的,这三条都该保留;如果明确知道目标系统不敏感,那重复试三次就是纯粹的浪费。

解决方式因地制宜:对大小写不敏感的目标,在做字典清洗时统一转小写再去重;对Linux类目标,保留原始大小写但做精确去重。另一个容易忽略的重复来源是首尾空格——pwd = " admin "被strip()处理后变成admin,但如果忘了strip,就会把admin原样发出去,既失败又造成重复。

4.6 WiFi场景下最容易搞错的定位:目标网卡的监控模式和握手包捕获

标题里提到了WiFi密码破解脚本,这里必须先说明边界:工程上对自家忘记密码的WiFi,最实用的恢复手段还是登录路由器后台查看,或者在已连接设备上查看已保存密码,而不是去跑握手包破解。后者的前提是抓到你本人在授权测试范围内的握手包,而且目标WiFi的密码强度通常决定了破解是否可行——你手里的弱口令字典对WPA2网络碰巧命中是有可能的,但字典里没有的强密码,跑多久都是白费。

如果你真的需要跑一次抓包验证,最值得注意的坑有两个:第一,无线网卡必须支持并切换到监控模式,否则抓不到完整握手包;第二,抓包时客户端需要在信号覆盖范围内,最好先让目标设备断开重连一次,否则握手包信息不完整。按授权协议把抓包范围限制在自己或公司设备上,这些操作才不会跑偏。

5. 最后一步:验证脚本的准确率,把“附赠”变成可控的生产工具

脚本能跑通只是第一步,能不能放心用于正式环境,取决于你怎么验证它。我的做法是搭一个本地验证环境,用最简单的Flask应用模拟一个带登录接口的系统,然后故意设置一个弱口令admin:admin123,再把字典清到只剩两条候选去跑批。如果脚本能稳定命中且没有误报,换到真实目标前就放心了。

验证时重点看三项指标:命中结果里有没有假阳性(拿错误密码上报成功)、有没有漏报(密码文件里存在但没跑出来)、以及触发锁定时的恢复能力。建议在脚本里加一个结果输出开关,--quiet模式只打印命中的账密,--verbose模式输出每条尝试的响应码和耗时,这样排查问题时不用反复改代码。

跑批完成后,把命中结果和完整尝试记录分文件保存,尝试记录以时间戳|密码|响应码的格式留痕。这个习惯帮我解决了不少“事后说不清”的麻烦——哪些密码试过、什么时间试的、当时目标返回什么,都有据可查。

我自己的教训是:字典永远比脚本重要。脚本只是搬运工,字典里的词才决定了命中率。哪怕脚本写得再漂亮,字典里没有目标用的密码模式,跑一夜也是零命中。反过来,一份精心维护的几百条字典,配合上并发和重试控制得体的脚本,在大多数场景下的收益远高于那些动辄几十万条的“全能字典”。

希望这份从字典整理到脚本跑批的完整路径能帮到你。先从小字典、低并发起步,把验证逻辑调到零误报,再逐步放开规模,这一套走稳了,密码验证这件事就不再是玄学,而是真正可控的工程流程。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 2:23:48

软件测试课后题答案别乱用!三步复盘法助你面试通关

先说个真实的场景。我经常在技术社群里看到有人问“黑马程序员《软件测试》第二版的课后题答案有没有”&#xff0c;底下往往是一堆求资源、留邮箱的回复。但说句得罪人的话&#xff0c;多数人拿到答案之后&#xff0c;干的第一件事就是把选择题答案背下来&#xff0c;然后去考…

作者头像 李华
网站建设 2026/10/1 2:22:05

LaTeX 论文排版实战:Windows 下 TeX Live 安装与报错排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 2:18:50

YOLOv8智慧工地安全绳检测实战:从数据集到部署全流程解析

简介&#xff1a;一套面向智慧工地场景的未戴安全绳自动预警系统&#xff0c;基于YOLOv8目标检测框架实现&#xff0c;专门解决高处作业人员未佩戴安全绳的实时识别问题。资源包含完整Python源码、已标注训练数据集、训练好的模型权重以及可视化操作界面&#xff0c;可一键生成…

作者头像 李华
网站建设 2026/10/1 2:17:43

YOLOv5飞机鸟类无人机检测:训练模型+数据集+PyQt界面全流程

简介&#xff1a;本资源面向计算机视觉学习者与目标检测开发者&#xff0c;提供一套细分类型飞机、鸟类与无人机的YOLOv5检测训练方案&#xff0c;重点在于可区分具体飞机型号&#xff0c;适合课程设计、科研实验与算法对比等场景。压缩包共约2000个文件&#xff0c;以1994个tx…

作者头像 李华