CRC背后的故事

百家 作者:Chamd5安全团队 2021-01-23 09:01:30


本文为翻译文章,笔者翻译水平有限,原文详见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以外,有限域本身也是一个经常在其他地方使用的概念,因此希望在以后出现混淆的时候可以参考这篇文章。

参考资料

  1. https://en.wikipedia.org/wiki/Finite_field
  2. https://en.wikipedia.org/wiki/Cyclic_redundancy_check
  3. https://stackoverflow.com/questions/21001659/crc32-algorithm-implementation-in-c-without-a-look-up-table-and-with-a-public-li
  4. https://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E5%9F%9F

由于公式问题展示最好的方式就是截图,也可以进行下载pdf进行阅读

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/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接