news 2026/10/26 1:05:37

Linux密码破解全链路:从shadow哈希提取到John与Hashcat实战防御

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux密码破解全链路:从shadow哈希提取到John与Hashcat实战防御

很多朋友以为Linux密码破解就是拿个U盘启动Kali然后对着屏幕一顿操作,实际上绝大多数场景根本没有那么“黑客电影”。我去年帮一家小公司做内部安全排查,最后发现一台内网服务器是被一句话字典猜中了root口令才被拿下的,那次之后我把Linux密码破解的完整链路从原理到工具到防御彻底过了一遍。这篇文章就是我自己的实验笔记加踩坑实录,写给运维、安全测试和系统管理员参考,想搞懂你的密码到底是怎么被“算出来”的,这篇看完基本就通了。

先说个结论:Linux系统的密码不是存在一个明文文件里的。所有账号口令经过加盐哈希后保存在/etc/shadow,所谓破解实际上是拿到这个哈希文件后在另一台机器上离线做碰撞计算。所以整个话题的核心就两件事:一是你能不能拿到shadow文件,二是你手里的计算资源够不够配合一份靠谱的字典。这篇文章会把我实测过的环境搭建、工具选型、三种攻击模式、常见坑和防御手段全部写出来。

1. Linux密码存储机制:先搞清楚你在破解什么

1.1 从登录验证到密码哈希,一次登录背后的运算

Linux系统里每个用户的信息分散在两个文件:/etc/passwd保存用户名、UID、家目录等公开信息,真正敏感的口令哈希字段在/etc/shadow里。普通用户对shadow文件没有任何读权限,只有root和shadow组可以读,这是一道基础防线。

当你输入密码登录时,系统并不会去“解密”存储的哈希回比对你的输入,而是把你刚敲进去的明文口令加上shadow里的盐值,用同样的哈希算法重新计算一遍,然后把计算结果和shadow里存的哈希做字符串比较。一致就放行,不一致就拒绝。这套机制的好处是哈希函数是单向的,就算攻击者拿到shadow文件,也没办法通过逆向运算直接还原出明文口令。

说到“加盐”,很多人第一次接触不理解。盐就是一串随机字符串,在哈希计算前拼到密码后面。同样一个密码Password@123,如果盐不同,最终算出的哈希串完全不一样。这样做防止了两种常见攻击:一是攻击者把所有常见口令预先算好哈希做成彩虹表,拿shadow里的哈希去查;二是多个用户恰好用了同一个密码,他们在shadow里的哈希值也会因为盐不同而不一样,攻击者无法一眼看出“这两人密码相同”。

再补充一个细节:shadow的哈希字段有特殊前缀。正常格式是分隔符加算法ID加盐加哈希,比如$6$random_salt$hash_value。如果账号被锁定,这个字段通常以一个感叹号开头。我之前见过不少新手拿着字段就硬跑,结果John直接告诉你“No password hashes loaded”,就是因为前面那个!导致哈希没被识别出来。

1.2 一眼识别哈希类型:算法ID与企业级特征

shadow字段里的算法ID是破解工具选择模块的关键依据,我用表格整理了一下最常见的几种:

算法ID哈希算法典型长度常见系统
$1$MD5 crypt22字符左右的盐+哈希老版本Linux
$5$SHA-256 crypt43字符部分新系统
$6$SHA-512 crypt86字符绝大多数当前Linux发行版
$y$yescrypt较长且含多段$Debian 12、Ubuntu 22.04及更新版本

这里有个很重要的识别技巧:看到$6$基本可以认定是SHA-512,Hashcat对应模块是1800;看到$y$则是yescrypt,属于新内核和部分新发行版默认算法。用John的时候可以让它自动识别,但用Hashcat时模块编号一定要选对,选错了结果就是一堆“Token length exception”之类的报错。

我自己的经验是:拿到一份哈希文件,先别急着上GPU,用文本编辑器打开看一眼字段,确定算法ID,再决定用哪个工具、哪个模块。这一步省下来的时间远大于你当场试错的时间。

2. 实验环境与工具选型:为什么我选John加Hashcat

2.1 合法实验前提与实验环境准备

先强调一句,这篇文章所有实验都发生在你自己授权的虚拟机里,拿自己创建的账号做测试。没授权就去碰别人的系统,那不是安全研究,那是违法犯罪。我在公司做内网安全评估,每一步都有书面授权和范围界定,你们在自己电脑上玩也一定要把边界卡死。

我的实验环境是这样的:一台VMware虚拟机装Ubuntu 22.04 LTS作为靶机,物理机是Windows 11配一张老款GTX 1080显卡。破解工具安装在物理机上,因为密码破解是计算密集型任务,GPU的并行能力比CPU强太多,虚拟机里跑GPU穿透又容易出驱动问题,不如直接在宿主机操控。

然后我在靶机上创建测试账号,这一步是为了后面提取哈希做实验。具体的命令我在第三节详细写,这里先不展开。

2.2 John the Ripper:CPU时代的全能选手

John the Ripper是我第一个接触的破解工具,它最大的优势是生态成熟、格式判断智能化、规则系统强大。你把shadow文件丢给它,它会自己猜哈希类型,根本不需要你指定什么模块编号。在CPU环境下它能自动调用所有核心并行计算,对老机器非常友好。

但John也有明显的短板:CPU算力上限就摆在那里,跑SHA-512这种慢哈希时速度感人。我以前拿一台8核的老服务器跑rockyou字典,1400万条密码跑了快一个小时,换成GPU之后结果完全不是一个量级。

如果你只是小规模测试、或者手头没有NVIDIA显卡,John完全够用。它的规则生成功能也值得单独说,后面规则攻击一节我会给实际参数。

2.3 Hashcat:GPU资源的调度高手

Hashcat是另一个阵营的代表,它把计算负载扔给GPU,利用几千个CUDA核心并发计算。同样一份SHA-512哈希,我用1080跑大概每秒一万多次,同一台机器用CPU跑John每秒只有几百到一千次,差距接近一个数量级。

Hashcat的代价是命令行参数更复杂,你得知道自己要处理的是什么哈希类型,得选对攻击模式和掩码,输出格式也偏硬核。但它的灵活性也是John没法比的:内置了非常丰富的掩码语法,支持多种攻击模式组合,还能暂停、恢复会话。对于需要长期跑大字典或暴力破解的任务,我基本都会优先用Hashcat。

所以我的结论很简单:日常快速验证、字段识别、规则测试用John,跑大字典和掩码暴力用Hashcat,两个工具配合着用效率最高。

3. 从零复现一次完整的离线破解实验

3.1 准备靶机账号与提取哈希

先在虚拟机里创建两个测试账号,一个设置简单密码模拟真实弱口令,另一个设置长密码对比效果:

sudo useradd -m -s /bin/bash lab01 echo 'lab01:Sunshine@2024' | sudo chpasswd sudo useradd -m -s /bin/bash lab02 echo 'lab02:Tr0ub4dor&3' | sudo chpasswd

然后提取shadow文件里的哈希字段。完整的shadow行是用冒号分隔的,第二个字段是哈希,但直接拷贝整行再手动加工容易出错。建议用awk命令精确提取:

sudo awk -F: '$1=="lab01" || $1=="lab02" {print $1 ":" $2}' /etc/shadow > lab_hashes.txt cat lab_hashes.txt

这里有个细节,awk拿到的是两个用户完整的shadow行,但我只输出用户名和哈希字段,保留用户名只是为了后面用--show的时候好区分是谁。注意传给破解工具的哈希文件里不能有多余空格或注释,格式越干净,后面工具报错越少。

把lab_hashes.txt拷贝到物理机上,实验的前半部分就完成了。接下来的所有操作都在你自己的机器上,跟靶机已经没关系了——这就是“离线破解”的特征。

3.2 字典攻击:最朴素也最高效的方法

字典攻击的原理是:把一批高频密码逐一做哈希计算,和目标哈希比对。它不聪明,但极其有效,因为现实中绝大部分密码都能在常见字典里找到。

很多系统自带rockyou字典,它在/usr/share/wordlists/rockyou.txt.gz。如果没有就自己准备一份常见弱密码列表,几百上千条也可以做验证。解压后先看字典规模:

sudo gunzip -k /usr/share/wordlists/rockyou.txt.gz wc -l /usr/share/wordlists/rockyou.txt

我这里的rockyou有接近1400万条。拿它跑lab01这个账号,先上John:

john --wordlist=/usr/share/wordlists/rockyou.txt --format=sha512crypt lab_hashes.txt

注意我指定了--format=sha512crypt,这样John就不用每次启动都去猜格式,能省一点时间。跑完查看结果:

john --show lab_hashes.txt

正常情况下几秒到几分钟就能看到Sunshine@2024被还原出来。原因很简单,rockyou里收录了大量带年份的生日密码、季节词汇加数字的组合,Sunshine@2024这类结构在里面有相似变体。

再用Hashcat跑一遍做对比,sha512crypt在Hashcat里对应模块1800,默认字典攻击模式是-a 0:

hashcat -m 1800 -a 0 lab_hashes.txt /path/to/rockyou.txt --show

如果是第一次跑这块显卡,Hashcat会先做自检和驱动测试,看到一堆模块编号扫过去不用慌,等它进入实际计算就行。

3.3 掩码攻击:精确打击的纯暴力模式

字典攻击找不到的密码,那就只能靠暴力枚举。Hashcat的掩码语法是它的核心优势,先记住这几个占位符:

  • ?d 代表数字
  • ?l 代表小写字母
  • ?u 代表大写字母
  • ?s 代表特殊符号
  • ?a 代表以上所有字符

假设你怀疑某个密码是六位纯数字,比如工号或者生日数字,那么掩码就是六个?d的重复。命令如下:

hashcat -m 1800 -a 3 lab_hashes.txt '?d?d?d?d?d?d'

六位纯数字一共只有100万种组合,在GPU上跑sha512crypt这种慢哈希也就是几分钟的事。如果换成?d?d?d?d?d,直接少一位,秒级就出来了。

但纯暴力不是万能的。八位以下、字符种类单一的场景可以用掩码解决,一旦密码长度超过十位且大小写数字符号全混用,组合空间就是天文数字。我用公式算一下:假设95个可用字符、长度10,那组合数是95的10次方,约等于6乘以10的19次方,哪怕每秒算1000亿次也需要7万多天。所以纯暴力攻击在真实场景里更多是用来试探结构,而不是无脑枚举超长密码。

3.4 规则变异:让字典长出翅膀

如果说字典攻击是拿现成钥匙试锁,规则变异就是给钥匙做改造。John和Hashcat都支持规则,它们的思路一样:把一个字典里的基础词,通过大小写替换、末尾追加数字、首字母大写、常见单词替换等规则衍生出一批新密码。

比如一个基础词password,加上规则后可能变成Password、PASSWORD、password123、P@ssw0rd等等。这些变形很有实战价值,因为现实中大量用户就是在基础词上做小幅变体。

John自带一批规则集,可以通过--rules参数指定。我常用的是:

john --wordlist=/path/to/dict.txt --rules=All --format=sha512crypt lab_hashes.txt

这套规则会生成极其庞大的候选集,速度也会直线下降,所以我一般先用规则集里的子集。Hashcat同样有规则文件,常用的是best64规则:

hashcat -m 1800 -a 0 lab_hashes.txt /path/to/dict.txt -r /path/to/hashcat/rules/best64.rule

best64听名字只有64条规则,但它覆盖了最常用、命中率最高的密码变形习惯。我实测下来,小字典加best64规则往往比直接跑几百万条大字典更快出结果,因为前者更贴合真实用户改密码的思维模式。

4. 破解实验中的坑与效率调优

4.1 我踩过的五个低级错误

写这一节的时候我特意回想了自己第一次完整实验时犯过的错,这些都是工具文档里很少直接告诉你的事情。

第一个错误是直接拿整个shadow文件丢给工具。shadow里除了普通用户,还有一些系统用户根本没有可破解的密码字段,或者字段被锁定,结果工具扫了半天说“No hashes loaded”。正确做法就像前面一样,先用awk把目标用户单独提取出来。

第二个错误是不知道哈希被锁定。账号被passwd -l锁定后,shadow里的哈希字段前面会多一个感叹号。我当时没注意,一直以为工具识别不了格式,折腾了半小时才发现是多了一个字符。

第三个错误是Hashcat报“Separator unmatched”但实际就是我的哈希文件里有回车符或者多余空格。Windows记事本编辑过的文件默认带了CRLF,Hashcat对行尾符非常敏感。解决办法是用VS Code或者Notepad++把行尾转为LF,或者重新用Linux处理一遍文件。

第四个错误是盲目暴力。我刚开始总觉得暴力最万能,上来就开十位全字符,结果跑了三小时一个结果都没有。后来想想,一个六位数字配合生日年份结构才是合理的攻击路径。暴力不是不能跑,而是要在明确知道密码结构的情况下跑。

第五个错误是没利用GPU。刚开始图省事全用John在CPU上跑,等换到Hashcat才发现同样字典快了近十倍。如果你的机器有NVIDIA显卡,装好CUDA驱动后一定要优先用Hashcat。

4.2 效率对比与参数调优心得

我把自己机器上几个典型的破解任务效率整理在一起,方便你做选型参考:

任务类型John CPU多核Hashcat GPU
1400万条rockyou字典跑sha512crypt大约一小时内20分钟左右
六位纯数字暴力十几分钟几分钟
八位小写字母暴力基本不现实仍需很长时间

从这个表能很直观看到差距。调优方面我比较喜欢用--status参数,Hashcat会定时输出当前进度和剩余时间估算,跑长任务时很有用。Hashcat还支持断电续跑,休息前保存会话,下次直接--restore接着来,离线破解本来就是可以随时中断的,不用一直盯着。

还有一点,多哈希文件批量破解时,Hashcat会把所有哈希一起并行计算,只要碰撞到其中一个就记录一次。如果手里有十几个哈希,整体破解效率会被显著拉高,因为GPU同时处理多个目标,任何一条先撞上都是收益。

4.3 常见问题速查表

现象原因解决办法
No password hashes loaded哈希被锁定或字段格式错误检查shadow字段是否有!前缀,确认算法ID
Separator unmatched行尾是CRLF或多处空格把文件转成LF行尾,去除多余空白
Token length exceptionHashcat模块编号选错确认算法ID后找对module编号
破解速度特别慢哈希类型是非主流算法或CPU在跑确认GPU已启用,必要时换规则缩小范围
跑完没有结果字典里确实没有目标密码换更大字典,或者结合掩码做分段攻击
--show没有输出当前会话没有被记录先跑一次让工具建立potfile,再用--show查询

这些都是我实际遇到过的问题,排查思路基本都指向同一个终点,先确认哈希内容本身没问题,再优化工具参数。

5. 从破解到防御:安全加固与检测

5.1 读懂威胁模型,别再迷信算法强度

很多人觉得只要把算法从MD5换成SHA-512或者yescrypt就高枕无忧了。但站在攻击者视角看,真正决定成败的从来不是算法本身,而是密码的熵值。SHA-512再慢,你把密码设成Password123这种级别,字典里第一条就撞出来了。

我观察到的实际情况是,大多数系统沦陷走的是这条链路:拿到一份企业员工账号密码库,再配合社工库里提取的昵称、生日、手机号组合规则,跑到最后总能撞开几个账号。算法上加盐只是提高单次计算成本,但如果候选密码本身就在字典里,这点成本对GPU来说根本不值一提。

所以防御的第一原则不是无止境地升级算法,而是让每个账号的密码足够随机且互不重复。哪怕密码是八个字符,只要是随机生成的、不带任何个人信息,字典和规则攻击就很难命中。

5.2 系统层面的十项加固建议

第一,强制密码策略。用PAM模块设置最短长度至少12位,同时要求包含大小写数字符号中的三类字符,并禁止连续重复字符。第二,启用密码过期策略。通过chage命令设置有效期,比如90天强制更换,但提醒一下,频繁改密码会导致用户把密码写在便利贴上,这时反而更危险,所以一周到两周改一次比较折中。

第三,禁止root直接SSH登录。改/etc/ssh/sshd_config里的PermitRootLogin为no,所有管理员先正常用户登录再sudo提权。第四,禁用空密码账号,检查/etc/shadow里是否存在没有密码哈希的账号。第五,管理好sudo权限,/etc/sudoers里尽量用sudo组而不是直接放行所有用户。

第六,定期检查审计日志。重点关注auth.log、secure日志里的Failed password记录,以及sudo命令的执行记录,任何异常提权行为都要追根究底。第七,部署fail2ban或类似工具,对SSH暴力破解自动封禁来源IP。注意封禁阈值不能太低,否则误伤正常用户,我一般设置5次失败后封禁15分钟。第八,给重要文件做文件完整性监控,比如用AIDE记录/etc/shadow和关键系统文件的哈希。

第九,最小化安装。系统不需要的服务一律不装,每多一个网络服务就多一个入口。第十,也是最容易被忽视的,不要在web目录、配置文件、备份包、日志文件里存放任何明文密码,我遇到过好几次因为备份文件泄露导致哈希被提取的案例。

5.3 通过日志发现暴力破解行为

既然离线破解的前提是拿到shadow哈希,那对于系统管理员来说,重点防御思路就是阻断攻击者接触哈希文件和登录入口。下面这个命令能从日志里快速统计失败登录来源:

sudo grep "Failed password" /var/log/auth.log | awk '{print $1,$2,$3,$11,$13}' | sort | uniq -c | sort -nr | head -20

如果你用的是CentOS或者RHEL,日志路径通常是/var/log/secure,把文件名换掉即可。输出结果会显示哪些IP尝试次数最多,如果某个IP在短时间内出现几十上百次失败登录,基本可以断定在撞库。

配合fail2ban的配置也很简单,安装后默认的sshd规则就能用,关键是把maxretry和bantime调到适合自己环境的数值。然后定期写个脚本把这些统计结果发到自己的邮箱或者即时通讯机器人里,比天天手动登录服务器看日志省心得多。

我建议每个运维都做一次这种“攻击自家系统”的实验,不是为了让你学会入侵,而是让你知道真正的风险点在哪里。体会到字典攻击有多廉价、GPU暴力有多快,你在配置密码策略和权限管理的时候才会真正下狠手。

最后再分享一个技巧:当你发现自己某台机器的shadow哈希已经泄露或者怀疑泄露时,别只改那台机器上的密码,立即排查所有使用相同密码的其他系统和网络服务。现实中大多数内网横向移动就是靠着同一个弱口令在不同机器间反复复制粘贴造成的。把这次实验中学到的工具、参数和排查思路,都变成你日常安全巡检的一部分,比你临时抱佛脚有用得多。

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

Rust与SQLite集成实战:从建表到并发优化的完整指南

做后端或者边缘计算项目的朋友,应该都遇到过这个场景:手头的设备资源有限,数据量又不算小,需要一个轻量、可靠、读写又快的存储方案。我最近在做一个设备数据采集服务时,重新把 Rust 和 SQLite 这个组合完整地过了一遍…

作者头像 李华
网站建设 2026/10/23 8:39:12

制造业研发管理本土化优势:从BOM到ECN的实战路径

制造业研发管理,听起来是个特别“正襟危坐”的话题,但干这一行的人心里都清楚,真正的研发管理根本不是画流程图、定制度那么潇洒,而是每天都在跟“需求变、交期赶、图纸返工、部门扯皮”做肉搏战。我在制造型企业里从工程师一路做…

作者头像 李华
网站建设 2026/10/19 7:33:44

Agent-Reach:为智能体补齐触达真实世界的能力高速公路

1. 从"Agent能想"到"Agent够得着":Agent-Reach的起点2024年年底,我和团队接到一个很典型的项目:给某客户做一套智能客服Agent,让它能根据用户的诉求自动走内部流程。模型选型、提示词工程、意图识别都调得很顺…

作者头像 李华
网站建设 2026/10/19 9:34:52

RISC-V低功耗链路:WFI、SBI CPPC与Linux cpufreq协同全解析

去年调一块带双核 RISC-V 核心的板子,整机待机功耗比参考值高出将近三分之一。功率计和逻辑分析仪查了半天,发现 CPU 确实执行了 WFI,主频却一直停在标称值附近——固件层的 CPPC 例程没有被正确调用,内核 cpufreq 也根本没有把“…

作者头像 李华
网站建设 2026/10/19 9:34:48

HT6872防削顶原理与低成本音频功放工程实践

1. 为什么HT6872的“4.7W防削顶”不是营销话术,而是设计取舍的硬指标 你拆过蓝牙音箱、便携收音机或者USB供电的小型功放板吗?大概率见过一块黑乎乎的贴片芯片,旁边印着“HT6872”或“HT6872A”。它不像TI的TPA系列那样被发烧友反复拆解分析&…

作者头像 李华
网站建设 2026/10/25 21:55:57

e2e路线图前瞻:通往1.0的API稳定性与版本规划

e2e路线图前瞻:通往1.0的API稳定性与版本规划 【免费下载链接】e2e Next generation e2e testing framework for web and mobile apps. 项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e e2e 是一款面向 Web 和移动端的下一代端到端测试框架&#xf…

作者头像 李华