简介:这是一款开源免费的Web后台弱口令与万能密码批量爆破检测工具,面向网络安全审计人员、渗透测试工程师及网站管理员,用于自动化发现后台登录弱口令,帮助提前修复安全隐患。资源共18个文件,压缩包约114KB,主体为12个Python源码文件,涵盖核心爆破任务、参数解析、字典生成与配置模块;另有3个txt文件提供密码字典与URL列表,并附README说明文档和项目示意图片,目录结构清晰可快速上手。目前已有407人学习下载。通过研究源码可理解批量爆破的完整实现流程与字典构造思路,也可直接修改配置文件自定义目标与密码列表,用于合法授权范围内的安全检测与教学演练。需要提醒的是,该工具应仅用于合规的渗透测试场景,切勿用于未授权目标。
1. WebCrack:批量爆破不是无脑堆字典,是门技术活
某次授权测试,某公司的内部OA后台有十几套系统,后台地址分布在好几个网段。手工试弱口令,一个后台试十分钟,两个晚上只测完三套。换成 WebCrack 批量跑:目标列表一行一个,字典用常规弱口令加目标信息构造的组合,一万多条密码,五分钟左右扫完一套。最后在其中一个旧后台里命中管理员账号,密码是「公司名拼音+年份+123」。手工做不到这个速度,更做不到把几十个后台统一跑一遍再统一出报告。
这篇不是工具说明书,是我把 WebCrack 这类批量爆破工具用顺手之后沉淀下来的完整流程:后台地址怎么找、登录参数怎么抓、字典和并发怎么配、万能密码在什么场景下值得测、跑出来的结果怎么二次验证。新手可以直接照着流程把第一轮跑通,熟手可以重点看第 3 章的并发策略和第 5 章的排查思路,那部分是实打实踩出来的。
2. 上手:先摸清工具的边界,再跑第一次实战爆破
2.1 工具能干什么、不该拿它干什么
WebCrack 的定位从名字就能拆开:web 后台、批量、弱口令/万能密码、检测。它解决的是「手里有一批后台地址,想统一验证账号口令强度」的问题,不是用来探索目标的。它不爬站、不扫端口、不做目录枚举,目标 URL 和登录参数都要你自己准备好。
我一般会先给它划三条边界,避免高估工具能力:
- 不识别验证码。带验证码的登录框直接放弃,或者找同系统的备用入口;
- 不做动态 token 处理。如果登录表单里带 csrf_token,要么先把 token 从页面取出来拼进参数,要么跳过这个目标;
- 不保证字典之外的口令能被发现。弱口令检测的上限由字典决定,万能密码只是补充,不是银弹。
边界清楚了,后面所有操作都围绕一件事:把「目标、字典、登录参数」这三样喂给工具,然后对结果做可信度判断。工具本身不复杂,复杂的是配参数和筛结果。
2.2 第一次爆破的完整流程:从目标 URL 到命中结果
我第一次用这类工具时犯过一个错:一上来就全量跑,结果跑出来一堆命中,逐一验证全是假的。后来我总结了一套固定顺序,先小范围验证参数,再全量执行。
第一步,准备目标列表。后台地址来源一般是三处:端口扫描结果里 80/443/8080 的入口、登录页面特征(比如路径里带 admin、login、manage)、前端源码里泄露的接口。把这些 URL 存成一个targets.txt,每行一个。
第二步,准备账号字典。先不急着自己造,用工具内置的常见账号名表跑一遍探测,确认登录接口的账号字段有效。users.txt内容大致是 admin、administrator、root、test、manager 这类。
第三步,抓登录参数。用浏览器无痕窗口打开目标登录页,F12 切到网络面板,提交一次错误密码,看表单实际提交的字段名。常见字段是username、password,但也见过用user_name和pwd的,还有把提交按钮的值也拼进去的。字段抓错,爆破永远不成功。
第三步做完,就可以跑第一次小范围验证。命令行我用的是下面这套,参数名各版本可能有差异,但逻辑是通用的:
webcrack \ -u http://192.168.1.10/admin/login.php \ -U ./users.txt \ -P ./weak-pass.txt \ --data "username=^USER^&password=^PASS^&submit=登录" \ --succ "欢迎回来" \ --fail "用户名或密码错误" \ --code-ok 302 \ -t 5 \ --delay 0.3 \ -o ./result.csv各参数含义:
-u:目标登录接口地址,不是后台首页,而是接收账号密码的那个 URL;-U/-P:账号字典和密码字典的路径;--data:登录表单的 POST 数据模板,^USER^和^PASS^是占位符,工具会自动替换;--succ和--fail:判断登录是否成功的文本特征,从登录响应里挑两段互不冲突的关键字;--code-ok:有些系统登录成功返回 302 跳转而不是直接渲染页面,这种情况下文本特征不可靠,得用状态码判断;-t和--delay:线程数和每次请求间隔,第一次跑我习惯用 3~5 个线程,给目标留余量;-o:结果输出文件,CSV 格式,后面二次验证要用。
2.3 登录参数和后端鉴权方式:判断命中前的最后一道功课
通过--succ和--fail判断命中,是大多数爆破工具默认的做法,但这里有个很大的黑匣子:目标系统不一定按你给的文字特征返回。我在实战里总结出一套优先级,按这个顺序确认命中的可信度:
响应状态码变化最可靠。比如登录失败返回 200 且页面带错误提示,登录成功返回 302 跳转,那--code-ok 302就是最强的判断条件,文本特征只做辅助。
其次是响应长度和关键字组合。有些系统错误提示和成功页面长度差异很大,可以用长度阈值;有些系统无论成败都是 200,只能靠页面里的具体文字区分,比如错误提示「用户名或密码错误」和成功后的「欢迎回来」。
最后才是判断 Cookie 或跳转 Location。登录成功后服务端通常会下发 session Cookie 或把页面跳转到/index.php,这些特征比页面文字更难伪造。工具跑完之后,我会把命中的条目单独抽出来,用真实浏览器带 Cookie 访问一次后台首页,这一步在本文第 4 章会细讲。
我第一次跑的时候,把--succ误配成了登录页面上本来就有的文字,比如「找回密码」——这个文字在登录失败时也出现,导致所有用户名都被判成命中。后来加了一条规则:成功特征必须选只在登录成功后出现的内容,拿不准就先手工登录一次,把成功响应的 HTML 存下来对比。
3. 爆破核心三件事:字典怎么造、并发怎么调、万能密码怎么测
3.1 字典不再玄学:按三级结构组织,先小后大
很多新人拿到工具第一件事就是去找那种几千万条的超级字典,跑起来又慢又容易被限速。我的习惯是分三级,按目标反馈决定要不要升级:
| 层级 | 字典内容 | 条数 | 适用场景 |
|---|---|---|---|
| 第一级 | 常见弱口令:admin/123456、test/test、root/root、空口令 | 100~500 | 临时系统、测试环境、默认口令未改的老系统 |
| 第二级 | 基于目标信息构造:公司名拼音、域名前缀、年份、常见组合 | 1000~10000 | 业务系统,密码含组织特征的内部系统 |
| 第三级 | 通用高频密码库加关键词变形 | 5万~50万 | 重点目标、社交媒体类密码习惯 |
第一级字典不是用来碰运气的,是用来验证工具链路通不通。如果工具配置、登录参数、判断条件都正确,第一级字典跑不出任何命中,那得先检查是不是编码或参数有问题,再考虑换更重的字典。
第二级字典才是爆破的核心价值。内部系统的用户起密码,普遍喜欢拿公司相关词做基础,再加数字和符号。我在某次测试里,目标后台登录页提示「密码长度 8-16 位,须含字母和数字」,手工猜了几组全失败,后来按「域名核心词 + 两位年份 + 序号」生成了一批组合,十分钟内命中了三个账号。注意:这种构造规则不要写成固定脚本硬编码进字典,要在每次测试前根据目标信息现场生成,关键词过时了,字典就是废纸。
第三级字典我只在重点目标上用,而且是先确认目标不卡验证码、不限速、服务器响应延迟正常之后才开跑。几万条密码对着一个后台跑,对目标服务器是有实际压力的,这必须建立在你有合法授权的基础上。
3.2 并发和延迟:不是越大越快,是越快越容易翻车
爆破工具默认给了并发参数,很多人直接拉到 50 甚至 100。我的经验是:线程数翻倍,速度未必翻倍,被封的概率一定翻倍。目标侧的反应路径大致是——短时间大量失败请求,触发登录失败计数;连续 N 次失败后,同一个 IP 被临时封禁;再严重一点,整个网段被 WAF 策略拉黑。所以并发配置要按目标性质分档:
- 内网测试环境、响应快的系统:线程 5~10,延迟 0.2~0.5 秒;
- 响应慢的旧系统:线程 3~5,延迟 1 秒以上,先把单请求的平均响应时间测出来,再决定并发;
- 有风控策略的生产系统:线程 1~2,延迟 2~5 秒,或者直接改跑小字典精确打击,不要做全量。
我见过最惨的一次翻车:对某目标开了 30 线程跑,十分钟后目标直接拒绝连接。检查发现是目标本身性能差,30 个并发请求把应用服务器打崩了,日志里全是连接超时。从那以后我给自己定了一条规矩:任何目标,第一轮先用 3 线程跑 200 条左右,看响应时间和失败率,再决定要不要加并发。
关于延迟还有一个容易忽略的点:延迟参数要大于目标单次请求的响应时间。如果目标响应要 1 秒,你延迟设 0.2 秒,实际就是每 1 秒发 1 个请求,配置和实际不符,跑出来的总时长会远大于预期。判断方法很简单,先手工发两个请求看响应耗时,再把这个值放大两倍设成延迟。
3.3 万能密码批量检测:原理、payload 与适用场景
万能密码不是新东西了,但很多爆破工具没把它独立出来。WebCrack 把「弱口令检测」和「万能密码检测」分成两类,这个设计是有道理的:弱口令的逻辑是碰运气撞真实密码;万能密码的逻辑是打目标登录校验的逻辑缺陷,两者原理完全不同,验证方式也不一样。
常见的万能密码方向有五类:
# SQL 注入绕过类,针对登录查询未做参数化的情况 admin' or '1'='1 ' or 1=1 -- admin' or '1'='1' # 弱类型比较类,针对 PHP 松散比较导致的判断绕过 admin" or "1"="1 ' or 'a'='a # 逻辑缺陷类,针对只校验用户名是否存在的写法 admin'-- ' or 1=1#这些 payload 能起效,前提是目标登录逻辑存在对应缺陷。我的用法是先把万能密码单独一个文件跑一轮,不跟弱口令字典混在一起。原因很实际:弱口令跑出来的命中,密码是真实可用的,验证时直接登录即可;万能密码跑出来的命中,往往用户名也会被带偏,容易在结果里搞混。分开跑,每轮结果的处置方式都清晰。
哪种目标适合测万能密码,我一般看两点:一是后台技术栈,PHP 系优先测弱类型和注释符类 payload,Java 系和.NET 系相对少;二是登录页有没有明显的拼接特征,比如错误提示把输入的用户名直接回显在页面上,这种最值得测。测验证的细节在第 4 章讲。
4. 结果验证:三层校验,把假阳性挡在报告外面
4.1 第一层看文本特征,第二层看状态码和 Cookie,第三层看登录后动作
工具跑完输出result.csv,这只是候选名单,不是结论。爆破成功这件事,工具说了不算,二次验证说了才算。我在第 2 章提过判断优先级,这里把它拆成完整的三层校验流程:
第一层,按工具内置的文本特征过滤。工具已经在自动化检测时判断过一次,这里再查是确认 CSV 里的命中条目确实包含--succ指定的特征。这一步能挡掉「成功特征配置错误导致的全量误报」。
第二层,带状态码和 Cookie 验证。手工起一个抓包工具或直接用脚本,用候选账号密码真实提交登录请求,检查三件事:返回状态码是否符合预期、Set-Cookie 里有没有会话标识、跳转的 Location 是不是登录后才能访问的页面。Cookie 是关键,很多误报在这一层暴露:页面文字照着成功页返回了,但服务端根本没下发 session,说明校验逻辑没通过。
第三层,登录后动作验证。用一个需要登录才能访问的页面(比如后台首页、用户列表页),带着第二层拿到的 Cookie 去请求。如果该页面正常返回且包含预期内容,才算真正确认这个口令有效。到这一层,误报基本被清干净了。
我一般会把这个逻辑写成脚本,一次跑完整批结果,而不是一个个手工点。
4.2 一个顺手可改的验证脚本
下面这个脚本按第三层校验逻辑,对result.csv逐行做登录验证,并把确认结果单独输出:
import requests import csv import time def verify_login(url, username, password, data_template, check): # 用独立会话模拟一次真实登录,避免污染其他目标的 Cookie session = requests.Session() data = data_template.replace("^USER^", username).replace("^PASS^", password) resp = session.post(url, data=data, allow_redirects=False, timeout=8) # 第一层校验:文本特征必须命中 if check.get("ok_text") and check["ok_text"] not in resp.text: return False, resp.status_code # 第二层校验:预期状态码,若配置了 302 就严格比对 if check.get("ok_code") and resp.status_code != check["ok_code"]: return False, resp.status_code # 第三层校验:带着登录后的 Cookie 访问受限页面 if check.get("verify_url"): page = session.get(check["verify_url"], timeout=8) if check["ok_text"] not in page.text: return False, page.status_code return True, resp.status_code if __name__ == "__main__": with open("result.csv", "r") as f: rows = list(csv.DictReader(f)) for row in rows: ok, code = verify_login( url="http://192.168.1.10/admin/login.php", username=row["username"], password=row["password"], data_template="username=^USER^&password=^PASS^&submit=登录", check={ "ok_text": "欢迎回来", "ok_code": None, "verify_url": "http://192.168.1.10/admin/index.php", }, ) if ok: print(f"[确认] {row['username']} / {row['password']} 状态码 {code}") time.sleep(0.5)脚本里几个参数按实际情况替换:url和data_template必须与爆破时完全一致,check["ok_text"]换成登录成功页面唯一出现的文字,verify_url通常填后台首页。跑之前先拿一组已知正确的账号密码测一遍,确认脚本本身没问题,再跑全量结果,否则脚本配置错了,会把真实命中也过滤掉,我之前就吃过这个亏。
另外注意脚本里的time.sleep(0.5)不是摆设。批量验证同样会对目标产生请求压力,验证阶段虽然请求量小,也要留间隔。输出到终端只是给人看的,如果结果要进报告,改成写入 CSV 即可。
5. 避坑:WebCrack 实战里最常见的五个翻车现场
5.1 跑了半天零结果:先检查判断参数,而不是怀疑字典
现象:字典没问题,目标也确认了,命令跑完一个命中都没有。
原因:九成是--fail或--succ配错了。我遇到过目标登录失败时返回 200,登录成功也返回 200,页面内容几乎相同,只是成功时多了个 Cookie;也遇到过错误提示是「账号或密码不存在」,我拿「不存在」当失败特征,结果登录成功页面也包含这个词,导致所有结果都被过滤掉。
解决:先手工登录一次,把成功和失败的完整响应分别保存下来,用文本编辑器对比差异,挑一段只在成功响应里出现的片段做--succ;如果两者文本完全一致,改用状态码或 Cookie 特征。
5.2 满屏都是命中:典型假阳性,别急着上报
现象:跑了几百条就出了几十条命中,浏览器验证却发现登录全部失败。
原因:最常见的是成功特征选得太宽,比如选了页面底部的版权文字,这个文字在登录失败页面也存在;其次是目标登录失败和成功共用同一套前端模板,只有 JS 里判断结果,服务端响应没有差异;还有一种是字典里的账号本身就是已锁定状态,响应里带着「多次失败已被锁定」的提示,却被--succ误匹配。
解决:按第 4 章的三层校验重新过一遍,优先加状态码和 Cookie 条件。如果确认判断参数无误但仍大量假阳性,怀疑是目标存在「提示统一化」机制,这类目标不适合用文本特征判断,考虑放弃或改用登录后动作验证。
5.3 跑着跑着越来越慢:被限速或封 IP 了
现象:前两分钟速度正常,后面开始大量超时,最后请求直接被拒绝。
原因:目标侧有登录失败计数或 IP 风控,短时间大量失败请求触发了策略。这是爆破里最常见的血泪经验,不是你网络的问题,是目标在反击。
解决:立即停掉,等一段时间让计数清零;换目标 IP 前先想清楚授权边界;后续调低线程、增大--delay,并且在字典结构上优先跑高概率组合,而不是拿超大字典硬刚。如果目标明确写接口有「接口调用频率限制」,那更要严格遵守。
5.4 账号密码全是中文却乱码:编码没对齐
现象:字典里中文内容提交后,目标返回的提示变成乱码,或者工具提示请求数据格式错误。
原因:字典文件编码和目标页面编码不一致。比如目标页面是 GBK,字典存成 UTF-8,提交的 POST 数据里中文字节错乱;反过来也一样。
解决:先看目标页面<meta charset>或响应头里的 Content-Type,再把字典文件转成对应编码。Linux 下用iconv -f utf-8 -t gbk dict.txt > dict-gbk.txt转换,注意转完后目标里如果是 GBK 页面,判断用的--succ文本也要用同编码写入命令。
5.5 授权范围没理清:工具没问题,用法有红线
现象:工具正常跑完,结果也验证了,但后续推进困难,因为测试范围早就超出了当初说好的授权边界。
原因:爆破工具的特性决定了它会触碰大量账号,测试前没有把「目标范围、测试账号范围、测试时段、是否允许对生产系统做全量爆破」这些边界谈清楚。
解决:先落一份文字确认的授权范围和测试计划,明确允许爆破的 IP 段、域名、测试时段的起止,以及发现弱口令后的处置流程。每次跑之前把目标列表过一遍,确认没有授权之外的地址。这个习惯在多次项目里避免了后续很多麻烦。
6. 把爆破做成一件事:从工具参数到完整闭环
6.1 爆破顺序为什么这么排:小规模试探在前,全量执行在后
整套流程跑顺之后,顺序是固定的:先确认目标可用性,再小规模验证工具参数,再全量执行,最后二次验证。顺序不能反。先跑小规模的另一个好处是能拿到目标的响应基线:平均响应时间、失败提示格式、是否带验证码、是否限速,这些信息决定后面的并发和延迟怎么配,也决定你愿不愿意对目标做全量爆破。
我之前跳过小规模直接全量跑,后果是字典和编码都对,但判断条件配错,几万条请求全白跑。从那以后,我每次开工前都会强制走一遍「三条请求验证」:拿一个已知错误的账号密码提交,确认失败特征;手工注册一个测试账号或用已知账号登录,确认成功特征;再用 30 条左右的小字典跑一遍,确认工具输出的格式和阈值符合预期。这一遍只花几分钟,但能避免后面几小时的无效劳动。
6.2 报告模板:让每一项结果都可以当场复现
爆破结果进报告,不能只写「发现弱口令 admin/123456」。我留的报告字段包含五块:目标 URL、账号、密码、验证方式、修复建议。验证方式必须写清楚是「通过状态码+Cookie 验证」还是「通过登录后访问特定页面验证」,方便复核的人照着重新操作一遍。
| 目标 URL | 账号 | 密码 | 验证方式 | 风险等级 | 修复建议 |
|---|---|---|---|---|---|
| http://192.168.1.10/admin/login.php | admin | 公司名拼音2024 | 登录后访问 index.php 返回 200 | 高 | 改强密码并启用登录失败锁定 |
| http://192.168.1.11/manage/login | test | test@123 | 登录响应含有效 Set-Cookie | 中 | 停用默认账号,开启双因素认证 |
另外报告中要单独留一节说明字典规模和测试时间,以及是否有账号被触发锁定。如果某些账号因为多次失败被锁,要在报告里同步提醒运维去检查,这类账号本身说明密码策略已经起效,但还需要人工复核。
6.3 我现在的固定动作
做完一次完整的批量爆破测试,我现在还会多走一步:把验证通过的账号密码,在目标的后台里查一下该账号的权限角色和最近登录记录。这一步不是为了扩大战果,而是确认这个弱口令账号的实际影响面。有一次,某个平台扫出了管理员弱口令,我看权限确实是管理员,就列进了报告;后来复测时发现该账号还在另一个子系统里有上传配置权限,如果不把权限核实清楚,报告里的风险等级就会写低一档。从那以后,权限和登录记录核查成了批量爆破之后的必选动作。
工具本身解决的是「批量检测」的效率问题,真正让结果可信的是参数配置、二次验证和授权边界这三道关。希望这套流程能帮你在下一次测试里少踩几个坑。
本文还有配套的精品资源,点击获取