试图对数据包校验和/CRC/哈希进行逆向工程

Posted

技术标签:

【中文标题】试图对数据包校验和/CRC/哈希进行逆向工程【英文标题】:Trying to reverse engineer a packet checksum/CRC/hash 【发布时间】:2014-05-16 03:21:40 【问题描述】:

我有一个旧的、不再生产的带有串行端口的电子设备。我正在尝试对该设备中使用的数据包 CRC/校验和/哈希进行逆向工程。

任何有敏锐眼光和敏锐数学能力的人都可以破解这个东西吗?

这是我目前所知道的......

每个数据包总是 21 个字节。 19 个字节的数据加上 2 个字节用于 CRC/校验和/哈希 因此,这里没有长度或标题字节。哈希计算涉及所有 19 个字节。 我有能力用设备生成一定数量的数据包 我的第一个想法是数据包有某种 CRC-16 计算 所以我按照www.cosc.canterbury.ac.nz/greg.ewing/essays/CRC-Reverse-Engineering.html 中的反向提示进行操作

验证我的数据包样本遵守了上述网页链接中概述的“叠加原理”。这表明它们具有数学 XOR 关系。

开始感觉很好……但之后就难住了。无法确定 CRC-16 多项式。这些数据包哈希很可能与 CRC 无关,而是一些自制方案。

通读 Ross N. Williams 的“CRC 错误检测算法无痛指南”

见http://www.ross.net/crc/download/crc_v3.txt 也使用过的应用程序:CRC Reveng – 逆向工程应用程序 参见 reveng.sourceforge.net 还是没有运气...

很遗憾,我无权访问任何设备源代码/二进制代码

还运行测试以查看是否使用了其他哈希值,例如 Fletcher 的校验和

这是我的数据包的各种样本。

0x47366B2EE00000000000751CEB5F3469543B585E2D 0x47366B2ED00000000000751CEB5F3469543B582A2C 0x47366B2EC80000000000751CEB5F3469543B580B2B 0x47366B2EC40000000000751CEB5F3469543B58BB2A 0x47366B2EC20040000000751CEB5F3469543B58DFE7 0x47366B2EC10000000000751CEB5F3469543B58A328 0x47366B2EC08000000000751CEB5F3469543B584127 0x47366B2EC04000000000751CEB5F3469543B588126 0x47366B2EC02000000000751CEB5F3469543B580525 0x47366B2EC01000000000751CEB5F3469543B580124

请注意以下关于这些数据包...

在数据包的最后 2 个字节发现 CRC。 如果我查看逻辑分析仪上的位,我已将字节表示为 MSB 优先 因此,数据包 0x47366B2EE00000000000751CEB5F3469543B585E2D 在二进制中显示为: 01000111 .................................... .............00101101

(0x47)....................... .............................(0x2D)

我不知道我的系统是大端还是小端,但相当确定的字节是 LSB 优先的

请注意,对于上述 10 个数据包样本,每个数据包的不同之处在于 1 个位移位至 10 个位位置。除了第 5 个数据包,我必须更改 2 位

查看数据包的 0x47366B2E 部分之后的数据字节。

我看到的唯一模式是每个数据包的最后一个字节减一(2D,2C,...)。 (除了第 5 个数据包,我必须更改 2 位)

最后一个字节不是某种序列号,因为我可以随时生成具有相同值的它们。 但它可能会提示使用的数学哈希。

感谢任何帮助!

【问题讨论】:

你怎么知道19个字节都参与了hash计算? 通过本机的液晶界面,我可以发送消息。这使我可以更改 19 个“数据”字节中的任何一个。我无法完全控制字节中的每一位,但非常接近。 它似乎不是 16 位 CRC。检查值确实似乎是数据的 GF(2) 上的线性函数。它可能类似于 32 位 CRC 的低两个字节。 谢谢马克。我会做更多的窥探并研究截断的 CRC-32 可能性。 我在文本中看不到任何地方你说设备道歉,如果它像白天一样清晰,但如果不是,它有助于了解设备或任何芯片的品牌和型号标记 - 只是从某人可能记得在设备上工作或使用设备并可以给出提示甚至可能有旧数据表的角度来看 - 这是一个很长的镜头,但看起来你需要你可以获得的所有帮助。 【参考方案1】:

我通过名为“SRP16”的应用程序运行了一些数据包,该应用程序搜索并显示 CRC16 Rocksoft 参数。输出如下:

===== Result parameter sets =====
CRC=$2a2c  Poly=$2817  init=$3141  xorout=$ffff  refin=true   refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$2817  init=$70f4  xorout=$0000  refin=true   refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$2817  init=$9bf3  xorout=$0000  refin=false  refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$2817  init=$da46  xorout=$ffff  refin=false  refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$4777  init=$1263  xorout=$0000  refin=false  refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$4777  init=$6f2d  xorout=$0000  refin=true   refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$4777  init=$a127  xorout=$ffff  refin=true   refout=true 
 *** Second data set verified
CRC=$2a2c  Poly=$4777  init=$dc69  xorout=$ffff  refin=false  refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$7354  init=$1dab  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$7354  init=$417e  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$7354  init=$a401  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$7354  init=$f8d4  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$8a23  init=$0fa0  xorout=$0000  refin=false  refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$8a23  init=$3f6a  xorout=$ffff  refin=false  refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$8a23  init=$cc70  xorout=$0000  refin=true   refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$8a23  init=$fcba  xorout=$ffff  refin=true   refout=true 
 *** Second data set verified
CRC=$2c2a  Poly=$9656  init=$3460  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$9656  init=$ff4b  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$a644  init=$195b  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$a644  init=$70ca  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$a644  init=$a3e8  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
CRC=$2c2a  Poly=$a644  init=$ca79  xorout=$0000  refin=false  refout=true 
 *** Third  data set verified
===== done =====

也许试试这些,看看它们是否适合你?

祝你好运!

【讨论】:

【参考方案2】:

如果它遵循简单的 XOR 关系,即 (checksum(A ^ B) == checksum(A) ^ checksum(B)) 那么有一个简单的暴力解决方案!

插图。假设您有一个带有 K 位校验和的 1 字节值 - 其中 K 实际上并不重要,所以我们只需将校验和表示为 c(i)。

步骤 1. 实验:观察全零数据包的校验和 c(-1)。

0b0000000 => c(-1)

Step 2. 实验:观察所有二进制序列的校验和 c(i),其中位置为 i

0b00000001 => c(0)
0b00000010 => c(1)
0b00000100 => c(2)
0b00001000 => c(3)
0b00010000 => c(4)
0b00100000 => c(5)
0b01000000 => c(6)
0b10000000 => c(7)

您观察到的校验和的值形成了 GF(2) 的线性基础,XOR 关系现在允许您计算任何校验和。

现在您可以通过将每个位位置的校验和与 1 相加来计算校验和,例如假设你想要 0XF3 的校验和,二进制是 0b11110011。自从

0b11110011 = (0) + 0x80 + 0x40 + 0x20 + 0x10 + 0x02 + 0x01

然后通过异或关系,

checksum(0b11110011) = c(7) + c(6) + c(5) + c(4) + c(1) + c(0) + c(-1)

即对于您要输出的每一位,只需对该位的已知校验和进行异或累加即可。

如果您进行此练习并实验性地写出基向量的所有 152 个校验和,那么您可能还会在此过程中发现一个简单的模式,该模式解释了校验和如何来自基向量。 :) 如果是这样的话,把它发回这里会很好! (也许告诉我们我们正在逆转什么?)

【讨论】:

以上是关于试图对数据包校验和/CRC/哈希进行逆向工程的主要内容,如果未能解决你的问题,请参考以下文章

CRC32 参数逆向工程可以访问多个示例

校验和:CRC 还是哈希?

文档:网络通讯包结构(crc校验,加解密)

CRC校验失败怎么办?

软考网工难点分析之三 CRC循环冗余校验

什么是CRC校验码?