CRC背后的故事
本文为翻译文章,笔者翻译水平有限,原文详见Understanding CRC
http://www.secmem.org/blog/2020/08/19/Understanding-CRC/
介绍
去年的时候,在一些CTF赛事中出现了与CRC
相关的问题。问题的关键就是找到一个x
使得flag{x}
的CRC
值为x
。在解题的过程中,我们发现大多数人并不了解CRC
的性质。实际在网络应用中,通常使用CRC
作为冗余校验码,但是也仅限于使用现有的函数接口计算文件或数据的CRC
值,而没有深入了解CRC
的性质。
我对CRC
的本质也不太理解,于是我重新学习并写下了这篇文章。
背景知识
Finite Field
有限域的更多性质详见[有限域]:https://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E5%9F%9F
CRC
unsigned int crc32b(unsigned char *message) {
int i, j;
unsigned int byte, crc, mask;
i = 0;
crc = 0xFFFFFFFF;
while (message[i] != 0) {
byte = message[i]; // Get next byte.
crc = crc ^ byte;
for (j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
i = i + 1;
}
return ~crc;
}
Playing With CRC
poly = 0x104C11DB7
def normalize(x):
while x.bit_length() > 32:
x ^= poly << (x.bit_length() - 33)
return x
def mult(x, y):
res = 0
for i in range(32):
if y & (1 << i) != 0:
res ^= (x << i)
return normalize(res)
def bytes_to_gf32(s):
val = 0
for c in s:
rev = int(format(c, '08b')[::-1], 2)
val = (val << 8) | rev
return normalize(val)
def crc32(s):
l = len(s)
m = bytes_to_gf32(s)
return normalize((m << 32) ^ (0xFFFFFFFF << (8 * l)) ^ 0xFFFFFFFF)
def crc32b(message):
crc = 0xFFFFFFFF
for i in range(len(message)):
byte = message[i]
crc = crc ^ byte
for j in range(8):
if crc & 1:
crc = (crc >> 1) ^ 0xEDB88320
else:
crc >>= 1
return crc ^ 0xFFFFFFFF
message = b"test"
crc1 = crc32(message)
crc2 = crc32b(message)
print(format(crc1, '032b'))
print(format(crc2, '032b')[::-1])
> python .\test.py
00110000011111101111111000011011
00110000011111101111111000011011
代码:
def pow(x, y):
if y == 0:
return 1
elif y == 1:
return x
else:
res = pow(x, y // 2)
res = mult(res, res)
if y & 1:
res = mult(res, x)
return res
def inverse(x):
return pow(x, 2 ** 32 - 2)
const = crc32(b"flag{\0\0\0\0}")
coef = normalize((1 << 40) ^ 1)
x = mult(const, inverse(coef))
print(format(x, '032b')[::-1])
# 01110011 10011011 01000101 00000111
# 0x73 0x9b 0x45 0x07
print(hex(x))
print(hex(bytes_to_gf32(b"\x07\x45\x9b\x73")))
print(hex(crc32(b"flag{\x07\x45\x9b\x73}")))
print(hex(crc32b(b"flag{\x07\x45\x9b\x73}")))
输出结果为:
python .\test.py
01110011100110110100010100000111
0xe0a2d9ce
0xe0a2d9ce
0xe0a2d9ce
0x739b4507
于是预期的x
为\x07\x45\x9b\x73
总结
我们花了一些时间来了解CRC
的数学基础,并深入了解了CRC
,并找出了某些字符串的CRC
值等于字符串自身情况。除了CRC
以外,有限域本身也是一个经常在其他地方使用的概念,因此希望在以后出现混淆的时候可以参考这篇文章。
参考资料
https://en.wikipedia.org/wiki/Finite_field https://en.wikipedia.org/wiki/Cyclic_redundancy_check https://stackoverflow.com/questions/21001659/crc32-algorithm-implementation-in-c-without-a-look-up-table-and-with-a-public-li https://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E5%9F%9F
https://github.com/ChaMd5Team/Venom-WP/blob/main/CRC背后的故事.pdf
查看以下链接或点击文末阅读原文
结束
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新
欢迎联系admin@chamd5.org
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 澳门是伟大祖国的一方宝地 7938471
- 2 女法官遇害案凶手被判死刑 7931081
- 3 日本火山喷发灰柱高达3400米 7869509
- 4 中国为全球经济增长添动能 7777234
- 5 肖战新片射雕英雄传郭靖造型曝光 7615970
- 6 大三女生练咏春一起手眼神骤变 7506103
- 7 #马斯克对特朗普政府影响有多大# 7441368
- 8 男子钓上一条自带“赎金”的鱼 7378118
- 9 赵丽颖带儿子探班 7258790
- 10 女子穿和服在南京景区拍照遭怒怼 7134733