Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
collisions — 哈希碰撞与利用 | Kitploit
工具/GitHubGitHub/corkami/collisions
漏洞利用哈希分析密码学二进制分析学习与教育
GitHubcorkami/collisions

collisions

哈希碰撞与利用

查看仓库
3.4k210591年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

哈希碰撞与利用

作者:Ange Albertini 与 Marc Stevens。

常见问题(TL;DR)

问:能否让一个文件获得任意的 MD2/MD4/MD5/MD6/SHA1/SHA2/SHA3 哈希,或者与另一个文件相同的哈希?
答:不能。

问:能否创建两个哈希相同的不同文件?
答:对于 MD5,在标准计算机上只需几秒钟。对于 SHA1,这可行,但对最终用户而言并不实用(复杂度:2^61.2 成本:1.1 万美元)。

问:能否通过附加数据让两个不同文件获得相同哈希?
答:对于 MD5,在标准计算机上只需几小时。对于 SHA1,这可行,但对最终用户而言并不实用(复杂度:2^63.4 成本:4.5 万美元)

问:这两个文件仍会保持有效吗?
答:一般来说是的,因为大多数文件格式都能容忍附加数据。但另一方面,文件签名很可能会失效。

问:能否制作两个内容任意但哈希相同的不同文件?
答:可以,借助特殊的文件结构可即时实现:

  1. 一个带有技巧的特殊格式头部(或一对头部),充当两种内容之间的开关(某些格式不允许此类技巧)。
  2. 基于特定头部预计算的碰撞。
  3. 两个特定格式的内容,均位于碰撞之后(在计算后追加)。

问:我可以为哪些格式获取即时 MD5 碰撞文件对?
答:JPG、PNG、GIF、GZIP、可移植可执行文件、MP4、JPEG2000、PDF、DOCX/PPTX/XSLX、EPUB、3MF、XPS。只需运行对应的脚本即可。

问:那 SHA1 呢?
答:对于 SHA1,PDF 中的 JPG 已计算并实现。

问:那已经支持 MD5 的格式(JPG、PNG……)换成 SHA1 呢?
答:它们很可能同样支持 SHA1,但相应的碰撞尚未被计算出来。

问:对于相似(但不同)的内容,计算会更快吗?
答:不会。任何微小的差异都需要一次完整的计算。

问:哪些格式没有这种捷径?
答:ELF、Mach-O、Java Class、TAR、ZIP(以及其他一些……)

问:这些格式仍能产生经典碰撞(几小时内)吗?
答:可以,只要容忍任意数量的附加数据(也就是说,ZIP 或 Class 很可能不行)。

问:你们提供碰撞示例吗?
答:提供。

目录

  • 简介
  • 状态
  • 攻击
    • 相同前缀
      • FastColl (MD5)
      • UniColl (MD5)
      • Shattered (SHA1)
    • 选定前缀碰撞
      • HashClash (MD5)
      • Shambles (SHA1)
    • 攻击总结
  • 利用
    • 标准策略
      • JPG
        • 自定义扫描
      • PNG
        • 不兼容性
      • GIF
      • GZIP
      • LZ4 / Zstandard
      • 可移植可执行文件
      • MP4 及其他
        • JPEG2000
      • PDF
        • PDF 中的 JPG
      • ZIP
        • 基于 ZIP 的格式
      • 其他
    • 非常规策略
      • MultiColls:多重碰撞链
        • Hashquines
      • 有效性
      • PolyColls:不同文件类型的碰撞
        • PE - JPG
        • PDF - PE
        • PDF - PNG
      • PileUps(多重碰撞)
        • PE - PNG - MP4 - PDF
    • 使用场景
      • 全都碰撞吧!
      • 定罪文件
    • 失败
      • ELF
      • Mach-O
      • Java Class
      • TAR
    • 利用总结
    • 测试文件
  • 检测
    • 安全哈希
  • 参考资料
  • 致谢
  • 结论

简介

目标是广泛探索现有的攻击方式——并在此过程中展示 MD5 有多么脆弱(任何 JPG、PNG、PDF、MP4、PE……都能即时碰撞)—— 同时深入探索常见文件格式,以确定 它们如何被现有或未来的攻击所利用。

事实上,相同的文件格式技巧可应用于多种哈希 (同样的 JPG 技巧曾用于 MD5、 恶意 SHA-1 和 SHA1), 只要碰撞遵循相同的字节模式即可。

本文档并非关于新攻击(最新的攻击于 2012 年被记载), 而是关于现有攻击的新利用形式。

状态

已知攻击的当前状态:

  • 让一个文件获得另一个文件的哈希或指定哈希:不可能

    • 即使对 MD2 或 MD4 而言也依然不现实。
    • 对更简单的哈希有效(*)
  • 让两个不同文件获得相同 MD5:即时

    • 示例:1 ⟷ 2
  • 让两个任意文件获得相同 MD5:几小时(72 小时.core)

    • 示例:1 ⟷ 2
  • 让两个特定文件格式(PNG、JPG、PE……)的任意文件获得相同 MD5:即时

    • 详见下文
  • 让两个不同文件获得相同 SHA1:6500 年.core

    • 让两个不同的 PDF 获得相同 SHA-1 以展示另一番景象:即时(前缀已预先计算)

(*) 以 crypt 为例——感谢 Sven!```

import crypt crypt.crypt("5dUD&66", "br") 'brokenOz4KxMc' crypt.crypt("O!>',%$", "br") 'brokenOz4KxMc'

# 攻击

MD5 和 SHA1 以 64 字节的块为单位工作。

如果两个内容 A 和 B 具有相同的哈希值,那么向两者追加相同的内容 C 将保持相同的哈希值。``` text
hash(A) = hash(B) -> hash(A + C) = hash(B + C)

碰撞攻击的原理是在块边界处插入若干个计算出的碰撞块, 其数量取决于文件中此前的数据。 这些碰撞块看起来非常随机,仅有细微差异 (每种攻击都遵循特定的模式), 它们会引入微小的差异,但最终在这些块之后使哈希值相同。

这些差异被滥用来构造具有特定属性的合法文件。

文件格式也是自上而下工作的,且大多数按字节级块(chunk)处理。

可以插入一些“注释”块,以使文件块对齐到块边界、 使特定结构与碰撞块差异对齐、 将碰撞块的其余随机性对文件解析器隐藏, 并隐藏原本有效的内容(从而使解析器看到的是另一份内容)。

这些“注释”块往往并非真正的官方注释: 它们只是被用作数据容器,解析器会忽略它们 (例如,ID 以小写字母开头的 PNG 块是辅助块(ancillary),而不是关键块(critical))。

大多数时候,碰撞块中的差异被用来修改某个注释块的长度, 该长度通常在此块数据之前声明: 在这个块的较短版本与较长版本之间的空隙中, 声明另一个注释块,以跳过一个文件的内容 A。 在这个文件内容 A 之后,再追加另一个文件内容 B。

由于文件格式通常会定义一个终止符,解析器会在遇到它后停止解析, A 将终止解析,从而使追加的内容 B 被忽略。

因此通常至少需要两个注释——往往是三个:

  1. 对齐
  2. 隐藏碰撞块
  3. 隐藏一个文件的内容(用于可复用的碰撞)

文件格式的这些常见属性使上述攻击成为可能——它们通常不被视为弱点,但可以被检测出来或被规范化消除:

  • 虚拟块(dummy chunks)——用作注释
  • 存在多个注释
  • 巨大的注释(长度:MP4 为 64b,PNG 为 32b -> 可轻松实现碰撞。JPG 为 16b,GIF 为 8b -> GIF 没有通用碰撞,JPG 也受限)
  • 在注释中存储任意数据(可能强制使用 ASCII 或 UTF8)
  • 在终止符之后存储任何内容(通常仅用于恶意目的)—— 可以通过使用两个在同一偏移处结束的注释来避免。
  • 没有完整性检查。PNG 中的 CRC32 通常会被忽略。 然而,它们可以全部是正确的,因为碰撞块声明了不同长度的块—— 所以即使块的数据起始不同, 块的长度也是不同的
  • 扁平结构:ASN.1 定义了父结构,包含所有内部子结构的长度, 这阻止了上述构造:你需要滥用一个长度,而且还要滥用父结构的长度。
  • 在头部之前放置注释——这使通用的可复用碰撞成为可能。

相同前缀

  1. 定义一个任意前缀——其内容和长度都无关紧要。
  2. 将前缀填充到下一个 64 字节块。
  3. 根据前缀计算碰撞块并追加。 两侧都非常随机。差异由攻击预先确定。
  4. 在这些块之后,尽管文件存在差异,哈希值仍然相同。
  5. 可以添加任意相同的后缀。
前缀=前缀
碰撞 A≠碰撞 B
后缀=后缀

两个文件几乎完全相同(它们的内容只有几个比特的差异)

利用方式:

将两个内容捆绑在一起,然后要么:

  • 数据利用:运行代码检查差异并显示其中一个或另一个(通常很简单,因为差异事先已知)。
  • 结构利用:利用文件结构(通常是注释的长度)来隐藏一个内容或显示另一个内容(取决于文件格式及其解析器)。

具有此结构的两个文件:

前缀=前缀
碰撞 A≠碰撞 B
A=A
B=B

将显示 A 或 B 中的其中一个。

FastColl (MD5)

最终版本于 2009 年发布。

  • 时间:几秒钟的计算
  • 空间:两个块
  • 差异:之前无法控制,之后无法控制。 FastColl 差异掩码:
    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
    .. .. .. X. .. .. .. .. .. .. .. .. .. .. .. ..
    .. .. .. .. .. .. .. .. .. .. .. .. .. X. .X ..
    .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
    
  • 利用:困难

这些差异不在块的起始/结束位置附近,因此很难利用,因为你无法控制任何邻近的字节。 一个潜在的解决方案是暴力破解周围的字节——参见 PoCGTFO 14:10。

示例:

使用空前缀时:``` MD5: fe6c446ee3a831ee010f33ac9c1b602c SHA256: c5dd2ef7c74cd2e80a0fd16f1dd6955c626b59def888be734219d48da6b9dbdd

下载工具