如何从密码生成多个登录名?
首先,算法 1 看起来是最薄弱的环节。算法 2 是一个单向哈希函数,您无法仅通过知道幻数和密码偏差来提取字符。它涉及一些高级数学工作和时间。我在第二部分解释了破解算法2的过程。
认为 :
log_bias = 0xfec0135a
pass_bias = 0xdeadbeef
让我们看看算法1:
1) log_chunk = 0xlogin(0)login(1)login(n - 2)login(n - 1);
2) log_checksum = Sum(login, 0, n);
3) log_magicnumber = log_chunk ^ log_checksum ^ log_bias;
该算法显示了两个潜在的弱点。一,如果你把幻数和log_bias常数异或你得到:
log_chunk ^ log_checksum。二、log_chunk是前两个字符和后两个字符的十六进制拼接,为登录提供一个框架;因此,我们可以生成自己的字符并为该变量赋值。
在消除偏差并为块选择一个值后,我们可以获得log_checksum的值。
log_checksum = (log_magicnumber ^ log_bias) ^ log_chunk;
剩下要做的是找到表示字符的数字序列,其总和是校验和。
如何?
好吧,如果您查看ASCII表,您会看到可打印字符从 33 到 126。如果我们生成一个介于 33 和 126 之间的随机值b并将其从校验和中减去,我们将获得一个字符值b并减少校验和值通过b:log_checksum -= b。重复此操作,直到校验和值低于 126,并且只存储diff = (log_checksum - b)大于或等于 33 的字符。这样,所有字符都可以打印。
填写登录字符串的中间后,可以表示如下:
登录= AB b 0 b 1 b 2 ... b j CD
其中 A、B、C、D 是我们选择的字符,而b是从校验和生成的字符。
这种逆向工程方法是一种廉价的智能黑客,它针对过程中最弱的哈希函数,它肯定会起作用并节省您的时间。通过一个密码,您将获得多次登录:这称为哈希冲突。
这是此代码的示例输出:
Login: Vasya_Pupkin
Password: 011c0d0f090e00
Login check : 0xa8a17eee
Password check : 0xa8a17eee
Check success :)
Valid login for pass_magicnumber 0xa8a17eee: Va[JiIUpHBI]in, length = 14
Valid login for pass_magicnumber 0xa8a17eee: VaU[^OnyD^fin, length = 13
Valid login for pass_magicnumber 0xa8a17eee: Va|IkH`y`i2in, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VaTziSl^oK>in, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VawNzAOGWktin, length = 13
Valid login for pass_magicnumber 0xa8a17eee: Vaeh]bmzbwin, length = 12
Valid login for pass_magicnumber 0xa8a17eee: VaugjXcNEvBin, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VaJoMwQ{p[8in, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VatBZwR`R|Ein, length = 13
Valid login for pass_magicnumber 0xa8a17eee: VaIy[lkZQbKin, length = 13
所有列出的有效登录都适用于密码“011c0d0f090e00”。如果您稍微更改密码,请说:“011c0d0f090efe”,这就是您得到的:
Login: VaNpNa^Twin
Password: 011c0d0f090efe
Login check : 0xa8a17e10
Password check : 0xa8a17e10
Check success :)
Valid login for pass_magicnumber 0xa8a17e10: VaeOTUkOG8in, length = 12
Valid login for pass_magicnumber 0xa8a17e10: VaUDFEzBx>in, length = 12
Valid login for pass_magicnumber 0xa8a17e10: Va|gktoein, length = 10
Valid login for pass_magicnumber 0xa8a17e10: VaaPRTogiin, length = 11
Valid login for pass_magicnumber 0xa8a17e10: VaFEzBpktin, length = 11
Valid login for pass_magicnumber 0xa8a17e10: VafCCzmQrin, length = 11
Valid login for pass_magicnumber 0xa8a17e10: VaFDWMHSNC<in, length = 13
Valid login for pass_magicnumber 0xa8a17e10: VaSvoIgR\in, length = 11
Valid login for pass_magicnumber 0xa8a17e10: Va[{eLdl?in, length = 11
Valid login for pass_magicnumber 0xa8a17e10: VaPaoDPXFDin, length = 12
现在,让我们谈谈从登录幻数生成密码。你必须攻击这个函数:
log_magicnumber = b ^ ((log_magicnumber << 5) + 1) ^ pass_bias
如果仔细观察,您会发现当前的log_magicnumber是使用先前的log_magicnumber值转换并与未知字节值和已知偏差混合计算得出的。迭代,它看起来像这样:
log_magicnumber(i) = b ^ ((log_magicnumber(i - 1) << 5) + 1) ^ pass_bias
如果我们对pass_magicnumber和pass_bias 进行异或,我们就剩下:
b ^ ((log_magicnumber << 5) + 1)
在生成b 的所有可能值(0-9和af,总共 16 种可能性)并为b 的每个可能值导出log_magicnumber的相应值后,我们对这些幻数值应用相同的步骤以获得另一个值 & 我们继续8 次(密码字符串为 64 位值 = 8 个字节,最小长度为 6 个字节)。如果设置为零,我们丢弃最左边的两个字节并将所有字节打包成密码字符串;然后我们使用密码幻数算法验证密码的幻数是否与登录名匹配。
这种方法相当于创建一个 8 阶段树,其中每个节点有 16 个子节点。这意味着我们必须生成 16 的 8 个字符的幂:16^8 = (2^4)^8 = 2^32 = 4.294.967.296 个字符 (4GB) 并将它们组合成 6 到 8 个字符的字符串每个字符串都被检查以进行验证。编码很有趣:)