前几天帮某单位做例行安全巡检登录测试服务器以后我习惯性地收集了一波Linux账号口令哈希丢给John the Ripper跑了一会儿结果连五分钟都没用到一个运维账号的弱口令就被直接撞了出来。这种场景在真实环境里几乎每个月都能遇到系统补丁打得很勤防火墙规则也足够严密最后偏偏栽在“口令太简单”这个最基础的短板上。今天想聊的就是Linux系统安全里绕不开的一个实战课题——John弱口令检测。John the Ripper是一款在安全圈里流传了很多年的离线密码破解工具它能对Linux系统里的账号口令哈希做字典攻击、规则变形、增量穷举等操作从而快速暴露那些“设了等于没设”的弱口令。对做安全运维、等保测评、渗透测试的同行来说这属于工具箱里的常备品。下面我会从原理、安装、实操、进阶策略到加固建议完整走一遍检测闭环希望你看完能直接在自己的测试环境里跑起来。1. 认清弱口令检测的本质1.1 内网失守多数从“口令太简单”开始很多人对弱口令的危害没有直观感受觉得“服务器有密码别人不知道就行了”。但现实是企业内部网络一旦有某个主机沦陷攻击者第一件事就是翻它的本地账号和口令哈希然后拿这批哈希对内网其他机器做横向尝试。如果内部账号普遍使用弱口令比如运维习惯用“Admin123”“Pssw0rd”这种人人都能猜到的组合攻击者根本不需要什么高级漏洞只需要跑一轮字典就能批量控制多台服务器。我在一次真实项目里见过类似的场景某团队做内部红队演练入口只是一台暴露了弱口令的测试机结果短短一个小时内攻击方利用这台机器上的口令复用现象横向拿到了六个服务器权限最后直接从研发内网摸到了生产数据库。事后复盘时发现真正被利用的漏洞只有一个但蔓延的关键却是口令太弱、多台机器同口令。弱口令就像是内网里的隐形后门平时不会响警报一旦有人去碰整个防线就像纸糊的一样。1.2 John the Ripper 在检测链条中的位置所谓弱口令检测本质上就是一个“在授权范围内用攻击者视角去验证口令强度”的过程。而John the Ripper正是这一环节里的核心执行引擎。它支持的哈希类型非常全从经典的DES、MD5、SHA-256到Linux常见的sha512crypt、bcrypt、scrypt再到各种应用系统的哈希基本上能覆盖日常巡检遇到的场景。检测链条通常是先获取到口令哈希文件然后通过字典、规则、掩码等手段尝试还原明文口令最后把漏洞结果转成整改任务。John做的就是中间这层最脏最累的“尝试还原”工作。这里要区分一个概念弱口令检测和暴力破解并不是同义词。John的攻击方式是有策略的多数场景下靠的是“字典规则”来模拟人的习惯而不是毫无章法地从aaaa试到zzzz。举个例子如果有人把口令设成“Welcome123”一个精心准备的字典加上基础规则可能几秒就试出来了但如果靠纯暴力从8位小写字母加数字开始枚举可能得跑上几年。John之所以高效不是因为它算得快当然它并行能力也很强而是因为它懂得按人的习惯去猜。1.3 使用边界与授权前提每次讲到口令破解我都要把边界说清楚John the Ripper是安全检测工具不是攻击工具。它的正确使用场景包括对自己负责的主机做口令自检、在授权范围内做等保测评和渗透测试、拿到客户书面授权后做红队演练。没有授权就对自己不控制的系统跑破解这是法律性质的问题没有任何商量余地。实战中我会在测试前把授权委托书、测试范围说明都归档好再开始操作。另外即使是自检也尽量在测试环境或非核心生产环境的副本上进行。因为大规模跑增量模式会消耗不少CPU资源操作前还要做好评估避免影响线上业务。工具本身不会惹麻烦但用它的时机和范围一定要拿捏好。2. 环境准备与哈希采集2.1 安装 John发行版包与源码编译John the Ripper的安装方式主要看你的系统。在Debian系发行版上直接一行命令就能装上sudo apt update sudo apt install -y john在Red Hat系发行版可以用dnf或yumsudo dnf install -y john不过这里有个细节很多发行版仓库里默认的是John的老版本或精简版格式化支持相对有限。如果你打算长期用它做日常巡检我建议直接用官方发布的jumbo版本它的功能更全支持的哈希格式、规则集、掩码模式都更多。源码编译的方式也不复杂依赖主要是gcc、make和libssl-dev装好后执行git clone https://github.com/openwall/john.git cd john/src ./configure make编译完成后主程序在run目录下。有些发行版把二进制命名为john而jumbo版里能直接用john或john-ompOpenMP并行版本。实测下来jumbo版在处理现代哈希如bcrypt、sha512crypt时速度和格式识别都比老版本稳得多。如果你是Kali用户系统里已经预装了John直接跳到下一步即可。2.2 用 unshadow 拼出可破解的哈希文件Linux系统的口令哈希存在/etc/shadow文件里普通用户看不到只有root或有sudo权限的账号能读取。拿到权限后最标准的做法是把/etc/passwd和/etc/shadow合并成一个John能识别的文件官方工具unshadow就是干这个的sudo unshadow /etc/passwd /etc/shadow /tmp/passwd_hash.txt生成的passwd_hash.txt里每一行都包含用户名、用户ID、完整口令哈希串和注释信息。John拿到这个文件以后会自动识别每个账号的哈希类型不需要你手工区分哪个是sha512crypt哪个是bcrypt。不过要注意unshadow输出里可能包含系统账号比如daemon、bin、sys这类没有实际登录能力的账号它们的口令字段通常是*或!John会自动跳过对检测结果没有影响。如果没有root权限理论上也可以用其他手段收集哈希但在合规前提下我不建议绕过权限去做这些操作。正常情况下弱口令检测都是系统管理员或安全测试人员在明确授权的前提下第一时间拿到shadow文件再开始分析的。2.3 字典怎么选从哪来字典是弱口令检测里最关键的一环。John自带的字典通常在安装目录下的run/password.lst里面汇集了大量常见弱口令可以作为第一轮攻击的基础词库。如果你想要更大规模的高质量词库社区里最常用的是rockyou.txt几百万条真实泄露口令清洗出来的字典覆盖了绝大多数人类取口令的习惯。在很多发行版里它的路径是/usr/share/wordlists/rockyou.txt.gz先解压再用sudo gunzip /usr/share/wordlists/rockyou.txt.gz除了现成的词库我习惯针对目标环境做一份定制字典。比如把公司名称、业务简称、域名、年份、常见数字组合按照大小写变形、前后缀拼接预先整理成列表。这类定制字典在内部测评中往往比通用大字典命中率更高因为很多公司内部口令都跟业务信息强相关。不过要提醒一句字典来源必须合规别去碰非法的社工库或交易数据使用公开的泄露口令研究数据集和正经的弱口令清单就够了。3. 核心实操一次完整的弱口令检测3.1 组装目标文件确认哈希类型假设我已经在一台测试服务器上拿到了root权限第一步就是生成合并文件sudo unshadow /etc/passwd /etc/shadow /tmp/accounts.txt然后查看内容长什么样看看有没有异常字段head -20 /tmp/accounts.txt正常情况下你会看到类似这样的行root:$6$rounds656000$xyzabc...:0:0:root:/root:/bin/bash webadmin:$6$rounds656000$defghi...:1000:1000::/home/webadmin:/bin/bash开头$6$表示这是SHA-512加密的密码也就是Linux系统默认的密码哈希算法如果是$1$则是MD5$5$是SHA-256$2y$或$2b$则是bcrypt。John强大的地方在于它通常能自动识别这些格式。如果你希望确认John对该文件的识别情况可以执行john --listformats | grep -i sha512也可以直接用--formatsha512crypt强制指定格式这样能跳过自动检测避免某些特殊哈希识别失败。3.2 字典攻击执行与参数解读拿到合并文件之后第一轮我建议先用系统自带字典或rockyou跑一次john --wordlist/usr/share/wordlists/rockyou.txt /tmp/accounts.txt命令执行后John会开启默认数量的线程边跑边把进度打印在终端上。屏幕上会出现当前尝试速度、已破解的账账号数量等信息。如果运气好几秒钟内就能看到命中提示比如Loaded 8 password hashes with 8 different salts (sha512crypt [SHA512 128/128 SSSE3 2x]) Press q or Ctrl-C to abort, almost any other key for status webadmin (?)这行输出意味着webadmin这个账号的口令已经被字典命中了。这里要留意一下口令策略Linux的sha512crypt计算比较慢字典迭代速度取决于CPU性能和哈希轮数。我曾在老款服务器上跑256MB的大字典速度只有几百KB/s换到当代多核服务器后速度能提升不少但还是比MD5一类旧哈希慢得多所以要有耐心。3.3 结果输出与 pot 文件解析John每破解一个口令除了在屏幕上提示还会把结果记录到~/.john/john.pot文件里这个文件的格式很简单$6$rounds656000$xyzabc...:Welcome123后面再跑同一个哈希文件John会直接从pot文件里读取已知答案不会重复计算。这个机制对效率提升很有帮助但也会带来一个现象第一次跑完再跑第二次屏幕上可能显示“No password hashes left to crack”这并不代表结果丢了只是说明已知的已经破解完剩下的还没被当前字典覆盖。想要查看完整结果用--show就行john --show /tmp/accounts.txt输出会列出所有已破解账号和对应口令同时统计已破解和未破解的数量。我习惯把输出重定向到文件留档john --show /tmp/accounts.txt /tmp/john_results.txt这样后续写报告时直接取数据即可。需要注意的是--show展示的内容只包括pot文件里已经破解的哈希未破解的不会出现。如果你想针对未破解账号再跑下一轮不需要单独过滤直接换策略继续跑同一个文件就行。3.4 特殊哈希格式的处理技巧日常巡检时除了/etc/shadow里的口令还可能会遇到别的场景比如某个应用导出了口令哈希文件格式不是Linux标准crypt格式。这时候John的--format参数就派上用场了。先列出支持格式john --listformats然后根据哈希前缀判断类型比如应用里常见的是MD5还是bcrypt或者某个中间件自成一套的变体。找到对应格式名以后执行类似john --formatbcrypt --wordlistwords.txt ./app_hashes.txt或者是john --formatmd5crypt --wordlistwords.txt ./app_hashes.txt如果哈希文件里还带着用户名John也能处理只要每一行的结构是“用户名:哈希”就行和unshadow的输出结构一致。对于结构不规整的文件可以用awk简单整理。我遇到过一个遗留系统导出的哈希格式非常混乱最后写了个小脚本把字段统一成user:hash形式再交给John跑效率高很多。4. 让检出率翻倍的三种攻击策略4.1 增量模式按字符集生成口令字典模式只能覆盖已有词汇如果目标口令是由纯数字、生日、电话号码等组成字典一般覆盖不到。这时可以上增量模式也就是按指定的字符集从1位到N位依次穷举。比如检测纯数字口令john --incrementalDigits --min-len1 --max-len10 /tmp/accounts.txt这里的Digits是John内置字符集只包含0-9速度非常快。测试一下10位纯数字的全量空间是100亿个组合看起来很多但对John来说在多数现代CPU上并不算离谱。如果你设置--max-len8那只有一亿个组合几分钟内就能跑完。除了DigitsJohn还内置了All、LowerNum、UpperNum等字符集。增量模式下--min-len和--max-len是核心参数设置合理范围能大幅缩短时间比如检测6到8位就不要设成1到12否则会浪费很多算力。4.2 规则变形让字典具备“自进化”能力规则变形是我最推荐的一个功能它能把一部小字典变成几十倍甚至上百倍的攻击载荷。原理很简单对字典里的每个基础词按规则自动做大小写转换、添加数字后缀、前后缀拼接、替换字母比如e换成3a换成等操作。John内置了多条规则集直接用--rulesAll就能启用全部规则john --wordlistwords.txt --rulesAll /tmp/accounts.txt举例来说字典里有admin这个词通过规则运行后John会自动尝试Admin、ADMIN、admin1、admin123、adm1n、Admin123等变形。这一招对“用户自以为设了复杂口令但其实只是把常见词做了简单变形”的情况非常有效。我做过一次对比实验同样一部10万条的小字典不加规则只跑出3个弱口令加了规则后跑出了11个命中率直接翻了三倍多。不过代价是计算量显著上升规则模式下的尝试次数可能是原字典的50~100倍。所以在时间有限的情况下可以先跑一轮不带规则的快速扫描再针对重要账号跑规则变形。John默认带的规则集种类很多也可以自定义规则来模拟企业内部常见口令组成习惯这部分发挥空间很大。4.3 掩码攻击基于口令习惯的精准爆破掩码攻击是John较新的一个功能也是我实战中最常用的策略之一。它允许你按“位置模板”来生成口令比如一个大写字母开头、接着四个小写字母、最后两个数字的模板可以这样写john --mask?u?l?l?l?l?d?d /tmp/accounts.txt掩码符号都有明确含义?u表示大写字母?l表示小写字母?d表示数字?s表示特殊符号?a表示任意可打印字符。这套模板能精准覆盖“首字母大写末尾数字”这类非常常见的人类取口令习惯。对比纯增量模式掩码攻击的最大优势是大幅压缩搜索空间。比如8位全数字是1亿次但如果你知道企业要求口令至少8位且必须有大写字母和数字猜它是“一个大写若干小写若干数字”的结构空间直接缩小好几个数量级跑起来非常快。实践中我把掩码当作字典攻击的补充等字典和规则都跑完、还没出结果的时候再针对“拼音生日”“英文单词年份”等高频结构来一轮掩码。命中率相当可观。4.4 性能调优多进程、内存与全量载荷John默认就会利用本机所有CPU核心在jumbo版本里还会自动启用OpenMP并行。如果你有一台多路CPU的机器还想再压榨一点性能可以用--fork参数指定进程数john --fork8 --wordlistwords.txt /tmp/accounts.txt但要注意--fork只在部分模式下有效而且每个进程会独立加载字典内存占用会成倍上升。另一个相关参数是--mem它影响的是部分哈希计算时的缓存大小对某些算法的速度有一定影响john --mem1024 --fork4 --wordlistwords.txt /tmp/accounts.txt跑大字典时我习惯先用--status查看当前进度按任意键也能看到实时的速度和剩余情况。如果一台机器要跑很久可以把它丢到后台用nohup挂起来但一定要做好日志和断电恢复的准备。对GPU加速John也支持OpenCL等后端但这通常需要单独编译配置实战中不是必须项。我自己在普通服务器上跑现代哈希还是靠多进程和策略优化更实在。5. 常见问题与排查实录5.1 高频问题速查表很多第一次用John的人会遇到一些看起来莫名其妙的问题其实多试几次就能摸到规律。我整理了几个高频场景现象常见原因解决思路提示“No password hashes loaded”文件里没有John能识别的哈希或哈希被!*占位符覆盖确认文件格式使用--format指定类型检查账号哈希字段是否有效自动识别格式错误哈希类型特殊或版本过老用--listformats筛选匹配类型再用--format强制指定破解速度极其慢哈希轮数高如bcrypt、sha512crypt或CPU核心没跑满切换到低轮数哈希测试启用--fork或缩小字典范围跑了很久屏幕上没有任何命中口令确实较强或当前策略没覆盖目标模式换规则、换掩码、换字典先用增量模式试探低位数空间第二次跑同一个文件显示没有剩余哈希结果已经写进pot文件不会重复显示用--show查看已破解结果或删除pot文件重跑系统里没有unshadow命令老版本John或极简安装直接手工合并passwd和shadow按user:hash格式整理这种排查过程很有必要因为很多人第一次就把时间浪费在跑错格式上最后怨工具不给力其实问题完全不在John身上。5.2 两个容易忽略的细节快照恢复与结果二次确认第一个细节是断点恢复。John在执行中途如果被Ctrl-C中断它会把进度信息存在~/.john/john.rec这样一个会话文件里。下次执行同一条命令它会提示是否恢复也可以用--restore参数强制恢复john --restore /tmp/accounts.txt这个功能在长周期任务里特别重要。我有一回跑一个大型数据库哈希预计要十几个小时中途服务器重启了如果没有快照恢复机制前面所有进度都得清零重新来。有了这个机制重新开机后一条命令就恢复到断点省了非常多时间。第二个细节是破解结果的二次确认。John显示已经破解某个账号后别急着写报告建议先在目标机器上手工确认一遍比如用su切换账号或者用SSH登录测试。因为John跑出来的“密码”有可能是一个相同哈希的等价字符串极少数时候会因为哈希碰撞或编码问题出现偏差。虽然概率很小但安全意识必须到位凡是能登录验证的都顺手验证一下写进报告里的数据才经得起推敲。6. 从检测到加固报告与防线建设6.1 把破解结果变成一份可落地的报告弱口令检测的最终价值不是“跑出几个密码”而是推动整改。所以报告必须清晰、可跟踪。我常用的报告表结构是主机IP/主机名账号哈希类型原始口令风险等级整改建议192.0.2.10webadminsha512cryptAdmin123高立即改密加入密码策略管理192.0.2.21backup_svcbcryptbackup2024中改密禁用SSH口令登录改用密钥报告里还应该写清楚检测范围、检测时间、使用的字典和规则参数、测试账号授权情况。这样运维同事拿到报告才知道具体怎么修、修哪里而不是只看一句“你的系统有弱口令”。我通常会在报告末尾附上整改复核清单把“改密时间”“验证方式”“复测结果”做成表格方便跟踪闭环。6.2 密码策略加固与账号管理检测完弱口令最重要的事情就是让强口令变成一种制度而不是一次性的临时动作。在Linux系统上可以从几个层面下手一是启用密码复杂度策略安装并配置libpam-pwqualityDebian系或pam_pwhistory强制口令长度、字符类别和轮换周期二是禁止root直接SSH登录修改/etc/ssh/sshd_config里的PermitRootLogin no三是关闭不必要的系统账号把/etc/shadow里不用的账号口令字段改成!或*彻底禁用登录能力。对关键服务器建议进一步上多因素认证。用PAM模块配合动态令牌就算口令被泄露攻击者也很难直接登录。口令管理的核心思路是让系统不再依赖于“用户自觉”而是靠策略和技术手段兜底。我见过很多团队改完密码后三个月又出现同样的弱口令就是因为只是单纯改密码没有在PAM层做硬性约束。6.3 常态化弱口令检测机制John这种工具不应该一个月才想起来跑一次我建议把弱口令检测放进常规安全巡检清单里形成固定节奏。比如每个季度对核心资产做一轮字典和规则检测检测前先用unshadow生成哈希快照检测后把新增命中项自动录入工单分配给对应的责任人整改。整改完成后再重新拉取哈希做一次回归确认弱口令已消失。在规模较大的环境里可以写个小脚本定期批量执行一组机器自动收集shadow文件、加密传输到跳板机、跑John、把结果格式化推送。整个流程跑起来以后人只需要盯异常和复核报告。这套机制的收益是持续性的它不依赖某个人记性好而是靠流程推动安全水位持续上升。等到下一次等保测评或者内部审计的时候你手里已经有一堆漂亮的复测记录说明弱口令治理是真在做不是临时攒出来的材料。最后聊几句实战体会我刚开始用John的时候也走过一些弯路总以为字典越大越全命中率就越高后来才发现在时间有限的情况下规则加掩码的性价比远高于一部超大字典。另一个经验是弱口令检测永远要和对端系统的风险承受能力挂钩普通测试服务器可以放开跑生产核心一定要先在副本上试确保不会因为高负载影响业务。还有一点检测工具永远只是发现问题的手段真正拉开安全水平差距的是发现问题之后能不能快速推动整改并形成长效机制。建议各位拿到第一份检测报告后别急着把数据库删了先顺手验证一两个结果再推动改密和PAM策略把这次检测变成一次小小的安全基建升级一年之后回头看整个系统的口令安全性绝对会明显不一样。