正在加载,请稍候…

MD5 碰撞:攻击者如何利用哈希弱点突破文件上传安全

了解 MD5 碰撞攻击如何破坏文件上传安全,通过 fastcoll 生成碰撞文件绕过哈希校验的实战示例。

服务器机架与发光网线

引言

MD5(Message Digest 5)曾是文件完整性校验的事实标准。它的 128 位哈希被广泛用于软件下载、文件上传系统等场景。然而,2004 年王小云教授展示了实用的碰撞攻击,彻底打破了 MD5 的安全性。时至今日,MD5 在密码学上已被攻破,但许多遗留系统仍依赖它进行文件验证。本文聚焦于一个特定的攻击向量:文件上传系统中的 MD5 碰撞。我们将解释攻击者如何上传一个与良性文件具有相同 MD5 哈希的恶意文件,从而绕过基于哈希的白名单或去重检查。你将了解底层机制、逐步利用示例、常见陷阱以及防御方法。

试试我们的 哈希文本工具 来观察微小的输入变化如何产生完全不同的哈希值。

MD5 碰撞的原理

Merkle-Damgård 结构

MD5 使用 Merkle-Damgård 构造:输入消息被填充到 512 位的整数倍,分成 512 位的数据块,并迭代处理。每个数据块通过一个 64 轮的压缩函数更新 128 位的内部状态(四个 32 位字:A、B、C、D)。

关键缺陷在于压缩函数:对于精心选择的两个数据块之间的差异,内部状态的差异在 64 轮后抵消,产生相同的最终哈希。这称为差分路径

王小云的差分攻击

王小云的攻击找到两个不同的 512 位数据块,当它们被插入到消息的特定位置时,会导致整体 MD5 哈希碰撞。攻击复杂度约为 2^39 次操作——比生日攻击的 2^64 边界快数万亿倍。现代工具如 fastcoll 可以在普通 PC 上几秒钟内生成一对碰撞文件。

选择前缀碰撞

一种更强大的变体是选择前缀碰撞:给定两个不同的前缀(例如,一个良性文件和一个恶意负载),攻击者可以附加不同的后缀,使得完整消息具有相同的 MD5 哈希。这正是文件上传攻击所需要的。

为什么文件上传系统容易受到攻击

许多文件上传系统使用 MD5 哈希进行:

  • 去重:只存储具有相同哈希的文件的一份副本。
  • 完整性检查:验证上传的文件是否与已知的良好哈希匹配。
  • 命名:将文件重命名为其 MD5 哈希以防止路径遍历。

如果攻击者能够上传一个与现有良性文件(例如系统配置文件或其他用户的文档)具有相同 MD5 的文件,他们就可以覆盖它或绕过安全检查。攻击过程如下:

  1. 攻击者获取一个系统接受的良性文件(例如 allowed.jpg)。
  2. 使用碰撞工具,攻击者生成第二个具有相同 MD5 哈希但内容不同的文件(malicious.jpg,例如包含 PHP 代码或恶意软件)。
  3. 攻击者上传 malicious.jpg。系统计算其 MD5,发现与白名单哈希匹配,接受它——可能覆盖原始文件或执行负载。

实战示例:在文件上传中利用 MD5 碰撞

我们将使用 fastcoll(王小云攻击的一个流行实现)创建两个具有相同 MD5 哈希但内容不同的文件。然后模拟一个使用 MD5 进行去重的文件上传系统。

步骤 1:准备一个良性文件

创建一个简单的文本文件 benign.txt

This file is safe.

步骤 2:生成碰撞文件

benign.txt 为前缀运行 fastcoll。它生成两个输出文件 coll1.bincoll2.bin,它们共享相同的 MD5 哈希,但在一小块数据上不同。

fastcoll_v1.0.0.5.exe -p benign.txt -o coll1.bin coll2.bin

步骤 3:验证碰撞

检查两个文件的 MD5 哈希:

certutil -hashfile coll1.bin MD5
certutil -hashfile coll2.bin MD5

两者输出相同的 32 字符十六进制字符串,例如 5d41402abc4b2a76b9719d911017c592

步骤 4:检查差异

使用十六进制编辑器(如 WinHex)比较两个文件。你会看到一个小区域(大约在字节 64–127)的比特不同。这就是碰撞块。

偏移 coll1.bin coll2.bin
0x40 0x12 0x34 0x56 0x78
... ... ...

步骤 5:模拟文件上传攻击

假设服务器按 MD5 哈希存储文件并进行去重:如果存在相同哈希的文件,则拒绝上传或覆盖旧文件。上传 coll1.bin 作为 photo.jpg。服务器计算其 MD5 并存储为 5d41402abc4b2a76b9719d911017c592.jpg。现在上传 coll2.bin 作为 photo.jpg。服务器计算相同的 MD5,发现已存在,并覆盖原始文件为恶意内容。之后下载 photo.jpg 的用户将收到恶意版本。

针对 MD5 碰撞的防御措施

防御措施 工作原理 有效性
使用 SHA-256 或更强 用 SHA-256、SHA-512 或 BLAKE2b 替换 MD5。 高——目前没有已知的实际碰撞。
内容类型验证 验证文件魔数,而不仅仅是扩展名。 中等——可能被多语言文件绕过。
沙盒执行 将文件存储在 web 根目录之外,通过脚本提供服务。 高——防止直接执行。
双重哈希(MD5+SHA-256) 组合两个哈希;攻击者必须同时碰撞两者。 中等——增加复杂度但并非未来-proof。
随机化文件名 使用 UUID 或随机字符串,而不是哈希。 高——消除基于哈希的覆盖攻击。

常见陷阱

  • 认为 MD5 在非安全场景中仍然安全:即使对于去重,攻击者也可以强制碰撞来破坏数据。
  • 只检查文件扩展名:攻击者可以在有效的图像中嵌入可执行代码(多语言文件)。
  • 按 MD5 哈希存储文件:使得基于哈希的覆盖攻击成为可能。
  • 忽略选择前缀碰撞:即使你控制了文件的一部分,攻击者也可以附加碰撞块。
  • 不更新遗留系统:许多企业系统仍然依赖 MD5 进行文件完整性检查。

常见问题

在非对抗场景中,MD5 还能用于文件完整性校验吗?

可以,如果你只需要检测意外损坏(例如网络传输错误),MD5 没问题。但如果存在恶意篡改的可能,请使用 SHA-256。

今天生成 MD5 碰撞有多快?

在现代 CPU 上,fastcoll 可以在不到一分钟内生成一对碰撞文件。使用 GPU 加速,只需几秒钟。

SHA-1 有同样的问题吗?

是的,SHA-1 也被攻破了(2017 年的 SHAttered 攻击)。然而,SHA-1 碰撞需要更多资源(约 11 万美元的云算力)。尽管如此,永远不要将 SHA-1 用于安全目的。

SHA-256 安全吗?

SHA-256 目前被认为是安全的。没有实际可行的碰撞攻击。它是所有安全应用的最低推荐标准。

我可以使用 MD5 进行密码哈希吗?

不行。MD5 太快且容易受到彩虹表攻击。请使用 bcrypt、Argon2 或 PBKDF2。

结论

MD5 碰撞对依赖哈希验证或去重的文件上传系统构成了真实威胁。借助 fastcoll 等工具,攻击者可以在几秒钟内生成碰撞文件。修复方法很简单:迁移到 SHA-256 或更强的算法,结合内容验证,并且永远不要单独信任哈希来保证安全。使用我们的 哈希文本工具 比较不同算法的哈希值,看看安全性保证的差异。