如何使用相同的 MD5 哈希创建两个 PHP 文件

我最近在 twitter 上发布了一个指向两个 PHP 脚本的链接,它们具有不同的行为,但具有相同的 MD5 哈希值。要验证这一点,请下载文件:

然后检查他们的 MD5 哈希值:

现在运行每个文件:

这些文件的行为不同,但使用 MD5 散列到相同的十六进制字符串。使用另一种哈希算法(在本例中为 SHA1)进行快速检查,确认这两个文件实际上是不同的:

那么这些文件是如何制作的呢?好吧,如果你看一下文件的源,你会发现这两个文件之间几乎没有区别。

cat a.php

$ cat b.php

发现有什么不同吗?它可能很难发现,但实际上在二进制数据的第一个块中存在细微的差异。

那么,所有这些二进制数据是怎么回事呢?二进制数据表示 MD5 算法中的冲突。在 Wang 于 2004 年首次发表的对 MD5 的攻击之后,为 MD5 创建碰撞非常容易。此外,您可以选择要创建的碰撞的起始值,这样它就不必位于文件的开头。 这是因为 MD5 与大多数哈希算法一样,一次对一个数据块(在 MD5s 情况下为 64 个字节)进行操作,然后使用此值作为下一个块的起点。接下来的两个块在两个文件之间有所不同,但是,它们是专门创建的,以便在插入到此位置时发生碰撞。两个文件中的所有后续块都相同。这是我用来生成文件的方法。

1) 首先,我创建了一个正好 64 字节长的文件,其中包含第一个单引号之前的所有内容。A 只是为了让它正好有 64 个字节长

2) 通过 MD5 算法运行此内容,但略微修改的版本不会在消息中添加长度或任何填充,我在 PHP 中使用了我自己的 MD5 实现,并注释掉了附加填充的部分。您可以在此处获取此代码 https://gist.github.com/natmchugh/fbea8efeced195a2acf2. 生成哈希值 32f6df28e4a110970fb7f9938bee1686。

3) 使用此哈希值作为初始值来查找 MD5 冲突。我发现的最快的碰撞脚本是 Marc Stevens fastcoll, https://marc-stevens.nl/research/ 如果在 MD5 中创建冲突听起来需要很长时间 – 但事实并非如此。它需要多少时间,但在本例中,大约需要 15 秒才能生成 2 条消息,这些消息与初始值 32f6df28e4a110970fb7f9938bee1686 发生冲突。

4)然后,我将生成的两条消息附加到1中创建的文件中,以提供两个文件。

5). 这两个文件现在应该具有相等的长度并且具有相同的 MD5,但它们不会作为 PHP 运行。所以我在两批二进制数据之间添加了语句。
‘ == ‘ ‘ == ‘

6)接下来,我将碰撞a附加到两个文件中。这将生成一个语句,该语句在文件 a 中为 true(因为 2 个二进制 blob 确实相同),但在文件 b 中为 false。

7) 我在两条消息中附加了相同的 PHP 以完成 if 语句并生成您看到的输出。因此,实际上我们有两个文件,其中前 64 个字节是相同的。接下来的 128 个字节是 MD5 中的冲突,然后是相同的所有其他文本。毫不奇怪,当通过整个 MD5 算法(包括填充)传递时,这会产生相同的 MD5 哈希值。

虽然这种攻击可能看起来毫无用处,因为文件充满了 gobbledygook 并且依赖于相当明显的 if 语句,但有一些方法可以创建具有相同 MD5 哈希值的文件,这些哈希值不依赖于开关,并且其余文件内容可以完全不同.

参考链接:如何使用相同的 MD5 哈希创建两个二进制文件

原文链接:Nat McHugh: How I made two PHP files with the same MD5 hash — Nat McHugh:我是如何用相同的 MD5 哈希值制作两个 PHP 文件的

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部