Linux密码安全实战:用Hydra和John the Ripper破解与防护
做安全测试或者接手Linux运维时有一类问题绕不开密码到底扛不扛得住暴力破解。我记得有一次做内网授权渗透演练目标是一台开了SSH的老服务器管理员图省事把密码设成了一个很短的纯数字组合hydra挂着字典跑过去没几分钟就出了结果。后来检查日志这台机器的auth.log里全是凌晨时段的扫描记录要不是提前做了防护估计早就被人悄悄登进去了。这年头聊“密码破解”很多人第一反应是玄乎的漏洞利用其实最常用也最有效的恰恰是暴力破解这条路。能把暴力破解玩明白Linux密码安全这块的地基就算打牢了。这篇文章不聊花哨理论就聚焦两个真正用得上的武器Hydra和John the Ripper。Hydra管“在线爆破”也就是对SSH、FTP、HTTP这类实时服务试密码John管“离线破解”也就是拿到 /etc/shadow 里的哈希之后在本地慢慢算。把这两个工具吃透Linux环境下的密码安全测试基本就能覆盖个七七八八。先声明一句老规矩所有操作只建议在你自己拥有的服务器、实验虚拟机或授权测试环境中进行。别拿这套东西去试别人的系统搞安全测试要有底线没授权就叫攻击这个性质完全不一样。1. Linux密码体系破解前必须搞清的底层逻辑很多人上来就敲命令结果连 hash 都加载不进去更别提破解了。要想用好 hydra 和 john先得知道 Linux 到底是怎么存密码的。1.1 从 /etc/passwd 到 /etc/shadow 的演变早期 Linux 把用户密码的哈希直接写在/etc/passwd文件里这个文件所有用户都有读权限等于把密码哈希裸奔在系统里任何拿到文件的普通用户都可以拿去离线猜。后来为了安全密码哈希被挪到了/etc/shadow这个文件只有 root 和特定组能读。拿cat /etc/passwd随便看一行大概是这样的test:x:1000:1000:Test User:/home/test:/bin/bash从左到右依次是登录名、x表示密码哈希在 shadow 里、UID、GID、描述信息GECOS 字段、家目录、登录 shell。注意那个描述信息字段john 的 single 模式会拿它当密码猜测的线索后面会细说。真正关键的是/etc/shadow里的内容test:$6$DMB68pA1$Yq8Fw7mJn2KhPzRw3sT/.....:18000:0:99999:7:::字段从左到右分别是用户名、密码哈希、最近修改时间、最小修改间隔、最大有效期、警告期、宽限期、失效时间、保留字段。密码哈希部分有三个$分隔的片段第一个是算法标识第二个是盐salt第三个才是真正的哈希值。1.2 哈希算法标识一看就知道密码怎么存shadow 文件第二字段的开头几个字符直接决定了 John 该用哪个格式去跑也决定了破解速度的天花板。常见的有这么几种标识算法典型长度破解难度$1$MD522字符快GPU下海量尝试$5$SHA-25643字符中等$6$SHA-51286字符较慢$2y$/$2a$/$2b$bcrypt53字符非常慢设计上就抗暴力$y$yescrypt长新一代Kali 等新系统默认$gy$gost-yescrypt长少见但也在有些发行版里出现新装的主流发行版比如 Debian 12、Ubuntu 22.04已经逐步切到 yescrypt也就是$y$开头的哈希。这种哈希对 CPU 和内存的要求比 SHA-512 高一个量级john 跑起来会很吃力但这恰恰是系统安全性的体现——暴力破解成本被大幅抬高了。盐的作用也得理解透。所谓加盐就是在哈希计算前把一个随机字符串拼到密码后面这样同一个密码在不同用户、不同时间生成出的哈希完全不同。没有盐的话攻击者可以预先把常见密码算成一张彩虹表拿到哈希直接查表几秒出结果加了盐就得针对每一组盐重新算彩虹表基本废了。所以破解的本质说白了就是拿候选密码加上盐去算哈希比对结果是否一致一致就算命中。2. Hydra在线服务的密码刺客Hydra 是 THC 出品的经典在线暴力破解工具支持协议多得吓人SSH、FTP、HTTP、HTTPS、SMB、RDP、MySQL、PostgreSQL、SMTP、POP3、SNMP……基本上你能想到的认证服务它都有模块。它的思路就是拿用户名和密码字典去登录目标服务靠服务器返回的结果判断有没有试对。2.1 在线与离线的区别我习惯用一个类比在线破解就像一个人挨家挨户试门锁手里拿一串钥匙一把一把插进去试离线破解则是把别人家的锁拆下来带回工作室坐在台灯底下慢慢研究。在线破解受网络延迟、服务端认证频率限制、防火墙拦截等因素影响速度有限离线破解只看本地算力GPU 一上每秒几百万次尝试不在话下。所以 hydra 和 john 不是替代关系而是互补关系。你有一台目标的 SSH 服务但拿不到内部文件用 hydra你已经拿到了一台机器的 /etc/shadow想顺藤摸瓜分析密码规律用 john。实战里经常是两个工具接力先 hydra 打下一个弱口令进去拿到 shadow再 john 批量整理这批用户的密码习惯。2.2 Hydra 安装与基础用法Kali 自带 hydra其他 Debian/Ubuntu 系系统直接装sudo apt update sudo apt install hydra装完先看版本hydra -h常用的参数就那几个背下来基本够用参数作用示例-l指定单个用户名-l root-L指定用户名字典文件-L users.txt-p指定单个密码-p admin-P指定密码字典文件-P rockyou.txt-s指定端口默认按协议走-s 2222-t并发任务数默认16-t 4-f找到第一个口令后停止-f-vV显示详细尝试过程-vV-o结果输出到文件-o result.txt-e尝试空密码或用户名即密码-e nsr看一个最基本的 SSH 爆破命令长什么样hydra -l root -P /usr/share/wordlists/rockyou.txt ssh://192.168.1.10这条命令的意思是用 root 这个用户名配上 rockyou.txt 字典去尝试登录 192.168.1.10 的 SSH 服务。hydra 会逐个拿字典里的密码去试最终把正确密码打印出来。实际用的时候我一般会加几个参数更稳也更可控hydra -l root -P passwords.txt ssh://192.168.1.10 -t 4 -f -vV -o hydra-ssh-result.txt-t 4把并发线程压到 4原因是 SSH 服务对高频认证请求比较敏感线程开太大容易被服务端直接断开连接-f争到第一个密码就停省时间-vV可以实时看到每一条尝试记录方便判断目标有没有异常-o把结果写到文件里方便复盘。如果是批量探测账号就把-l root换成-L users.txthydra 会拿用户名列表和密码列表做笛卡尔积hydra -L users.txt -P passwords.txt ssh://192.168.1.10字典文件里的格式是一行一个记得最后一行也要有换行符否则最后一条内容可能读不进去这个坑我踩过。2.3 常见协议模块与踩坑点HTTP 表单登录是 hydra 里最容易出问题的模块没有之一。因为每个网站的登录接口、请求参数、错误提示都不一样hydra 没法自适应必须手动指定。命令格式比较特殊hydra -l admin -P pass.txt 192.168.1.20 http-post-form /login.php:user^USER^pass^PASS^:FLogin failed拆开解释/login.php是登录接口路径中间部分是 POST 请求体用^USER^和^PASS^作为占位符让 hydra 替换实际值最后一段FLogin failed是“失败标记”也就是当响应页面里出现这段文字就说明密码不对。如果登录成功页面里有特定标识也可以用SWelcome, admin这样的“成功标记”hydra 找不到失败标记时会去找成功标记两个策略二选一即可。这里的失败标记是最大的坑。你要先自己用浏览器或 curl 登录一次抓取真实返回内容找一个“只有登录失败才会出现而登录成功绝不出现”的唯一字符串。用太泛的字符串比如页面公共的 footer 文案会导致判断失误明明试对了也报失败。我见过不少人栽在这排查了半天发现失败标记写错了。SSH 模块相对简单但要注意新版 OpenSSH 默认禁止 root 密码登录的配置。如果你测的机器改了PermitRootLogin yes-l root当然能试如果没改就得换个普通用户名的字典否则怎么跑都是失败。另外现在很多服务器上了 fail2ban 之类的防护登录失败几次就封 IP这种环境下 hydra 要非常收敛-t 1慢慢磨甚至加上随机延时。FTP 模块是最好跑也最宽容的很多老旧的 FTP 服务没有任何频率限制一次放 16 个线程也没事hydra -L users.txt -P pass.txt ftp://192.168.1.30RDP 模块Windows 远程桌面hydra -l administrator -P pass.txt rdp://192.168.1.40RDP 撞库容易被 Windows 的账户锁定策略打断所以如果目标开了账户锁定基本只能靠弱口令碰运气想大规模爆破不现实。3. John the Ripper离线哈希的攻坚利器John the Ripper简称 john是离线密码破解里的老牌工具专门对付各种密码哈希文件。拿到 Linux 的 shadow 文件后john 就是最顺手的解析工具。3.1 用 unshadow 合成待破解文件直接拿 /etc/shadow 喂给 john 不是不行但效果不好。因为 john 的很多破解模式尤其是 single 模式需要结合用户名、GECOS 描述信息来生成密码猜测而这些信息在 /etc/passwd 里。所以标准姿势是用 unshadow 命令先把两个文件合成一个unshadow /etc/passwd /etc/shadow combined.txt如果你是从目标机器上把这两个文件捞出来的注意保持原始权限和格式然后在本地执行 unshadow。执行后生成的 combined.txt 每一行就是用户名加上完整哈希john 可以直接解析。有些系统没有 unshadow比如 macOS 或者某些精简发行版你想手动拼也行就是把 passwd 里的用户信息字段和 shadow 里的哈希段拼成一行但不如 unshadow 省事。3.2 John 的三种经典破解模式Wordlist 模式字典模式是最常用的。指定一个字典文件john 把字典里的每个词当密码去算哈希比对john --wordlist/usr/share/wordlists/rockyou.txt combined.txt这个模式适合目标密码由常见单词、常见组合构成的情况。rockyou.txt 是 Kali 自带的大字典解压一下就能用sudo gunzip /usr/share/wordlists/rockyou.txt.gz里面有 1400 多万条常用密码从 123456 到各种变体都有。如果你要自己构造小字典一行一个密码注意 UTF-8 编码Windows 下编辑的文本最好转一下行尾符。Single 模式是 john 的特色模式不需要外部字典。它会根据用户名、GECOS 描述信息等自动生成密码猜测比如用户名叫 alice就试 alice、alice123、Alice、alice2024 这类变体。很多人密码喜欢用自己名字或者公司名打底single 模式就是精准打击这个习惯john --single combined.txt这个模式的思路非常实用。如果你拿到了一台机器上十几个用户名和他们的描述信息一个人叫 zhangwei岗位信息里写了 ops那他的密码大概率跟 zhangwei、ops 沾边。single 模式把这些信息揉合成猜测集合在字典跑之前先用它试一轮经常有惊喜。Incremental 模式增量模式是纯粹的穷举。它按照字符集排列组合去试所有可能性john --incremental combined.txt这个模式在小范围字符集下很立竿见影。比如说你知道目标密码是 8 位纯数字那增量模式本质上就是从 00000000 到 99999999 挨个试一亿种组合GPU 加持下并不算太多。但如果字符集是大小写字母加数字加符号长度还超过 10 位那就是天文数字跑多久都不现实。John 也支持指定格式。比如你知道这是 SHA-512 的哈希可以用john --formatsha512crypt --wordlistrockyou.txt combined.txt用--format强制指定格式有两个好处一是避免 john 自动识别失败二是减少去试其他格式的时间浪费。查看 john 支持哪些哈希格式john --listformats跑完以后查已经破解出来的密码john --show combined.txtJohn 会把每次破解结果记录到 pot 文件默认在~/.john/john.pot里。这个文件是累计的哪怕你换了新字典重新跑已经破解过的密码也会被跳过直接显示出来。想重新跑某个哈希可以加上john --show combined.txt如果发现明明改过字典但结果没更新多半是 pot 文件缓存的原因。可以用--pot指定一个全新的 pot 路径来绕过john --pot/tmp/custom.pot --wordlistmydict.txt combined.txt3.3 从 shadow 里定向爆破单个用户很多时候你不想对全部用户跑只关心 root 或者某个特定账号。可以先 grep 出来单跑grep ^root: /etc/shadow root.hash john --wordlistrockyou.txt root.hash这里要注意一个细节shadow 文件里的 root 行带着冒号和后面的时间字段john 能自动解析但如果文件格式不对会出现No password hashes loaded的报错。解决办法是只保留哈希串或者干脆用 unshadow 处理。另外提一嘴 hashcat。John 是 CPU 为主虽然也支持 OpenCL但配置比较麻烦hashcat 则天然为 GPU 设计同样的哈希格式在显卡上跑速度能比 CPU 快上几十倍甚至上百倍。如果你有一块像样的 NVIDIA 或者 AMD 显卡场景又是大量哈希要批量破解hashcat 是更好的选择。John 的优势在于生态成熟、模式丰富、对 shadow 格式兼容性好Kali 自带随手可用。两个工具配合使用才是完整的离线破解方案。4. 字典与规则破解效率的决定性因素工具只是载体真正决定破解效率的是字典。常有人问我为什么同样的工具别人跑几分钟出结果我跑一晚上毛都没有答案大半在字典上。4.1 用 crunch 生成定制字典Crunch 是 Kali 自带的一个字典生成器可以按照你指定的字符集和长度生成排列组合。基本用法crunch 6 8 abc123 -o dict.txt这条命令的意思是生成 6 到 8 位长度的密码字符集只用 abc123 里这几个字符输出到 dict.txt。算一下规模6 位的话 6^646656 种8 位封顶 6^81679616 种这么大一个小文件秒秒钟跑完。更高级的玩法是用-t指定模板。比如你知道某公司密码格式是“小写字母生日”可以这么生成crunch 8 8 -t %%%%%% -o company.txt代表小写字母%代表数字。这个命令生成的是两个小写字母加六位数字的 8 位密码符合“ab123456”这种形态。Crunch 的功能远不止这些还支持-d限制重复字符数量、-q从现有文件读取字符串、-z输出压缩格式等等。但实战中我很少真去生成超大字典因为排列组合的规模增长太恐怖了。10 位大小写字母加数字的规模是 (262610)^10数量级在 10 的 17 次方这个量级硬盘都装不下更别提跑。所以 crunch 适合的场景是你已经掌握了目标的密码策略只差在限定范围内穷举。比如密码策略强制 8 位以上、必须含大小写字母和数字你就用 crunch 生成“小写字母大写字母数字”组合的字典比拿通用大字典硬碰硬高效得多。4.2 John 的规则变形John 有一条--rules参数能在字典基础上做“变形”。比如字典里有 password 这个词规则可以自动生成 Password、password123、password!、pssword、PASSWORD 等变体。规则的本质是一组字符串变换操作John 内部已经预置了多套规则直接调用即可。john --wordlistrockyou.txt --rulesAll combined.txt常用规则名包括 All、Single、Wordlist、Jumbo、Extra 等范围从小到大。规则用得好的话一个小字典能顶一个大字典的效果。比如中文用户习惯在密码后面加年份像 admin2023、admin2024john 的规则里就内置了年份追加逻辑又比如 leet 替换a→、o→0、i→1规则也能覆盖。规则唯一的缺点是会让破解时间成倍增加。原来一条字典词只算一次哈希启用规则后一条词可能要算几十次甚至上百次。所以正确用法是先用无规则的纯字典跑一轮快的再启用规则跑一轮而不是一上来就把规则拉满否则很可能跑了大半天还在处理字典的前几千条词。还有一个非常实用的技巧就是从目标信息里提取候选词喂给 john。比如你知道目标用户的公司叫 BlueOcean那就把 blueocean、BlueOcean、BO 等变体手动加到一个只有几十行的字典里再用规则变形。这种“信息定制化”的字典往往比几千万行的通用字典更有效因为真正的弱密码通常和用户的个人信息强相关。4.3 Cewl 从目标网站生成密码词典Cewl 是一个根据网站内容爬取单词生成字典的工具。它的思路是如果有人用公司的名字、产品名、创始人名字当密码你在目标官网就能收集到这些词。cewl http://www.example.com -m 6 -w words.txt-m 6表示只收集长度大于等于 6 的单词-w输出到文件。生成的 words.txt 可以交给 john 或 hydra 当字典。这个工具在授权渗透测试里特别好用因为它完全是针对目标“量身定做”的密码词典。5. 常见问题与避坑指南工具不难装命令也不难打真正让人头大的是各种想不到的报错和异常。这里把我这些年踩过的坑集中整理一下。5.1 Hydra 高频故障排查连接失败Connection refused最常见的原因是端口号不对。SSH 不在 22 端口、FTP 不在 21 端口就必须用-s指定实际端口。另外很多云主机安全组默认屏蔽了外部对 22 的访问先自己用 ssh 命令手工连一下确认服务能通再上 hydra。认证频率限制导致全部失败现代 SSH 服务有很多保护机制比如 MaxAuthTries、PerSourcePenaltiesOpenSSH 9.8 之后引入。Hydra 并发一高服务端会直接断开你的连接表现为“Connection reset by peer”或者一堆[FAILED]。这时把-t降到 1 或 2加上-w调整超时等待时间慢慢跑反而更稳。发了大量请求但无一个成功先手工验证密码字典里有没有正确的密码。可以随机选几条密码用 ssh 命令手工登录测试确认服务端逻辑正常。还有一个隐藏坑是目标启用了 key-based auth only密码认证被禁用你再怎么爆破都不会成功。HTTP 模块不停报错回到上面的失败标记问题。用浏览器开发者工具或者 curl 把登录请求的真实响应抓下来找到唯一出现在失败页面的关键词。特别注意有些网站的所有响应都是 JSON错误信息藏在响应体里hydra 的文本匹配也能处理只要把标记串写对。5.2 John 高频故障排查No password hashes loaded这是最常见的报错原因是文件格式 john 不认识。如果你直接拿 /etc/passwd 喂给 john没有 x 占位或 shadow 文件被截断都可能出这个问题。先用 unshadow 合成再不行就--formatsha512crypt强制指定但前提是你确认哈希确实是对应的算法。破解速度慢得离谱先检查是不是用了--incremental全穷举这个模式本身就慢再看哈希类型如果是 bcrypt 或者 yescrypt这个速度就是正常的这些算法天生抗暴力。想要快要么换 GPU 跑 hashcat要么改用更精准的小字典加规则。pot 文件导致结果不更新John 会把已破解的结果存到 pot 文件里重新跑同一条哈希时不会自动重算。想强制重跑就指定一个不存在的 pot 路径john --pot/tmp/new.pot --wordlistdict.txt combined.txtunshadow 后 hash 格式变了不要直接修改 combined.txt 的格式john 对字段顺序有严格要求。如果一定要裁剪最好只保留特定的用户行而不是动分隔符和字段内容。5.3 安全防护视角的一点提醒学暴力破解不是只为了“打进去”更是为了知道怎么防。我在做完测试之后一般会顺手给服务器加固密码策略强制 16 位以上包含随机字符别跟用户名、公司名、生日沾边。SSH 关闭密码登录改用密钥认证。密钥文件的密码短语也要足够长否则密钥本身也有被爆破的风险。部署 fail2ban 之类的工具连续失败几次直接封禁来源 IP。定期检查 auth.log 或者 journalctl看有没有异常的 SSH 登录尝试。这套组合拳下来暴力破解基本就废了。就算攻击者有一百台机器的算力碰上一台禁用密码登录、只允许密钥、还封禁异常 IP 的服务器也只能换目标。写在最后密码破解这行当玩到深处拼的不是命令背得多熟而是对系统的理解深不深。hydra 和 john 只是两个入口背后是密码存储机制、哈希算法特性、字典构造思路、系统防护策略这一整个知识链。建议你在虚拟机里搭一个 Ubuntu 靶机自己创建几个弱密码用户然后分别用 hydra 和 john 跑一遍把报错和效果都亲眼看看。亲手踩过一遍坑比看十篇文章都管用。最后再分享一个小技巧不要把暴力破解当成纯粹的“撞大运”。真正高效的破解永远是从目标信息收集开始的。用户名规律、密码策略、常见命名习惯、员工常用词汇这些信息越充分你准备的字典越精准成功率越高。工具只是执行者真正的主导者是前面那些功课。