简介WebCrack 是一款基于 Python 的 Web 后台弱口令与万能密码批量检测工具面向安全测试人员、渗透学习者及 Python 脚本爱好者。它支持批量导入后台地址并自动检测内置多重判断机制以减少误报同时提供随机 UA、随机 X-Forwarded-For、随机 Client-IP 等绕过策略还可依据域名生成动态字典、自定义爆破规则适合在授权环境下评估后台登录弱口令风险。压缩包内共 13 个文件以 8 个 Python 脚本为核心辅以 2 个文本配置/说明文件及使用文档、示意图片整体仅 113KB轻量易用。代码按功能拆分便于定位字典生成、表单解析、核心检测逻辑与全局配置可快速二次开发或调整检测策略。目前已有 1601 人学习/下载。通过源码读者能理解弱口令爆破的整体流程、反爬/绕过思路及 Python 安全工具的模块化写法是一份轻量而完整的安全测试参考。1. WebCrack 不是「扫一下」那么简单web 后台弱口令批量检测的落地姿势作为授权渗透测试和甲方自查的常客我手里最常见的资产形态不是一串 IP而是一张写满 URL 的表格其中不少是 web 后台地址。手点浏览器一个个试弱口令别说几十个后台五六个就能耗掉一下午。WebCrack 解决的就是这个场景它是一款 web 后台弱口令万能密码批量检测工具把后台地址复制进工具就会自动跑一轮「弱口令 万能密码」的登录检测最后只把有问题的目标标出来。适合有授权前提的安全工程师、打 CTF 需要快速过后台入口的选手也适合运维自查内部系统的口令强度。别把它当成扫描器拿去乱扫授权边界清楚工具才用得好。2. 一条检测链路的拆解后台地址、登录接口和弱口令判定逻辑2.1 弱口令检测到底在测什么弱口令检测听起来简单本质上是三件事目标对不对、凭据全不全、判定准不准。目标指的是登录接口不是后台首页。凭据是账号加密码的组合再加一组万能密码 payload。判定则是根据服务器响应判断这次登录是成功还是失败。很多人直接导入后台地址就想开跑工具确实会做页面解析尝试找表单里的 action 和 input 字段但这类自动提取经常翻车——登录框是 JS 动态渲染出来的、表单按钮不是 submit 而是 onclick 事件解析结果跟实际请求对不上。我一般会先用浏览器或 Burp 抓包看一眼登录请求长什么样确认接口路径和参数名再把接口地址喂给工具。这一步花五分钟后面省一小时。WebCrack 在设计上把「输入后台地址」作为入口简化了使用方式但你要知道它内部做的事情依然是定位登录 URL、构造请求、尝试凭据、判定响应。理解这条链路之后遇到批量结果为空的情况排查范围就小很多。2.2 WebCrack 的批量调度骨架从 txt 地址列表到并发任务工具输入是一份地址列表每行一个 URL。这是最常见也最容易对接的格式。文件格式如下表文件内容示例targets.txt后台地址每行一个 URLhttp://192.168.1.10/admin/login.phpusers.txt账号字典每行一个账号adminpasswords.txt密码字典每行一个密码admin123payloads.txt万能密码列表 or 11调度主流程固定四步读文件、建任务队列、线程池并发、收集结果。下面这段是我常用的调度骨架import concurrent.futures def load_lines(path): with open(path, r, encodingutf-8, errorsignore) as f: return [line.strip() for line in f if line.strip()] def build_tasks(targets, users, passwords, payloads): tasks [] for target in targets: for user in users: for pwd in passwords payloads: tasks.append((target, user, pwd)) return tasks targets load_lines(targets.txt) users load_lines(users.txt) passwords load_lines(passwords.txt) payloads load_lines(payloads.txt) tasks build_tasks(targets, users, passwords, payloads) with concurrent.futures.ThreadPoolExecutor(max_workers5) as executor: future_map {executor.submit(check_one, t): t for t in tasks} for future in concurrent.futures.as_completed(future_map): task future_map[future] try: result future.result() if result and result.startswith(LOGIN_OK): print([], task, result) except Exception as e: print([-], task, e)build_tasks 是任务生成的核心账号和密码做笛卡尔积万能密码 payload 混在密码列表里一起测。ThreadPoolExecutor 的 max_workers 控制并发数5 是一个偏保守的值不容易触发目标站点的防护。as_completed 的好处是哪个任务先返回先处理不会因为某个地址超时卡住整个队列。这里把 payloads 追加在 passwords 后面是故意的因为弱口令字典通常几十到几百条万能密码只有十几种先跑弱口令、再跑万能密码结果的排序更符合人工复核的习惯如果你希望优先测万能密码把两段顺序调换即可。check_one 是单次检测函数完整实现在第 3 章给出。2.3 为什么用 Python 来做这件事选 Python 不是因为 WebCrack 恰好是 Python 写的而是这个场景用 Python 确实顺手。requests 构造登录请求只要十几行pyyaml 读配置不用手写解析器concurrent.futures 是标准库自带的线程池零额外成本就能拿到并发能力。还有一层是调试效率。批量检测工具在第一次跑的时候几乎必然遇到「判定不准」的问题要么把失败当成功要么把成功当失败。Python 的交互式环境可以快速验证一段响应解析逻辑改完直接重跑比编译型语言少一道构建步骤。配合 Burp 抓包导出的原始请求Python 也能很方便地转成 requests 代码常见的做法是复制为 cURL 再转换。另外Python 生态里字典文件本身就是纯文本一行一个和工具的输入格式天然一致不需要转换。即便是新手也能在半小时内把核心检测逻辑改成适配自己目标的版本。这也是 WebCrack 这个工具值得下下来拆开看的原因——它的边界和代码量都适合按需改。3. 环境装好、把工具跑起来最小可用检测脚本3.1 安装依赖与准备输入文件拿到资源包之后第一步不是急着跑而是把环境固定下来。弱口令检测工具对 Python 版本不挑3.8 以上就行但依赖版本要统一否则 requests 的 TLS 行为会不一样。我的习惯是先建虚拟环境再装依赖python3 -m venv webcrack_env source webcrack_env/bin/activate pip install requests pyyaml pip freeze requirements.txtvenv 隔离开系统 Python 环境避免和系统包冲突。requirements.txt 记录当前版本后面踩坑回滚有后悔药。如果目标后台是古老设备TLS 握手可能失败常见做法是把 urllib3 锁到 1.26.x因为 urllib3 2.x 对证书链的校验更严格而老旧后台的设备证书往往不完整。输入文件按工具包里的模板准备即可。targets.txt 每行一个 URL建议带协议头因为工具要根据 http/https 决定默认端口和后续请求构造不带协议头的地址会被视为 http。users.txt 里放你打算测的账号名至少放 admin、administrator、root、test 这几个具体看目标系统的命名习惯。passwords.txt 就是弱口令字典资源包里有现成的常见弱口令列表后面我会讲怎么在它的基础上扩。3.2 核心检测脚本请求、超时、状态判定2.2 的调度骨架里引用了 check_one下面是它的完整实现。这段是检测单次登录尝试的最小核心逻辑完整可以直接跑import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def check_one(task): url, user, pwd task headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), Content-Type: application/x-www-form-urlencoded, } data { username: user, password: pwd, } try: r requests.post(url, datadata, headersheaders, timeout10, verifyFalse, allow_redirectsFalse) except requests.exceptions.Timeout: return TIMEOUT except requests.exceptions.RequestException as e: return fERROR: {e} if r.status_code 302 and Location in r.headers: return LOGIN_OK(302) for kw in [logout, dashboard, welcome]: if kw in r.text.lower(): return LOGIN_OK(keyword) if r.status_code 200 and len(r.text) 500: return LOGIN_OK(length) return FAILcheck_one 接收一个三元组返回检测结论。verifyFalse 关掉证书校验是因为大量后台用的是自签名证书不关会直接报 SSL 错误这是这个场景的惯例同时用 urllib3.disable_warnings 压掉告警不然日志会刷屏。allow_redirectsFalse 很重要登录成功往往伴随 302 跳转如果放行重定向最终响应是落地页反而丢失了跳转特征。注意verifyFalse 会关掉证书校验只应在授权测试环境中使用别在生产环境照搬。判定顺序是从强到弱先看 302再看响应体关键字最后才看长度。这个顺序在下一章展开说但你可以先记住一个原则有强特征就不依赖弱特征。10 秒超时对大部分 web 后台够用内网慢速目标可以调到 15 或 20。3.3 用命令行完整跑一遍批量检测资源包里的入口脚本一般长这样python webcrack.py --targets targets.txt --users users.txt --dict passwords.txt --payloads payloads.txt --threads 5 --delay 0.5 --output result.txt参数作用建议值--targets后台地址列表必填每行一个 URL--users账号字典admin 居首--dict密码字典拷贝自资源包再追加--payloads万能密码列表单独文件方便增减--threads并发线程数5~10外网别超过 5--delay每次请求间隔秒数0.3~1.0--output结果输出文件建议 UTF-8 编码跑之前先拿单条地址手动验证一遍工具判定逻辑确认目标返回 302 还是关键字。命令行跑起来之后我会盯着前几十条输出看判定结论有没有异常比如全部 FAIL 或者全部 TIMEOUT说明请求构造有问题而不是目标没问题。资源包里通常会附默认的 passwords.txt 和 payloads.txt第一次就用自己的字典替换我认为没必要——先跑默认字典摸一轮再根据结果做定向扩展效率更高。4. 把成功率提上去响应指纹判定与万能密码 payload4.1 登录成功的判定不能只看状态码新手最容易翻车的点就在这里。很多后台在登录失败时返回 200登录成功时也返回 200区别只在响应体里的一段 JSON 字段或者一个跳转。如果你只看状态码等于把判断交给运气。我用的判定优先级是状态码 跳转 Cookie 关键字 响应长度按序组合。判定维度特征示例权重HTTP 状态码登录成功 302失败 200强Location 头/admin/index.php 而非 /admin/login.php强Set-Cookie出现新的 session 标识强响应体关键字欢迎、logout、退出中JSON 字段{code:0,msg:success}中响应长度成功页远大于登录页弱实际判断时我倾向于写一个函数按顺序检查先看状态码是否在预期成功集合里再检查 Location 是否跳出了登录页路径再看有没有新增 Cookie最后看关键字和长度。单项命中不一定可靠两项同时命中就可以记录结果了。Set-Cookie 是最容易被忽略的强特征后端登录成功一定会下发新的会话标识而失败响应通常只会刷新原有 Cookie。这也正是 WebCrack 这类工具最值得改的地方把判定规则从代码里抽出来放到配置文件里不同目标系统换一套规则就行不用碰代码。4.2 万能密码为什么能「万能」万能密码在技术上不是「密码」而是 SQL 注入的登录绕过。老一代后台直接把前端传来的用户名密码拼进 SQLSELECT * FROM admin WHERE usernameadmin AND password123456如果密码框输入 or 11拼接后变成SELECT * FROM admin WHERE usernameadmin AND password or 11or 两边的条件任何一个成立都算成立11恒真于是这条查询直接把 admin 用户返回了。工具里的 payloads.txt 装的就是这类输入。常见的几条Payload说明 or 11经典恒真绕过分admin--注释掉后面的密码校验 or 11#井号注释MySQL 风格 or aa双引号变体1 or 11 or 11多重或确保恒真要注意边界凡是用了参数化查询或 ORM 的系统这类 payload 全部无效这是安全的进步而不是工具的失败。有的系统会对密码做 md5 再比对这种 payload 也不生效因为拼接发生在加密之后。所以万能密码是「历史向后兼容」的检测项不是银弹。在构造检测任务时payloads 要当作密码来提交但结果展示要单独标注区分弱口令风险和注入风险方便后续修复时对症下药。4.3 规则可配置用 YAML 管理判定特征资源包如果带了 config.yaml大概率长这样request: method: POST timeout: 10 verify_ssl: false allow_redirects: false success_rule: status_codes: [200, 302] location_contains: [] cookie_new: true keywords: [logout, 欢迎, dashboard] json_code_field: code json_code_values: [0] min_length: 500 exclude_rule: keywords: [验证码错误, token 失效, 密码错误]success_rule 是白名单命中exclude_rule 是黑名单排除两者都配置时先跑黑名单再跑白名单避免「密码错误」四个字命中 keyword 列表造成误报。json_code_field 用于处理登录结果通过 JSON 返回的接口比如 code0 表示成功。这个配置的价值在于遇到一个新系统只要改 YAML不需要碰 Python。我一般会先把单个目标用 curl 复现一次登录把响应体存下来然后照着响应体的特征填 config.yaml再用工具验证。这套流程下来误报率能压到很低。5. 批量检测避坑现象、原因和解决办法5.1 后台地址全部检测失败一条结果都没有现象targets.txt 导入了几十个后台地址跑完输出全空没有任何成功记录。原因地址给的是后台首页不是登录接口。大多数后台的登录表单单独挂在 /login、/admin/login.php、/user/login 这类路径首页只是展示页根本不含登录提交逻辑。工具就算做了页面解析也经常因为登录框由 JavaScript 动态渲染而拿不到真实表单参数。解决先用浏览器打开后台地址F12 切到 Network 面板手动提交一次错误密码找到那条 POST 登录请求的 URL 和参数名。然后把 targets.txt 里的地址换成这个接口 URL。如果不想改地址确认工具是否支持配置登录路径前缀多数情况下直接改文件更省事。这一步做扎实后面的检测才有意义。5.2 全部提示「验证码错误」或「Token 失效」现象所有账号密码组合跑完结果全部是同一句话——验证码错误或者 Token 校验失败。原因目标登录接口带验证码或 CSRF Token每次请求的验证码图片或 hidden 字段都不一样。而批量工具每秒发出大量请求验证码字段要么为空要么是死值服务器当然全部拒绝。解决先去登录页源码里找 Token 的生成逻辑很多系统的 Token 只是固定的 hidden 值可以从登录页 HTML 里用正则抽出来再塞进请求验证码则需要先解决识别问题简单数字验证码可以用 OCR 识别复杂的不建议硬扛直接把该目标从批量名单里剔掉留给人工处理。还有一类情况是 Cookie 与 Token 绑定需要先用 GET 请求登录页拿到 Session Cookie再带着 Cookie 提交 POST。工具里如果支持 pre_login 脚本就配置上不支持就把这类目标单拎出来。5.3 状态码 200 到底算成功还是失败现象检测结果里大量标记成功但手工点开登录这些账号根本进不去。原因判定逻辑只依赖状态码。前面说过很多系统无论成败都返回 200真正区分成败的是响应 JSON 里的 code 字段或者一个跳转。只看状态码等于把所有失败请求都误判成了成功。解决抓一次失败响应、一次成功响应对比两者的差异。常见差异有响应体长度、是否包含「密码错误」、是否下发新的 Set-Cookie、JSON 里 code 值。把这几个差异写进 config.yaml 的 success_rule再用单条地址重测验证。不要忽略 Set-Cookie 的细节后端登录成功一定会下发新的会话标识这是强特征。5.4 并发一高就被封 IP 或触发 WAF现象线程数开到 20跑了不到两分钟所有请求开始超时或返回 403日志里出现拦截页面关键字。原因外网目标几乎都有频率限制或 WAF20 线程加零延时等于每分钟几千次请求正常用户不可能那个频率触发封禁是必然的。解决线程控制在 5 以内请求间隔至少 0.5 秒。轮换 User-Agent 可以降低被识别的概率但不能只靠这个。如果目标有验证码或人机校验任何频率的批量请求都会被拦这种目标不适合纯脚本硬跑。检测时间放到业务低峰内网目标也要控制速率避免影响正常业务。5.5 Python 环境依赖带来 TLS 握手失败现象同一份脚本在一台机器上跑正常换一台机器报SSL: CERTIFICATE_VERIFY_FAILED或者SSLEOFError。原因requests 依赖的 urllib3 版本不同TLS 默认行为不一样目标后台用的又是老版本 OpenSSL 或自签名证书。urllib3 2.x 对证书校验更严格部分老后台的 TLS 配置不兼容。解决统一依赖版本把 urllib3 锁定在 1.26.xrequests 锁定在 2.31 附近同时代码里保持 verifyFalse。换环境后重新 pip install -r requirements.txt而不是直接拷贝虚拟环境目录。这样能避免大多数 TLS 玄学问题。6. 收尾技巧结果二次验证与自建弱口令字典的习惯6.1 把结果导出成 CSV手工复验一遍工具跑完的结果不要直接拿去报告至少手工复验一轮。我会把命中记录统一导成 CSV字段包括目标地址、账号、密码类型弱口令/万能密码、命中判定依据、检测时间。CSV 的好处是 Excel 能直接打开方便筛选。复验的方法很简单拿命中的账号密码用浏览器无痕窗口手工登录一次。300 个结果里随机抽 5 个如果 5 个都能进这轮检测的可信度就足够了。如果抽到误报再回头调 success_rule重新跑受影响的那几条。6.2 自建字典的两种组合思路资源包自带的字典是通用集覆盖面广但精准度一般。我习惯在它基础上按目标特征扩展。第一种组合是「品牌词 年份 特殊字符」公司拼音或系统名加 2024、2025再加 、!、#。比如某个系统叫 zentao那 zentao2024、Zentao2024! 之类就可以加进去。第二种是「常见弱口令 键盘规律」admin123、123456、Aa123456、qwerty123 属于常见弱口令1qazWSX、!#$%^* 属于键盘规律型很多运维图省事会设置成这排。账号方面也别只盯 admin管理后台的账号常见的有 administrator、root、test、operator 这些有些系统支持邮箱登录还要把常见命名前缀加上。字典膨胀会拖慢检测速度最终字典控制在 200 行以内比较合适重点在于精准而不是量大。从这里我能明显感觉到一个习惯的差异以前我拿到工具直接全量跑结果报表又臭又长后来改成「先单测登录接口、再调判定规则、再小并发起步」每次检测的误报率低了很多复验工作也轻了。从那以后我每次跑批量检测前都强制走这三步希望帮到你。本文还有配套的精品资源点击获取