使用哈希的前 10 个字符已知的 hashcat

Using hashcat where first 10 character of hash are known

我有使用 MySQL

的 Web 应用程序

应用程序使用来自MySQL的密码哈希函数来存储相关帐户的密码

问题是,它 trim 哈希密码,因此它只将前 10 个字符存储到密码字段中

我想向我的主管证明,trimming 散列密码可以使不同的密码在登录表单上输入并被应用程序接受。因为这些密码的前 10 个字符相同

为了证明这一点,我打算使用 hashcat。我已经下载了相当大的词典文件来帮助我达到目的

那么,有没有人可以帮助我在 hashcat 中应该使用的参数如何?

我已经尝试 google 寻找答案,但没有成功

谢谢

要获得实际问题的答案,请跳至此答案的最后一部分。其他部分没有直接回答你的问题,但你可能会发现这已经不是必需的了。


您对系统的描述

你说系统对密码的处理如下
plaintext passwordhashed passwordfirst 10 characters of the hash

示例:
Topsecret123*E7C95D33E14D3C2A3AE4EAB25C1D98C88593F7AC*E7C95D33E

请注意 MySQL's PASSWORD() prefixes hashes with a *,因此您实际上只包含哈希中的 9 个字符。


在后台回答问题

您问过如何使用 hashcat 查找上述方法的哈希冲突,但您真正想要 know/show 的是

prove trimming hashed password can make different password [...] accepted by the application.

您的重点是 »修剪 导致接受多个密码«。但是,您忽略了即使未经trimmed 散列也会导致接受多个密码。

鸽笼原理

解释的很简单,不用找哈希冲突。大家应该明白以下几点:

  • 有无限多的密码。
  • MySQL 密码哈希具有固定长度,恰好是 64 位。只能有 264 个不同的哈希。
  • 密码哈希函数将密码映射到哈希值。由于密码比散列多,所以一些密码必须映射到相同的散列。
    如果没有,您会找到一个压缩功能,它允许您仅以 64 位存储任何内容

有人可能会争辩说有效密码的数量不是无限的。但是,即使您将有效密码的长度限制为恰好为 11 并且仅包含 [A-Za-z0-9] 组中的符号(有 62 个符号),也会有 6211 个唯一密码:

6211 ≈ 5,2×1019 密码
264 ≈ 1,8×1019 哈希

所以,碰撞还是要多的。

哈希冲突

修剪散列不是冲突问题的根本原因,但它当然会极大地增加冲突的可能性。通常,散列冲突不是问题,因为它们很少发生,您不会遇到它们。但是,对于像您这样的强 trimmed 哈希,冲突成为一个真正的问题。


寻找碰撞

使用哈希猫

hashcat 可以使用 -m 300 计算 MySQL 密码哈希值。您可以通过 computing SELECT Password("hashcat"); and comparing the resulting hash with the hash shown here.

确认这一点

但是,我找不到 trim 这些散列/查找前缀冲突的方法。我想 hashcat 不能做你想做的事。您必须为 hashcat 实现自定义哈希模式。最简单的方法是更改​​ current implementation of hashcat's MySQL mode. I'm not sure, but maybe it is sufficient to just change const int out_len = 40; to 9. You may have to update the OpenCL versions of the same module too. Search for m00300 here.

使用自定义脚本

或者,查找密码哈希对列表或自己生成一个,然后在其中查找前缀冲突 table。这很有趣所以我自己做了

以下 python 程序为一些数字密码生成 trimmed 哈希:

#! /usr/bin/python3
import hashlib as hl

def mySqlPwHash(password):
        return hl.sha1(hl.sha1(password.encode()).digest()).hexdigest()[:9]

for number in range(0, 300000):
        password = str(number)
        print(password, "\t", mySqlPwHash(password))

我选择生成 300'000 个哈希,因为有 169 trim 个哈希,我们可以预期在 √(169) = 262'144 次尝试(参见 birthday problem)。

要查找具有相同散列值的密码 运行 脚本如下:

./collide.py | sort -k2 | uniq -Df1

脚本仅用了两秒钟就完成并打印了

23607    47ae310ff
251848   47ae310ff

你有它,两个密码(23607251848)具有相同的trimmed hash(47ae310ff)。

如果您的 trimmed 哈希值实际上包含 10 个十六进制数字,您可以调整脚本并找到共享哈希值 18745472873667 的两个密码 47fc464b2f .