试图对数据包校验和/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/哈希进行逆向工程的主要内容,如果未能解决你的问题,请参考以下文章