我正在尝试确定big-endian系统上内存的32字节受保护部分背后的算法。即使更改了一个位,它也会变得无效,但是我可以生成任意数量的有效32字节消息。这里显示了各种示例数据。我相信最后4个字节是校验和。所有这些都被算法接受。

00000000000000000000000000000000000000000007478A000101004892B760
F0000000000000000000000000000000000000000002D8DF00010100C9E23610
3065C0000000000000000000000000000000000000006F850001010060EB9F07
FFFFFFFF03FC6BBD000000000000000000000000000000000001010070B88F3A
FFFFFFFF0397E33D340C804138458C5006060968570C214B0001017AE8F416FE


我能够创建一堆自定义消息,它们之间的差异很小。似乎不可能是CRC-32。

FFFFFFFF01671F7E000000000000000000000000000000000001010021E4DE0E (00)
FFFFFFFF01671F84000000000000000000000000000000000001010021EADE08 (01)
FFFFFFFF01671F88000000000000000000000000000000000001010021EEDE04 (02)
FFFFFFFF01671F86000000000000000000000000000000000001010021ECDE06 (03)
FFFFFFFF01671F8C000000000000000000000000000000000001010021F2DE00 (04)
FFFFFFFF01671F8A000000000000000000000000000000000001010021F0DE02 (05)
FFFFFFFF01671F86000000000000000000000000000000000001010021ECDE06 (06)
FFFFFFFF01671F8C000000000000000000000000000000000001010021F2DE00 (07)
FFFFFFFF01671F90000000000000000000000000000000000001010021F6DDFC (08)


所有输入字节都是相同的,只是每个消息中的一个字节增加1。

这里有50对左右的列表。我可以生成任意数量的这些消息,并验证它们是否被接受。 F88,1EA-> 1EE,E08-> E04)。
经过一些实验(主要是对不同的值进行加减法测试),我很幸运地发现它是前14个16位字的总和。将总和与0xFFFF进行“与”运算,则该值等于第15个字(例如,第一条消息中的21EA)。
然后从0xFFF2中减去此值以在消息中产生第16个字。
FFFFFFFF01671F84000000000000000000000000000000000001010021EADE08
FFFFFFFF01671F88000000000000000000000000000000000001010021EEDE04


评论

关键是在差异分析和框架化/完善您的工作假设之间进行迭代。对于第0轮,让一位翻转在输入消息上徘徊,观察哪些输出位在何时改变。这应该使您对结构有个好主意(并排除所有像CRC这样的体面的哈希)。进一步的微分实验可以为您提供迭代函数,并且一旦有了迭代函数,就可以推导/计算迭代前后(预处理和后处理)涉及的魔术常数。

#1 楼

所示的某些样本输入仅在第十六个半字节的值上有所不同;让's(X)'代表这样的输入,该值在那个半字节处为X:
现在,让我们将某些输入的XOR(位差)和相应的校验和的XOR当作MSB优先位串:

s(4): FFFFFFFF01671F840000000000000000000000000000000000010100 21EADE08
s(6): FFFFFFFF01671F860000000000000000000000000000000000010100 21ECDE06
s(8): FFFFFFFF01671F880000000000000000000000000000000000010100 21EEDE04
s(A): FFFFFFFF01671F8A0000000000000000000000000000000000010100 21F0DE02
s(C): FFFFFFFF01671F8C0000000000000000000000000000000000010100 21F2DE00


校验和差异的最低设置位等于输入差异的位,并且匹配差异恰好高16位。设置位的突发可能是由于冒泡进位引起的。

为了进行比较,这是对应的CRC32值之间的XOR差异:

>更改的结构完全不同,并且更加复杂。请注意,在同一位(前两行)中存在差异的输入的CRC差异以及差异的密度接近理论上的50%。这是因为CRC具有比简单的经验校验和更好的扩散(有效效果)。

现在,具有近乎完美扩散的哈希(杂音哈希混合器功能)的图片如下:

s(4) ^ s(6) = o(2), cksum delta: .............**.............***.
s(8) ^ s(A) = o(2), cksum delta: ...........****..............**.
s(8) ^ s(C) = o(4), cksum delta: ...........***...............*..
s(4) ^ s(C) = o(8), cksum delta: ...........**...............*...


通过观察这些越来越复杂的函数的差值,可以很容易地了解校验和的结构:求和,xor,xorshift和一些经典的哈希。 br />然后将焦点放在目标功能上。观察某些固定输入的输出差异,让单个位在字符串中翻转。对于一系列不同的输入,请在某些固定位置观察输出差的单位差。让差异位置跳变以8位为增量,观察行为。然后尝试32位跳,观察。如果可能的话,将最初的研究集中在输入的最后32位,因为它们与输出的关系肯定比经过更多迭代的位要简单得多。您很久了。

那是看xor差速器。根据校验和的假设结构,其他实验也是可能的。作为一个真实的例子,几年前,我不得不基于(主要是)正确样本的样本推论出各种校验数字算法(本质上与ISBN校验数字算法相似)。由于这些算法基于将数字与某些位置相关的权重相乘,因此我搜索了一对数字,这些数字对与校验和仅相差一个位数。通过修正关于如何将总和转换为校验位的某些假设,我可以得出每个数字的权重(1、2、3、4 ...),并为该总和确定正确的假设。 >
在考虑的情况下,对于我在这里使用的五个样本,肯定有一个总和表示校验和的第16个半字节和最后一个半字节为12(0x0C)。 ,基本思想是将输入差异与输出差异面对,这取决于人们对需要推断的功能结构的怀疑。如果差异最小的样本对稀缺,事情就会变得非常棘手。相反,如果您可以随意制作样本(选择明文攻击),那么情况看起来确实很好...

评论


谢谢-好的技巧。我很幸运,从输入中可以发现一些很小的差异-发现它是一个非常有趣的16位求和算法。将前十四个16位字相加,并对0xFFFF进行AND屏蔽。该值是第15个字,第16个字是相同的值,但要减去0xFFF2。我相信您的信息将对以后的工作有所帮助

– bryc
2014年12月31日下午0:41